La carga diferida (también conocida como carga asincrónica ) es un patrón de diseño que se usa comúnmente en la programación de computadoras y principalmente en el diseño y desarrollo web para diferir la inicialización de un objeto hasta el punto en el que se necesita. Puede contribuir a la eficiencia en el funcionamiento del programa si se utiliza de forma adecuada y apropiada. Esto lo hace ideal en casos de uso donde se accede al contenido de la red y los tiempos de inicialización deben mantenerse al mínimo, como en el caso de las páginas web . Por ejemplo, aplazar la carga de imágenes en una página web hasta que sean necesarias puede acelerar la visualización inicial de la página web. Lo opuesto a la carga diferida es la carga ansiosa .
Frameworks que usan carga diferida
Un marco bastante famoso que usa carga diferida es Angular . Ha habido algunas discusiones sobre si la carga diferida realmente ayuda, ya que aumenta la comunicación con el servidor. Esencialmente, la carga diferida ayuda a los desarrolladores de Angular a decidir qué módulos cargar en la inicialización o cuándo se llama a una función. Se afirma que es compatible con dispositivos pequeños e Internet con baja capacidad.
A continuación se muestra un ejemplo de carga diferida que se usa en Angular, programada con TypeScript de Farata Systems [1]
@ NgModule ({ importaciones : [ BrowserModule , RouterModule . ForRoot ([ { ruta : '' , componente : HomeComponent }, { ruta : 'producto' , componente : ProductDetailComponent }, { ruta : 'lujo' , loadChildren : () => import ( './luxury.module' ). luego ( m => m . LuxuryModule ), datos : { preloadme : true } } ] //, {preloadingStrategy: CustomPreloadingStrategy} ) ], declaraciones : [ AppComponent , HomeComponent , ProductDetailComponent ], proveedores : [{ provide : LocationStrategy , useClass : HashLocationStrategy }, CustomPreloadingStrategy ], bootstrap : [ AppComponent ] })
Implementaciones
Hay cuatro formas comunes de implementar el patrón de diseño de carga diferida : inicialización diferida ; un proxy virtual ; un fantasma y un poseedor de valor . [2] Cada uno tiene sus propias ventajas y desventajas.
Inicialización perezosa
Con la inicialización diferida, el objeto que se cargará de forma diferida se establece originalmente en nulo, y cada solicitud del objeto comprueba si hay nulo y lo crea "sobre la marcha" antes de devolverlo primero, como en este ejemplo de C #:
private int myWidgetID ; Widget privado myWidget = null ; public Widget MyWidget { get { if ( myWidget == null ) { myWidget = Widget . Cargar ( myWidgetID ); } return myWidget ; } }
O con el operador de fusión nula '??'
private int myWidgetID ; Widget privado myWidget = null ; public Widget MyWidget { get { return myWidget = myWidget ?? Widget . Cargar ( myWidgetID ); } }
Este método es el más simple de implementar, aunque si null es un valor de retorno legítimo, puede ser necesario utilizar un objeto de marcador de posición para indicar que no se ha inicializado. Si este método se usa en una aplicación multiproceso , se debe usar la sincronización para evitar condiciones de carrera .
Proxy virtual
Un proxy virtual es un objeto con la misma interfaz que el objeto real. La primera vez que se llama a uno de sus métodos, carga el objeto real y luego delega.
Fantasma
Un "fantasma" es el objeto que se va a cargar en un estado parcial. Puede que solo contenga el identificador del objeto, pero carga sus propios datos la primera vez que se accede a una de sus propiedades. Por ejemplo, considere que un usuario está a punto de solicitar contenido a través de un formulario en línea. En el momento de la creación, todo lo que sabemos es que se accederá al contenido, pero se desconoce qué acción o contenido.
Ejemplo de PHP:
$ userData = array ( "UID" = > uniqid (), "requestTime" => microtime ( verdadero ), "dataType" => "" , "request" => "" );if ( isset ( $ _POST [ 'datos' ]) && $ userData ) { // ... }
Titular de valor
Un contenedor de valor es un objeto genérico que maneja el comportamiento de carga diferida y aparece en lugar de los campos de datos del objeto:
Private ValueHolder < Widget > valueHolder ; Widget público MyWidget => valueHolder . GetValue ();
Implementación web
Permitir que el navegador sirva y muestre páginas en el menor tiempo posible es una necesidad crítica del mundo moderno de hoy. El método más simple para implementar la carga diferida es el siguiente
El atributo de carga admite dos valores, perezoso y ansioso . Eager cargará la imagen con prioridad, mientras que lazy la buscará solo cuando sea necesario o la imagen esté en la ventana gráfica.