Lazy Loading - Implementation Principle

This article mainly explains the principle of lazy loading technology through the following aspects, personal front-end side dishes, please point out any mistakes

1. What is image scroll loading?

  In layman's terms: when visiting a page, first replace the background image path of the img element or other elements with a path with a size of 1*1px (so that you only need to request it once), only when the image appears in the browser. Only when it is within the visible area of ​​​​the device, the true path of the picture is set, so that the picture is displayed. This is image lazy loading.

2. Why use this technology?

  For example, there are many pictures in a page, such as Taobao, Jingdong homepage, etc. If you send so many requests as soon as you come up, the page loading will take a long time. If the js files are placed at the bottom of the document, it happens that the head of the page depends on This js file is not easy to handle. What's more terrible is that the server may be overwhelmed by sending 180 requests as soon as it comes up (and it's not just one or two people visiting this page).

  So the advantages are obvious: not only can it reduce the pressure on the server, but also make the loaded page appear to the user faster (good user experience).

Three, how to achieve?

  The key points are as follows:

      1. If the img element in the page does not have the src attribute, the browser will not send a request to download the image (there is no request, and the performance will be improved). Once the image path is set through javascript, the browser will send the image. ask. It's a bit of a distribution on demand. If you don't want to watch it, I won't show it to you. If you want to watch it, I will show it to you~

  2. How to get the real path ;

  3. Before starting the comparison, first understand some basic knowledge, such as how to obtain the size of an element, the scrolling distance of the scroll bar and the offset position distance;  

  1) The size of the visible window on the screen: corresponding to positions 1 and 2 in the figure

    Native method: window.innerHeight standard browser and IE9+ || document.documentElement.clientHeight standard browser and lower version IE standard mode||

           document.body.clientHeight low version promiscuous mode

       jQuery method: $(window).height() 

  2) The distance between the top of the browser window and the top of the document, that is, the scrolling distance of the scroll bar: that is, the positions corresponding to 3 and 4 in the figure;

    Native method: window.pagYoffset——IE9+ and standard browsers|| document.documentElement.scrollTop Compatible with standard mode of lower versions of ie||

         document.body.scrollTop is compatible with promiscuous mode;

        jQuery method: $(document).scrollTop(); 

  3) Get the size of the element: corresponding to positions 5 and 6 in the figure; the jquery method on the left, the native method on the right

    $(o).width() = o.style.width; 

    $(o).innerWidth() = o.style.width+o.style.padding;

    $(o).outerWidth() = o.offsetWidth = o.style.width+o.style.padding+o.style.border;

    $(o).outerWidth(true) = o.style.width+o.style.padding+o.style.border+o.style.margin;

    Note: To use the native style.xxx method to get attributes, this element must already have an embedded style, such as <div style="...."></div>;

    If the css style was originally defined through an external or internal style sheet, you must use o.currentStyle[xxx] || document.defaultView.getComputedStyle(0)[xxx] to get the style value

  4) Obtain the position information of the element: corresponding to the positions 7 and 8 in the figure

    1) Returns the distance of the element relative to the top and left of the document document;

    jQuery: The distance of the $(o).offset().top element from the top of the document, and the distance of the $(o).offset().left element from the left edge of the document

    Native: getoffsetTop(), there are specific instructions on the elevation, which are ignored here;

      By the way, the offset distance of the returned element relative to the first positioned parent element, pay attention to the difference from the above offset;

        jQuery: position() returns an object, $(o).position().left = style.left, $(o).position().top = style.top;

  4. After knowing how to obtain the element size and offset distance, the next question is: how to judge whether an element has entered or is about to enter the visible window area? Below is a picture to illustrate the problem.

    1) The largest box outside is the size of the actual page, the light blue box in the middle represents the size of the parent element, and objects 1 to 8 represent the actual position of the element on the page; the horizontal direction is explained below!

    2) The offset distance (offsetLeft) of the left border of object 8 relative to the left border of the page is greater than the distance of the right border of the parent element relative to the left border of the page, and the interpretable element is located outside the parent element at this time;

    3) The left border of object 7 crosses the right border of the parent element. At this time: the offset distance (offsetLeft) of the left border of object 7 relative to the left border of the page is less than the right border of the parent element relative to

      The distance from the left border of the page, so object 7 enters the visible area of ​​the parent element;

    4) At the position of object 6, the distance between the right border of object 5 and the left border of the page is greater than the distance between the left border of the parent element and the left border of the page;

    5) At the position of object 5, the distance between the right border of object 5 and the left border of the page is less than the distance between the left border of the parent element and the left border of the page; at this time, it can be judged that the element is outside the visible area of ​​the parent element;

    6) Therefore, two conditions must be satisfied in the horizontal direction to indicate that the element is located in the visible area of ​​the parent element; similarly, the vertical direction must also meet two conditions; see the source code below for details;

Fourth, extend to jquery plugin

  How to use: $("selector").scrollLoad({ parameters are explained in the code })

copy code
(function($) {
    $.fn.scrollLoading = function(options) {
        var defaults = {
            // The attribute name stored in the html tag;
            attr: "data-url",
            // parent element defaults to window
            container: window,
            callback: $.noop
        };
        // Regardless of whether there are parameters passed in, merge them first;
        var params = $.extend({}, defaults, options || {});
        // Convert the parent element to a jquery object;
        var container = $(params.container);
        // Create a new array, and then call the each method to store the data related to each dom object;
        params.cache = [];
        $(this).each(function() {
            // Take out the node type of each dom object in the jquery object, and take out the image path set on each dom object
            var node = this.nodeName.toLowerCase(), url = $(this).attr(params["attr"]);
            //Reorganize, save the attributes on each dom object as an object;
            var data = {
                obj: $(this),
                tags: node,
                url: url
            };
            // add this object to an array;
            params.cache.push(data);
        });

        var callback = function(call) {
            if ($.isFunction(params.callback)) {
                params.callback.call(call);
            }
        };
        
        //Every time a scroll event is triggered, the position of each dom element and container element is judged, and if the conditions are met, the path is given to this dom element!
        var loading = function() {
            // Get the height of the parent element
            var contHeight = container.outerHeight();
            var contWidth = container.outerWidth();

            // Get the distance of the parent element relative to the top of the document page, pay attention here, it is divided into the following two cases;
            if (container.get(0) === window) {
                // In the first case, the parent element is window, and the distance that the browser scroll bar has been scrolled is obtained; $(window) has no offset() method;
                var contop = $ (window) .scrollTop ();
                var conleft = $(window).scrollLeft();
            } else {
                // In the second case, the parent element is a non-window element, get the scrolling distance of its scroll bar;
                var contop = container.offset (). top;
                var conleft = container.offset().left;
            }

            $.each(params.cache, function(i, data) {
                var o = data.obj, tag = data.tag, url = data.url, post, posb, posl, posr;
                if (o) {
                    //The distance between the top of the object and the top of the document, if it is less than the distance between the bottom of the parent element and the top of the document, it means that the vertical direction has entered the visible area;
                    post = o.offset().top - (contop + contHeight);
                    //The distance between the bottom of the object and the top of the document, if it is greater than the distance between the top of the parent element and the top of the document, it means that the vertical direction has entered the visible area;
                    posb = o.offset().top + o.height() - contop;

                    // The same is true in the horizontal direction;
                    posl = o.offset().left - (conleft + contWidth);
                    posr = o.offset().left + o.width() - conleft;

                    // Only when the object is visible and these four conditions are met, can the image path be assigned to this object;
                    if ( o.is(':visible') && (post < 0 && posb > 0) && (posl < 0 && posr > 0) ) {
                        if (url) {
                            //in the browser window
                            if (tag === "img") {
                                //set image src
                                callback(o.attr("src", url));
                            } else {
                                // Set the background url of elements other than img
                                callback(o.css("background-image", "url("+ url +")"));
                            }
                        } else {
                            // No address, trigger the callback directly
                            callback(o);
                        }
                        // After setting the image path for the object, clear the object in params.cache; when the object enters the visible area, it will not be set repeatedly;
                        data.obj = null;
                    }
                }
            });
        };
        // execute after loading
        loading();
        // scroll execution
        container.bind("scroll", loading);
    };
})(jQuery);
copy code

 

5. Reference:

  1. Detailed explanation of jQuery.lazyload

  2. Zhang Da: http://www.zhangxinxu.com/wordpress/?p=1259

  3. Jquery image delay loading plugin jquery.lazyload.  http://www.daxueit.com/article/3944.html
  4. Detailed steps for jQuery.lazyload to realize delayed loading  http://www.daxueit.com/article/21 .html
  5. Analysis of the implementation principle of jquery lazyload delay loading technology  http://www.daxueit.com/article/3777.html

  6, Lazyload delay loading effect

  7. The realization principle of image delay loading (lazyload)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325202038&siteId=291194637