Home  >  Article  >  Web Front-end  >  What are the methods to implement lazy loading? (Introduction to three methods)

What are the methods to implement lazy loading? (Introduction to three methods)

不言
不言forward
2019-01-08 10:26:503935browse

What this article brings to you is what are the methods to implement lazy loading? (Introduction to three methods), it has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Advantages

  1. Performance benefits: The browser consumes resources to load images, decode, and render. Lazy loading can save performance consumption and shorten the onload event time.

  2. Saving bandwidth: This needs no explanation.

Usually, we display images in html in two ways:

  1. img tag

  2. css background-image

Lazy loading implementation of img

Img has two ways to implement lazy loading:

  1. Event monitoring (scroll, resize, orientationChange)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>event</title>
    <style>
        img {
            background: #F1F1FA;
            width: 400px;
            height: 300px;
            display: block;
            margin: 10px auto;
            border: 0;
        }
    </style>
</head>
<body>
    <img src="https://ik.imagekit.io/demo/img/image1.jpeg?tr=w-400,h-300" />
    <img src="https://ik.imagekit.io/demo/img/image2.jpeg?tr=w-400,h-300" />
    <img src="https://ik.imagekit.io/demo/img/image3.jpg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image2.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image3.jpg?tr=w-400,h-300" /> -->
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image4.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image5.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image6.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image7.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image8.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image9.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image10.jpeg?tr=w-400,h-300" />
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var lazyloadImages = document.querySelectorAll("img.lazy");    
            var lazyloadThrottleTimeout;
            
            function lazyload () {
                if(lazyloadThrottleTimeout) {
                    clearTimeout(lazyloadThrottleTimeout);
                }    
                
                lazyloadThrottleTimeout = setTimeout(function() {
                    var scrollTop = window.pageYOffset;
                    lazyloadImages.forEach(function(img) {
                        if(img.offsetTop < (window.innerHeight + scrollTop)) {
                            img.src = img.dataset.src;
                            img.classList.remove(&#39;lazy&#39;);
                        }
                    });
                    if(lazyloadImages.length == 0) {
                        document.removeEventListener("scroll", lazyload);
                        window.removeEventListener("resize", lazyload);
                        window.removeEventListener("orientationChange", lazyload);
                    }
                }, 20);
            }
            
            document.addEventListener("scroll", lazyload);
            window.addEventListener("resize", lazyload);
            window.addEventListener("orientationChange", lazyload);
        });
    </script>
</body>
</html>
  1. Intersection Observer (compatibility issue)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>observer</title>
    <style>
        img {
            background: #F1F1FA;
            width: 400px;
            height: 300px;
            display: block;
            margin: 10px auto;
            border: 0;
        }
    </style>
</head>
<body>
    <img src="https://ik.imagekit.io/demo/img/image2.jpeg?tr=w-400,h-300" />
    <img src="https://ik.imagekit.io/demo/img/image3.jpg?tr=w-400,h-300" /> -->
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image1.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image2.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image3.jpg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image4.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image5.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image6.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image7.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image8.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image9.jpeg?tr=w-400,h-300" />
    <img class="lazy" src="https://ik.imagekit.io/demo/img/image10.jpeg?tr=w-400,h-300" />
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var lazyloadImages = document.querySelectorAll(".lazy");
            var imageObserver = new IntersectionObserver(function(entries, observer) {
                entries.forEach(function(entry) {
                    if (entry.isIntersecting) {
                        var image = entry.target;
                        image.src = image.dataset.src;
                        image.classList.remove("lazy");
                        imageObserver.unobserve(image);
                    }
                });
            });
            lazyloadImages.forEach(function(image) {
                imageObserver.observe(image);
            });
        });
    </script>
</body>
</html>

background The implementation of -image

The implementation of background-image is basically the same as the principle of img. The difference is in the processing of classes:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>background</title>
    <style>
        body {
            margin: 0;
        }
        .bg {
            height: 200px;
        }
        #bg-image.lazy {
            background-image: none;
            background-color: #F1F1FA;
        }
        #bg-image {
            background-image: url("https://ik.imagekit.io/demo/img/image1.jpeg?tr=w-400,h-300");
            background-size: 100%;
        }
    </style>
</head>
<body>
    <p id="bg-image" class="bg lazy"></p>
    <p id="bg-image" class="bg lazy"></p>
    <p id="bg-image" class="bg lazy"></p>
    <p id="bg-image" class="bg lazy"></p>
    <p id="bg-image" class="bg lazy"></p>
    <p id="bg-image" class="bg lazy"></p>
    <p id="bg-image" class="bg lazy"></p>
    <p id="bg-image" class="bg lazy"></p>
    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var lazyloadImages = document.querySelectorAll(".lazy");
            var imageObserver = new IntersectionObserver(function(entries, observer) {
                entries.forEach(function(entry) {
                    if (entry.isIntersecting) {
                        var image = entry.target;
                        image.classList.remove("lazy");
                        imageObserver.unobserve(image);
                    }
                });
            });
            lazyloadImages.forEach(function(image) {
                imageObserver.observe(image);
            });
        });
    </script>
</body>
</html>

Progressive lazy loading

Progressive lazy loading refers to the existence of downgrade processing. Usually the HTML format is as follows:

<a href="full.jpg" class="progressive replace">
  <img src="tiny.jpg" class="preview" alt="image" />
</a>

Such code will have 2 benefits:

  1. If js execution fails, You can click to preview

  2. The placeholder data URI with the same size as the actual image to avoid reflow

The final code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>progressive</title>
    <style>
        a.progressive {
            position: relative;
            display: block;
            overflow: hidden;
            outline: none;
        }
        a.progressive:not(.replace) {
            cursor: default;
        }
        a.progressive img {
            display: block;
            width: 100%;
            max-width: none;
            height: auto;
            border: 0 none;
        }
        a.progressive img.preview {
            filter: blur(2vw);
            transform: scale(1.05);
        }
        a.progressive img.reveal {
            position: absolute;
            left: 0;
            top: 0;
            will-change: transform, opacity;
            animation: reveal 1s ease-out;
        }
        @keyframes reveal {
            0% {transform: scale(1.05); opacity: 0;}
            100% {transform: scale(1); opacity: 1;}
        }
    </style>
</head>
<body>
    <a href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/nature5.jpg" srcset="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/nature5.jpg 800w, https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/nature5big.jpg 1600w" class="progressive replace">
        <img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2NjIpLCBxdWFsaXR5ID0gNzAK/9sAQwAKBwcIBwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47/9sAQwEKCwsODQ4cEBAcOygiKDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7/8AAEQgABQAUAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A5yC3e2S3gM7OEQHdgA57VTuLAPqUoaUk7yM7R2BPSiivS5VN8stjmk2ldGVM3lyshG7bxk0UUV4skk2jdN2P/9k=" class="preview" alt="palm trees" />
    </a>
    <a href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/nature2.jpg" class="progressive replace">
        <img src="http://lorempixel.com/20/15/nature/2/" class="preview" alt="sunset" />
    </a>
    <a href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/nature3.jpg" class="progressive replace">
        <img src="http://lorempixel.com/20/15/nature/3/" class="preview" alt="tide" />
    </a>
    <a href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/nature5.jpg" srcset="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/nature5.jpg 800w, https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/nature5big.jpg 1600w" class="progressive replace">
        <img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD//gA7Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2NjIpLCBxdWFsaXR5ID0gNzAK/9sAQwAKBwcIBwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47/9sAQwEKCwsODQ4cEBAcOygiKDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7/8AAEQgABQAUAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/aAAwDAQACEQMRAD8A5yC3e2S3gM7OEQHdgA57VTuLAPqUoaUk7yM7R2BPSiivS5VN8stjmk2ldGVM3lyshG7bxk0UUV4skk2jdN2P/9k=" class="preview" alt="palm trees" />
    </a>
    <a href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/nature2.jpg" class="progressive replace">
        <img src="http://lorempixel.com/20/15/nature/2/" class="preview" alt="sunset" />
    </a>
    <a href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/123941/nature3.jpg" class="progressive replace">
        <img src="http://lorempixel.com/20/15/nature/3/" class="preview" alt="tide" />
    </a>
    <script>
        window.addEventListener('load', function() {
            var pItem = document.getElementsByClassName('progressive replace'), timer;

            window.addEventListener('scroll', scroller, false);
            window.addEventListener('resize', scroller, false);
            inView();

            function scroller(e) {
                timer = timer || setTimeout(function() {
                    timer = null;
                    requestAnimationFrame(inView);
                }, 300);
            }

            function inView() {
                var scrollTop = window.pageYOffset;
                var innerHeight = window.innerHeight;
                var p = 0;
                while (p < pItem.length) {
                    var offsetTop = pItem[p].offsetTop;
                    if (offsetTop < (scrollTop + innerHeight)) {
                        loadFullImage(pItem[p]);
                        pItem[p].classList.remove('replace');
                    }
                    else p++;
                }
            }


            function loadFullImage(item) {
                var img = new Image();
                if (item.dataset) {
                    img.srcset = item.dataset.srcset || '';
                    img.sizes = item.dataset.sizes || '';
                }
                img.src = item.href;
                img.className = 'reveal';
                if (img.complete) addImg();
                else img.onload = addImg;

                function addImg() {
                    item.addEventListener('click', function(e) { e.preventDefault(); }, false);
                    item.appendChild(img).addEventListener('animationend', function(e) {
                        var pImg = item.querySelector('img.preview');
                        if (pImg) {
                            e.target.alt = pImg.alt || '';
                            item.removeChild(pImg);
                            e.target.classList.remove('reveal');
                        }
                    });
                }

            }

        }, false);
    </script>
</body>
</html>

Ready-made library

Recommend the following library, which is very simple to use: https://www.npmjs.com/package/lozad

The above is the detailed content of What are the methods to implement lazy loading? (Introduction to three methods). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete