页面性能优化-原生JS实现图片懒加载
在项目开发中,我们往往会遇到一个页面需要加载很多图片的情况。我们可以一次性加载全部的图片,但是考虑到用户有可能只浏览部分图片。所以我们需要对图片加载进行优化,只加载浏览器窗口内的图片,当用户滚动时,再加载更多的图片。这种加载图片的方式叫做图片懒加载,又叫做按需加载或图片的延时加载。这样做的好处是:1.可以加快页面首屏渲染的速度;2.节约用户的流量。
一.实现思路
1.图片img标签自定义一个属性data-src来存放真实的地址。
2.当滚动页面时,检查所有的img标签,判断是否出现在事业中,如果出现在视野中,继续进行判断,看齐是否被加载过了,如果没有加载,那就进行加载。
判断图片元素是否处于浏览器视野中的示意图(手绘):

二.根据思路完成代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>原生js实现图片懒加载</title>
<style>
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
ul{
overflow: hidden;
list-style: none;
}
li{
float: left;
width: 50%;
height: 200px;
padding: 10px;
}
li img{
display: inline-block;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="container">
<ul>
<li><img src="http://cdn.jirengu.com/book.jirengu.com/img/1.jpg" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/1.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/2.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/3.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/4.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/5.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/6.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/7.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/8.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/9.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/10.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/11.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/12.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/13.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/14.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/15.jpg"></li>
<li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/16.jpg"></li>
</ul>
</div>
<script>
// window绑定滚动事件
window.addEventListener('scroll',function(){
// 遍历所有的img标签
Array.prototype.slice.apply(document.getElementsByTagName('li')).forEach((li)=>{
let img=li.getElementsByTagName('img')[0];
// 判断当前img是否出现在了视野中
// 判断当前img是否被加载过了
if(checkShow(img) && !isLoaded(img)){
loadImg(img);
}
})
}); // 判断img是否出现浏览器视野中
function checkShow(img) {
let scrollTop=document.documentElement.scrollTop; // 页面向上滚动的高度
let windowHeight=window.innerHeight; //浏览器自身高度
let offsetTop=img.offsetTop; //目标标签相对于document的高度
return (offsetTop > scrollTop && offsetTop <(windowHeight + scrollTop));
} // 判断是否已经加载过
function isLoaded(img) {
return img.getAttribute('src')===img.getAttribute('data-src');
} // 加载图片
function loadImg(img) {
img.setAttribute('src',img.getAttribute('data-src'));
}
</script>
</body>
</html>
好了,在浏览器中运行一下,第一次进页面如果不滚动滚轮的话什么也看不到,所以第一次进页面需要调用checkShow(),处于视野中的图片也加载出来。
在代码最后加上:
// 第一次进页面加载处于视野中的图片
Array.prototype.slice.apply(document.getElementsByTagName('li')).forEach((li)=>{
let img=li.getElementsByTagName('img')[0];
// 判断当前img是否出现在了视野中
// 判断当前img是否被加载过了
if(checkShow(img) && !isLoaded(img)){
loadImg(img);
}
})
此时我们发现判断加载视野中的图片代码存在重复,直接封装成一个新的方法lazyRenderImg();
// window绑定滚动事件
window.addEventListener('scroll',function(){
// 遍历所有的img标签
lazyRenderImg();
}); function lazyRenderImg(){
Array.prototype.slice.apply(document.getElementsByTagName('li')).forEach((li)=>{
let img=li.getElementsByTagName('img')[0];
// 判断当前img是否出现在了视野中
// 判断当前img是否被加载过了
if(checkShow(img) && !isLoaded(img)){
loadImg(img);
}
})
} // 第一次进页面加载处于视野中的图片
lazyRenderImg();
三.性能优化
问题:window.scroll 方法页面只要一滚动就会触发里面的方法,对性能影响很大
解决方法:当页面停止滚动的时候,再去执行页面中的方法,类似与函数节流(throttle)
Tips:函数节流:等时间间隔执行函数, 让一个函数不要执行得太频繁,减少一些过快的调用来节流。
// window绑定滚动事件
let timer;
window.addEventListener('scroll',function(){
console.log('scroll')
// 遍历所有的img标签
if(timer){
clearTimeout(timer)
}
timer=setTimeout(()=>{
console.log('lazyRenderImg...');
lazyRenderImg();
},300);
通过打印的日志发现当滚动停止后才执行lazyRenderImg方法的,确实减少了不必要调用lazyRenderImg的次数。

页面性能优化之图片懒加载就写这么多了,网页优化还有很多方法与技巧,前端路漫漫其修远兮,吾将上下而求索。本文不足之处,请多指正。
参考资料:
https://www.jianshu.com/p/1b32e16ed0e5
页面性能优化-原生JS实现图片懒加载的更多相关文章
- 原生js实现图片懒加载+加入节流
这两天在学习图片的懒加载实现,看了很多大佬的博客,终于有了点成果.现在用了其中一位大佬的文章中的代码实现了图片懒加载并且在其基础上加入了节流函数. 原理就不多讲了,有需要的可以去大佬的文章看看.大佬文 ...
- 2.原生js实现图片懒加载
网上查了很多图片懒加载的内容, 但基本上都是jQuery实现的, 没有说清楚其原理, 所以研究了一下 多的不说, 上代码, 看不明白的建议看下我的上一篇文章<1. 图解浏览器和用户设备的宽高等属 ...
- js插件---图片懒加载echo.js结合 Amaze UI ScrollSpy 使用
js插件---图片懒加载echo.js结合 Amaze UI ScrollSpy 使用 一.总结 一句话总结:图片懒加载echo.js结合 Amaze UI ScrollSpy 使用的效果就是:懒加载 ...
- js插件---图片懒加载lazyload
js插件---图片懒加载lazyload 一.总结 一句话总结:使用异常简单,src里面放加载的图片,data-original里面放原图片,不懂的位置去官网或者github找API就好. 1.laz ...
- JS实现图片懒加载插件
一.前言 我在前几篇博客的记录中,有说自己在做一个图片懒加载的功能,然后巴拉巴拉的遇到哪些问题,结果做完了也没对懒加载这个功能做一些记录,所以这篇文章主要针对我所实现的思路,以及代码做个记录,实现不佳 ...
- js实现图片懒加载原理
原理 图片懒加载是前端页面优化的一种方式,在页面中有很多图片的时候,图片加载就需要很多时间,很耗费服务器性能,不仅影响渲染速度还会浪费带宽,为了解决这个问题,提高用户体验,所以就出现了懒加载这种方式来 ...
- js实现图片懒加载
大型购物网站都会采用图片懒加载技术来优化网站首页打开速度,以提高用户体验,那么具体是怎么实现的呢,我们一探究竟. html结构(div包裹一层用来显示背景图片,等待图片加载完成后,显示真实图片) &l ...
- js, javascript 图片懒加载 实例代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Js 之图片懒加载插件
一.PC端(lazyload) 1.引入js文件 <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.m ...
随机推荐
- cannot import name '_imaging' 与No module named PIL解决方法
今天学习廖雪峰的python 第三方模块pillow一章. 直接使用from PIL import Image 会报"No module named PIL",显然这是没有安装pi ...
- OAuth 2.0中文译本
(一)背景知识 OAuth 2.0很可能是下一代的“用户验证和授权”标准,目前在国内还没有很靠谱的技术资料.为了弘扬“开放精神”,让业内的人更容易理解“开放平台”相关技术,进而长远地促进国内开放平台领 ...
- Java基础知识总结【转+整合】
写代码: 1.明确需求.自己要做什么? 2.分析思路.怎么做? 3.确定步骤.每个思路部分用到哪些语句,方法和对象. 4.代码实现.用具体的java语言代码把思路体现出来. 学习新技术的四点: 1,该 ...
- Unity3d Mecanim动画系统Animator学习笔记
1. unity3d Mecanim学习 Unity3d新版动画系统网上的介绍很多,但多是流水笔记,外人很难看明白,后来我 终于找到介绍的比较明白的两个作者,特别感谢.一个是58开发网的乐天老师,课 ...
- flex 生成多边形时内、外环计算
//顺时钟 var pA:Array = [{x:"2969925.6674000006",y:"476254.4874999998"},{x:"29 ...
- 手把手教你如何安装Pycharm——靠谱的Pycharm安装详细教程
今天小编给大家分享如何在本机上下载和安装Pycharm,具体的教程如下: 1.首先去Pycharm官网,或者直接输入网址:http://www.jetbrains.com/pycharm/downlo ...
- 条件随机场CRF(二) 前向后向算法评估标记序列概率
条件随机场CRF(一)从随机场到线性链条件随机场 条件随机场CRF(二) 前向后向算法评估标记序列概率 条件随机场CRF(三) 模型学习与维特比算法解码 在条件随机场CRF(一)中我们总结了CRF的模 ...
- Django 项目创建之前的环境搭建
安装虚拟管理环境 sudo apt install virtualenv 在项目中运行 virtualenv fruitenv 进入到环境中 source fruitenv/bin/activate ...
- Python_struct模块操作二进制文件
''' 使用struct模块写入二进制文件 ''' import struct n=130000000 x=96.45 b=True s='a1@中国' sn=struct.pack('if?',n, ...
- Spring Boot使用RestTemplate消费REST服务的几个问题记录
我们可以通过Spring Boot快速开发REST接口,同时也可能需要在实现接口的过程中,通过Spring Boot调用内外部REST接口完成业务逻辑. 在Spring Boot中,调用REST Ap ...