English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Análisis y resumen de la implementación de carga diferida y precarga de imágenes en JavaScript

Este artículo principal introduce la explicación de dos tecnologías: carga perezosa y precarga, sin muchas palabras, veamos.

La carga perezosa también se llama carga retrasada:El artículo anterior ha presentado: JS carga de imágenes retrasada, carga de imágenes retrasada o cuando se cumplen ciertas condiciones.

Precarga:Cargar imágenes anticipadamente, cuando el usuario necesita verlas, se pueden renderizar directamente desde el caché local.

La esencia de ambas tecnologías:Ambos comportamientos son opuestos, uno es la carga anticipada, y el otro es la carga retrasada o no carga. La carga perezosa tiene un efecto de alivio de la presión en el frontend del servidor, mientras que la precarga aumentará la presión en el frontend del servidor.

El significado y la forma de implementar la carga perezosa son:

Significado: El objetivo principal de la carga perezosa es optimizar el servidor y el frontend, reducir el número de solicitudes o retrasar las solicitudes.

Forma de implementar:

1. La primera es la carga puramente retrasada, que utiliza setTimeOut o setInterval para retrasar la carga.

2. La segunda es la carga condicional, que comienza a descargar de manera asincrónica cuando se cumple cierta condición o se desencadena algún evento.

3. La tercera es la carga en la zona visible, es decir, solo se carga la área visible del usuario, lo que se realiza principalmente mediante el monitoreo de la barra de desplazamiento, generalmente se comienza a cargar a una cierta distancia antes de que el usuario vea la imagen, de modo que se garantiza que el usuario pueda verla cuando descienda.

El significado y la forma de implementar la precarga son:

La precarga puede decirse que es sacrificio de la capacidad del servidor y el rendimiento del frontend, a cambio de una mejor experiencia del usuario, de modo que las operaciones del usuario puedan recibir la mayor respuesta. Hay muchos métodos para implementar la precarga, se puede usar CSS(background), JS(Image), HTML(<img /Todo es posible. Lo más común es new Image();, configurar su src para realizar la precarga y luego usar el método onload para devolver el evento de finalización de la precarga. Tan pronto como el navegador descarga la imagen localmente, el mismo src se usará en el caché, que es el método más básico y práctico de precarga. Después de que Image descargue la cabecera de la imagen, se obtiene el ancho y la altura, por lo que se puede obtener el tamaño de la imagen antes de la precarga (el método es usar un temporizador para recorrer los cambios en el ancho y la altura).

¿Cómo podemos lograr la pre-carga?}

Podemos buscar en google: podemos ver que muchas personas utilizan este método para la pre-carga: el código es el siguiente:

 function loadImage(url, callback) {
  var img = new Image();
  img.src = url;
  img.onload = function() {
    img.onload = null;
    callback.call(img);
  }
}

Por qué otros navegadores funcionan normalmente: la razón es muy simple, es que los navegadores tienen la caché, excepto IE6Además (es decir, opera también, pero específicamente probé con opera y no funcionó, puede ser un problema de versión, tal vez ya se ha solucionado). Otros navegadores al hacer clic nuevamente ejecutarán el método onload, pero IE6Es directamente tomado del navegador.

Entonces, ¿qué hacer ahora? Lo mejor sería que Image tuviera un valor de estado que indique si ya se ha cargado con éxito. Al cargar desde la caché, ya que no es necesario esperar, este valor de estado indica directamente que se ha descargado, y al cargar desde una solicitud http, ya que es necesario esperar a la descarga, este valor se muestra como incompleto. De esta manera, se puede resolver. Después de buscar en google, se encontró que hay una propiedad de Image compatible con todos los navegadores: complete. Por lo tanto, antes de que se dispare el evento onload de la imagen, se debe hacer una comprobación de este valor. Finalmente, el código se convierte en lo siguiente:

function loadImage(url, callback) {
  var img = new Image();
  img.src = url;
  if(img.complete) { // Si la imagen ya existe en la caché del navegador, llamar directamente a la función de devolución de llamada.
    callback.call(img);
    return; // Regresar directamente, sin necesidad de procesar el evento onload.
  }
  img.onload = function() {
    img.onload = null;
    callback.call(img);
  }
}

Es decir, si la imagen ya está en la caché del navegador, se puede obtener directamente de la caché del navegador y ejecutar la función img.complete, luego regresar.

Pero podemos ver el código superior: debe esperar que la imagen se cargue completamente antes de ejecutar la función de devolución de llamada, o también se puede decir que después de que la imagen se haya cargado, podemos obtener el ancho y la altura de la imagen. Entonces, ¿qué hacer si queremos obtener el tamaño de la imagen con anticipación? La experiencia en línea me dice: mientras el navegador carga la imagen, verás que primero ocupa un espacio y luego se carga lentamente hasta que se completa, y no es necesario predefinir las propiedades width y height, porque el navegador puede obtener los datos de la cabecera de la imagen. Basado en esto, solo es necesario usar javascript para monitorear el estado del tamaño de la imagen para saber cuando está listo el tamaño de la imagen. El código es el siguiente: (pero hay un prerequisito, este método no es el que quería, ni es el código que escribí, es el código resumido por un amigo en línea. Solo sé que hay un principio así)

var imgReady = (function(){
  var list = [],
    intervalId = null;
  // 用于执行队列
  var queue = function(){
    for(var i = 0; i < list.length; i++{
      list[i].end ? list.splice(i--,1) : list[i]();
    }
    !list.length && stop();
  };
  // 停止所有定时器队列
  var stop = function(){
    clearInterval(intervalId);
    intervalId = null;
  }
  return function(url, ready, error) {
    var onready = {}, 
      width, 
      height, 
      newWidth, 
      newHeight,
      img = new Image();
    img.src = url;
    // 如果图片被缓存,则直接返回缓存数据
    if(img.complete) {
      ready.call(img);
      return;
    }
    width = img.width;
    height = img.height;
    // 加载错误后的事件 
    img.onerror = function () {
      error && error.call(img);
      onready.end = true;
      img = img.onload = img.onerror = null;
    };
    // 图片尺寸就绪
    var onready = function() {
      newWidth = img.width;
      newHeight = img.height;
      if (newWidth !== width || newHeight !== height ||
        // 如果图片已经在其他地方加载,则可以使用面积检测
        newWidth * newHeight > 1024
      ) {
        ready.call(img);
        onready.end = true;
      };
    };
    onready();
    // Evento de carga completa
    img.onload = function () {
      // onload puede ser más rápido que onready en el rango del tiempo del temporizador
      // Aquí se realiza la verificación y se garantiza que onready se ejecute primero
      !onready.end && onready();
      // El animation gif de IE se ejecutará en bucle onload, estableciendo onload a null
      img = img.onload = img.onerror = null;
    };
    // Se une a la cola para ejecutarse regularmente
    if (!onready.end) {
      list.push(onready);
      // Se permite solo un temporizador en cualquier momento para reducir el consumo de recursos del navegador
      if (intervalId === null) {
        intervalId = setInterval(queue, 40);
      };
    };
  }
})();

La forma de llamar es la siguiente:

imgReady('http://img01.taobaocdn.com/imgextra/i1/397746073/T2BDE8Xb0bXXXXXXXX-397746073.jpg',function(){
  alert('width:' + this.width + 'height:' + this.height);
});

Esto es todo el contenido de este artículo, espero que te haya sido útil. ¡Esperamos que sigas interesado en nuestro sitio web! Si deseas aprender JSP, puedes seguirnos en este sitio.

Declaración: El contenido de este artículo se ha obtenido de la red, y los derechos de autor pertenecen al propietario original. El contenido ha sido contribuido y subido por usuarios de Internet de manera autónoma. Este sitio no posee los derechos de propiedad, no ha sido editado por humanos y no asume ninguna responsabilidad legal relacionada. Si encuentra contenido sospechoso de copyright, por favor envíe un correo electrónico a: notice#oldtoolbag.com (al enviar un correo electrónico, por favor reemplace # con @) para denunciar, y proporcione evidencia relevante. Una vez confirmado, este sitio eliminará inmediatamente el contenido sospechoso de infracción.

Te gustará