>웹 프론트엔드 >JS 튜토리얼 >지연 로딩을 구현하는 방법은 무엇입니까? (3가지 방법 소개)

지연 로딩을 구현하는 방법은 무엇입니까? (3가지 방법 소개)

不言
不言앞으로
2019-01-08 10:26:504036검색

이 기사에서 제공하는 내용은 지연 로딩을 구현하는 방법이 무엇인지입니다. (3가지 방법 소개) 도움이 필요한 친구들이 참고하면 좋을 것 같습니다.

장점

  1. 성능 이점: 브라우저는 이미지 로드, 디코딩 및 렌더링을 위해 리소스를 소비합니다. 지연 로딩은 성능 소모를 줄이고 온로드 이벤트 시간을 단축할 수 있습니다.

  2. 대역폭 절약: 설명이 필요하지 않습니다.

일반적으로 우리는 두 가지 방법으로 html로 이미지를 표시합니다:

  1. img 태그

  2. css background-image

img 지연 로딩 구현

img는 두 가지 방법으로 구현될 수 있습니다 지연 로딩:

  1. 이벤트 모니터링(스크롤, 크기 조정, 방향 변경)

<!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(호환성 문제)

<!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>

배경 이미지 구현

배경 이미지 구현은 img와 동일 원칙은 기본적으로 동일하며 차이점은 클래스 처리에 있습니다.

<!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은 다운그레이드 처리가 있음을 의미하며 일반적으로 HTML 형식은 다음과 같습니다.

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

이러한 코드에는 2개의 하나가 있습니다. 이점:

  1. js 실행이 실패하면 클릭하여 미리 볼 수 있습니다.

  2. 리플로우를 방지하기 위해 실제 이미지와 동일한 크기의 자리 표시자 데이터 URI

최종 코드는 다음과 같습니다.

<!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

아래 추천 이 라이브러리는 사용이 매우 간단합니다: https://www.npmjs.com/package/lozad

위 내용은 지연 로딩을 구현하는 방법은 무엇입니까? (3가지 방법 소개)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제