La carga diferida (también conocida como carga asincrónica ) es una técnica utilizada en programación informática , especialmente en diseño web y desarrollo web , para diferir la inicialización de un objeto hasta que sea necesario. Puede contribuir a la eficiencia en el funcionamiento del programa si se utiliza de forma adecuada y apropiada. Esto la hace ideal en casos de uso en los que se accede al contenido de la red y los tiempos de inicialización se deben mantener al mínimo, como en el caso de las páginas web . Por ejemplo, diferir la carga de imágenes en una página web hasta que sean necesarias para su visualización puede hacer que la visualización inicial de la página web sea más rápida. Lo opuesto a la carga diferida es la carga ansiosa . [1]
Antes de establecerse como un estándar web, los marcos web se utilizaban generalmente para implementar la carga diferida.
Una de ellas es Angular . Dado que la carga diferida disminuye el ancho de banda y, por consiguiente, los recursos del servidor, es una opción sólida para implementar en un sitio web, especialmente para mejorar la retención de usuarios al tener menos demoras al cargar la página, lo que también puede mejorar la optimización de motores de búsqueda (SEO). [2]
A continuación se muestra un ejemplo de carga diferida utilizada en Angular, programada en TypeScript de Farata Systems [3]
@ NgModule ({ importaciones : [ BrowserModule , RouterModule . forRoot ([ { ruta : '' , componente : HomeComponent }, { ruta : 'producto' , componente : ProductDetailComponent }, { ruta : 'lujo' , loadChildren : () => import ( './luxury.module' ) . then ( m => m.LuxuryModule ) , datos : { preloadme : true } } ] //, {preloadingStrategy: CustomPreloadingStrategy} ) ], declaraciones : [ AppComponent , HomeComponent , ProductDetailComponent ], proveedores : [{ provide : LocationStrategy , useClass : HashLocationStrategy }, CustomPreloadingStrategy ], bootstrap : [ AppComponent ] })
Desde 2020, los principales navegadores web han habilitado el manejo nativo de la carga diferida de forma predeterminada. [4] [5]
Esto permite incorporar la carga diferida a una página web agregando atributos HTML .
El loading
atributo admite dos valores, lazy
y eager
. [6] Si se establece el valor en , lazy
se obtendrá el recurso solo cuando sea necesario (por ejemplo, cuando una imagen se desplaza a la vista cuando un usuario se desplaza hacia abajo), mientras que si se establece en eager
, el estado predeterminado, el recurso se cargará inmediatamente.
<!-- Estos recursos se cargarán inmediatamente --> < img src = "header_image.jpg" > < img src = "header_image2.jpg" loading = "eager" ><!-- Mientras estos recursos se carguen de forma diferida --> < img src = "article_image.jpg" alt = "..." loading = "lazy" > < iframe src = "video-player.html" title = "..." loading = "lazy" ></ iframe >
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 contenedor de valores . [7] Cada uno tiene sus propias ventajas y desventajas.
Con la inicialización perezosa, el objeto se establece primero en null
.
Cada vez que se solicita el objeto, se verifica el objeto y, si es así null
, se crea y se devuelve inmediatamente.
Por ejemplo, la carga diferida de un widget se puede implementar en el lenguaje de programación C# de la siguiente manera:
int privado _myWidgetID ; Widget privado _myWidget = null ; público Widget MyWidget { obtener { si ( _myWidget == null ) { _myWidget = Widget . Load ( _myWidgetID ); } devuelve _myWidget ; } }
O alternativamente, con el operador de asignación de coalescencia nula ??=
int privado _myWidgetID ; Widget privado _myWidget = null ; público Widget MyWidget { obtener => _myWidget ??= Widget . Load ( _myWidgetID ); }
Este método es el más sencillo de implementar, aunque si null
se trata de un valor de retorno legítimo, puede ser necesario utilizar un objeto marcador de posición para indicar que no se ha inicializado. Si se utiliza este método en una aplicación multiproceso , se debe utilizar la sincronización para evitar condiciones de carrera .
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.
Un fantasma es el objeto que se va a cargar en un estado parcial. Inicialmente, puede contener solo el identificador del objeto, pero carga sus propios datos la primera vez que se accede a una de sus propiedades. Por ejemplo, supongamos 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, la única información disponible es que se accederá al contenido, pero se desconoce la acción y el contenido específicos.
Un ejemplo en PHP :
$userData = matriz ( "UID" = > uniqid (), "requestTime" => microtime ( verdadero ), "dataType" => "" , "request" => "" );if ( isset ( $_POST [ 'datos' ]) && $userData ) { // ... }
Un contenedor de valores es un objeto genérico que maneja el comportamiento de carga diferida y aparece en lugar de los campos de datos del objeto:
ValueHolder privado < Widget > valueHolder ; Widget público MyWidget => valueHolder . GetValue ();