玖叶教程网

前端编程开发入门

懒加载实现的方法有哪些?(三种方法介绍)

本篇文章给大家带来的内容是关于懒加载实现的方法有哪些?(三种方法介绍),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

优势

  1. 性能收益:浏览器加载图片、decode、渲染都需要耗费资源,懒加载能节约性能消耗,缩短onload事件时间。
  2. 节约带宽:这个不需要解释。

通常,我们在html中展示图片,会有两种方式:

  1. img 标签
  2. css background-image

img的懒加载实现

img有两种方式实现懒加载:

  1. 事件监听(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('lazy');

}

});

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>

background-image的实现

background-image的实现跟img的原理基本是一样的,区别是在对class的处理上:

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

渐进式懒加载

渐进式懒加载,指的是存在降级处理,通常html形式如下:

<a href="full.jpg" class="progressive replace">

<img src="tiny.jpg" class="preview" alt="image" />

</a>

这样的代码会有2个好处:

  1. 如果js执行失败,可以点击预览
  2. 大小与实际图一致的占位data URI,避免reflow

最终的代码如下:

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

现成库

推荐下面这个库,使用非常简单:https://www.npmjs.com/package/lozad

以上就是懒加载实现的方法有哪些?(三种方法介绍)的详细内容,更多请关注其它相关文章!

更多技巧请《转发 + 关注》哦!

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言