Home  >  Article  >  Web Front-end  >  Analysis and summary of lazy loading and preloading of JavaScript images

Analysis and summary of lazy loading and preloading of JavaScript images

高洛峰
高洛峰Original
2016-12-08 15:17:161148browse

This article mainly introduces the analysis of the two technologies of lazy loading and preloading. Without further ado, let’s take a look.

Lazy loading is also called delayed loading: introduced in the previous article: JS image delayed loading. Delayed loading of images or loading of certain images only when certain conditions are met.

Preloading: Load images in advance and render them directly from the local cache when the user needs to view them.

The essence of the two technologies: the behavior of the two is opposite, one is loading early, and the other is loading slowly or even not at all. Lazy loading has a certain effect on relieving the pressure on the server front-end, while preloading will increase the pressure on the server front-end.

The meaning and implementation methods of lazy loading are:

Meaning: The main purpose of lazy loading is to optimize the server front-end and reduce the number of requests or delay the number of requests.

Implementation method:

1. The first is pure lazy loading, using setTimeOut or setInterval for loading delay.

2. The second is conditional loading, which starts when certain conditions are met or certain events are triggered. Asynchronous download.

3. The third method is to load the visual area, that is, only load the area that the user can see. This is mainly achieved by monitoring the scroll bar. Generally, it will start loading at a certain distance before the user sees a picture. This can Make sure that the user can see the picture when he pulls it down.

The meaning and implementation methods of preloading are:

Preloading can be said to sacrifice the front-end performance of the server in exchange for a better user experience, so that the user's operations can be reflected as quickly as possible. There are many ways to implement preloading, including CSS (background), JS (Image), and HTML (6ed09268cbdd0015bce8dcbbdfa9bfe4). Commonly used is new Image();, set its src to implement preloading, and then use the onload method to call back the preloading completion event. As long as the browser downloads the image locally, the same src will be cached. This is the most basic and practical preloading method. When Image downloads the image header, it will get the width and height, so you can get the size of the image before preloading (the method is to use a timer to cycle through the width and height changes).

How to achieve preloading?

We can search through Google: we can see that many people use this method to preload: the code is as follows:

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

Why other browsers work normally: In fact, the reason is very simple, it is the browser cache. Except for IE6 (that is, Opera can do it, but I specifically tried it with Opera, and it didn't work. It may be a version problem, maybe it has been fixed now.), other browsers will execute the onload method again when you click again, but IE6 directly Taken from the browser.

What to do now? The best case is that the Image can have a status value indicating whether it has been loaded successfully. When loading from the cache, because there is no need to wait, this status value directly indicates that it has been downloaded. When loading from the http request, because it needs to wait for the download, this value is displayed as incomplete. In this case, it can be done. After searching on google, I will introduce it: I found that there is an attribute of Image that is compatible with various browsers - complete. Therefore, just make a judgment on this value before the image onload event. Finally, the code becomes as follows:

function loadImage(url,callback) {
  var img = new Image();
   
  img.src = url;
 
  if(img.complete) { // 如果图片已经存在于浏览器缓存,直接调用回调函数
     
    callback.call(img);
    return; // 直接返回,不用再处理onload事件
  }
 
  img.onload = function(){
    img.onload = null;
    callback.call(img);
  }
}

That is to say, if the image is already in the browser cache, it supports getting it directly from the browser cache, directly executing the function in img.complete and then returning.

But we You can see the code above: you must wait for the image to be loaded, and then you can execute the callback function. It can also be said that after the image is loaded, we can get the width and height of the image. So what if we want to get the size of the image in advance? Internet experience tells me: when the browser loads an image, you will see that the image will first occupy a piece of land and then slowly load. There is no need to preset the width and height attributes because the browser can obtain the header data of the image. Based on this, you only need to use javascript to regularly detect the size status of the image to know the image size ready status. The code is as follows: (But there is a premise that this method is not what I thought, nor is it the code I wrote. It is the code summarized by friends online. I just know that there is such a principle)

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();
    // 完全加载完毕的事件
    img.onload = function () {
      // onload在定时器时间差范围内可能比onready快
      // 这里进行检查并保证onready优先执行
      !onready.end && onready();
      // IE gif动画会循环执行onload,置空onload即可
      img = img.onload = img.onerror = null;
    };
     
     
    // 加入队列中定期执行
    if (!onready.end) {
      list.push(onready);
      // 无论何时只允许出现一个定时器,减少浏览器性能损耗
      if (intervalId === null) {
        intervalId = setInterval(queue, 40);
      };
    };
  }
})();

The calling method is as follows:

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

The above is the entire content of this article


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn