用 JS 实现图片懒加载,以及如何在 vue 中使用图片懒加载:
- 图片懒加载出现的原因 :
有时候一个网页会包含很多的图片,例如淘宝京东这些购物网站,商品图片多只之又多,页面图片多,加载的图片就多。服务器压力就会很大。不仅影响渲染速度还会浪费带宽。比如一个 1M 大小的图片,并发情况下,达到 1000 并发,即同时有 1000 个人访问,就会产生 1个G 的带宽。为了解决以上问题,提高用户体验,就出现了懒加载方式来减轻服务器的压力,优先加载可视区域的内容,其他部分等进入了可视区域再加载,从而提高性能。
- 懒加载原理 :
一张图片就是一个
<img>
标签,浏览器是否发起请求图片是根据<img>
的 src 属性,所以实现懒加载的关键就是,在图片没有进入可视区域时,先不给<img>
的 src 赋值,这样浏览器就不会发送请求了,等到图片进入可视区域再给 src赋值。
- dataset :
HTML5
中我们可以使用data-
前缀 设置我们需要的自定义属性,来进行一些数据的存放。dataset
自定义属性的格式:data-xx
;前面的data-
是固定的,后面的xx
一 般为表示与自定义属性相关的字符串。img
标签中的data-src
属性就属于一种自定义的dataset
属性。<div id="today" data-food="sushi" data-meal="lunch"> dinner </div> <script> //当我们想要获取这个属性的时候 var today = document.getElementById('today'); var typeOfFood = today.dataset.food; </script>
页面中的
img
元素,如果没有src
属性,浏览器就不会发出请求去下载图片,只有通过javascript
设置了图片路径,浏览器才会发送请求。所以懒加载基本的原理就是用dataset
自定义属性取代src
存储图片的路径,然后在检测到图片进入到可视区域的时候,再将其换为src
。
- 首先将所有图片的
src
换为自定义属性data-src
,这个时候图片是不显示的:
其中 ‘src="./图片懒加载/F1mjpV.gif"’ 为占位符,为了使其效果更明显;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>懒加载</title>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
height: 600px;
box-sizing: border-box;
border: 1px solid black;
}
img {
display: block;
margin: 100px auto;
}
</style>
</head>
<body>
<div id="box">
<ul>
<ul>
<li>
<img data-src="./图片懒加载/1.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/2.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/3.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/4.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/5.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/6.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/7.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/8.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/9.jpg" src="./图片懒加载/F1mjpV.gif" alt="">
</li>
<li>
<img data-src="./图片懒加载/10.jpg" alt="">
</li>
</ul>
</div>
</body>
</html>
- 判断条件 :
window.innerHeight :
可以获取到这个 窗口的高度 (不包括工具栏和滚动条)。
getBoundingClientRect()
方法 : 用来获取页面中某个元素的左、上、右、下分别相对浏览器视窗的位置,返回的是一个矩形对象,包括四个属性,分别是 left 、top、right、bottom。分别表示元素各边与页面上边和左边的距离。基本的判断就是如果该图片距离窗口上方的位置小于窗口的高度(也就是说该图片已经进入了窗口),那么就将该图片的
src
属性赋为data-src
找那个存的图片路径。然后 全局绑定scroll
事件,在滚动页面的时候,图片进入到窗口后,500ms
之后才会显示出图片。
<script>
function imgonload() {
let img = document.querySelectorAll("img");
/*console.log(img);*/
for(let i=0; i<img.length; i++) {
if(img[i].getBoundingClientRect().top < window.innerHeight) {
//图片一旦有src就会加载出来,所以图片的路径不会放在src中,而是一个自定义的属性data-src中
img[i].src = img[i].dataset.src;
}
}
}
function scollImg(fn) {
let timer = null;
let context = this;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(context);
}, 500)
}
}
window.onload = imgonload;
window.onscroll = scollImg(imgonload);
</script>
- 在 vue 中使用图片懒加载
实现方法 ---> (使用 vue 的 vue-lazyload 插件)
- 安装插件 :
npm install vue-lazyload --save-dev
- 在入口文件 main.js 中引入并使用 :
import VueLazyload from 'vue-lazyload'
在这里可以选择 直接使用,或者 添加自定义选项 :
直接使用 :
Vue.use(VueLazyload)
或者添加自定义选项 :
Vue.use(VueLazyLoad,{ error:'data-src', //加载图片出错了,显示的图片 loading:'data-src' //加载中,显示的图片(预加载显示的图片) attempt:3, //尝试加载的图片数量 preLoad:1.3, //预加载的高度比例 listenEvents:['scroll'] //触发的事件 (监听) })
- 修改图片显示方式为懒加载(将 :src 属性直接改为 v-lazy ):
<a href="javascript:;"><img v-lazy="'/static/img/' + item.productImage"></a> <!-- 原: --> <img :src="emptyGif"> <!-- 现: --> <img v-lazy="emptyGif">
美酒没故事°: 弄完了,但并不是在使用的地方按需加载啊,而是在项目加载的时候把elementUI就加载了
乐乐码代码: 可以改成六列吗?
点滴_53353950: 谢谢分享
coder__Song: 文章非常好,支持一下作者
Sir_Manley: ES6这个怎么使用