原生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的次数。

以上所述是小编给大家介绍的原生JS实现图片懒加载之页面性能优化,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • javascript瀑布流式图片懒加载实例解析与优化

    之前写过一版图片"懒加载"的文章,刚好周末在整理文件的时候,大概又看了一遍之前写的代码发现有很多可以优化的地方. 这篇文章主要就是结合上篇<javascript瀑布流式图片懒加载实例>再来看看图片"懒加载"的一些知识. 图片"懒加载"的主旨: 按照需要加载图片,也就是说需要显示的时候再加载图片显示,减少一次性加载的网络带宽开销. 先来看一段代码: var conf = { 'loadfirst': true, 'loadimg': t

  • 整理AngularJS框架使用过程当中的一些性能优化要点

    1. 简介 无论你正在编写一个旧的应用程序还是在一个大型应用中采用AngularJS,性能是一个重要的方面.了解是什么原因导致AngularJS应用程序慢下来非常重要,要知道,在开发过程中做出权衡是很重要的.本文将介绍一些AngularJS比较常见的性能问题,以及优化的建议. 2. 性能测试工具 本文采用jsPerf http://jsperf.com/ 性能测试的基准. 3. 软件性能 评价软件性能有两个基本的因素: 首先是算法的时间复杂度.一个简单的例子就是线性搜索和二分检索有着非常显著的性

  • 快速实现JS图片懒加载(可视区域加载)示例代码

    js懒加载图片 如何提高网页加载速度?在网页中有许多img标签,这些标签就是图片,其属性src则是指向服务器地址,当浏览器从上往下读取到src标签中的地址时,浏览器就会开启线程,加载这张图片.而并不是等到整张页面都解析完成才加载图片.我们要做的就是加载用户可视范围内的图片. js懒加载图片的目的 1.网页优化,提高网页加载速度 2.页面优化友好,提高SEO收录与排名 3.提高用户体验,减少服务器压力 实例代码如下: <!DOCTYPE html> <html lang="en&

  • js性能优化技巧

    性能优化:简而言之,就是在不影响系统运行正确性的前提下,使之运行地更快,完成特定功能所需的时间更短 http:超文本协议 它的最上层是应用层 传输层 网络层 物理层 请求信息:请求行 请求头 空行 消息体 响应信息:状态行和状态码 使用值类型的ToString方法: 在连接字符串时,经常使用"+"号直接将数字添加到字符串中.这种方法虽然简单,也可以得到正确结果,但是由于涉及到不同的数据类型,数字需要通过装箱操作转化为引用类型才可以添加到字符串中.但是装箱操作对性能影响较大,因为在进行这

  • 基于javascript实现图片懒加载

    一.定义 图片延迟加载也称为懒加载,延迟加载图片或符合某些条件时才加载某些图片,通常用于图片比较多的网页.可以减少请求数或者延迟请求数,优化性能.  二.呈现形式 [1]延时加载,使用setTimeout或setInterval进行加载延迟,如果用户在加载前就离开,自然就不会进行加载. [2]条件加载,符合某些条件或者触发了某些条件才开始异步加载. [3]可视区域加载,仅仅加载用户可以看到的区域,这个主要监控滚动条来实现,一般距离用户看到的底边很近的时候开始加载,这样能保证用户下拉时图片正好接上

  • 解析javascript图片懒加载与预加载的分析总结

    本篇文章主要介绍了懒加载和预加载两种技术的解析,废话不多说,一起来看吧. 懒加载也叫延迟加载:前一篇文章有介绍:JS图片延迟加载 延迟加载图片或符合某些条件时才加载某些图片. 预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染. 两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载.懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力. 懒加载的意义及实现方式有: 意义: 懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数. 实现方式:

  • JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)

    函数节流,简单地讲,就是让一个函数无法在很短的时间间隔内连续调用,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用. 函数节流的原理挺简单的,估计大家都想到了,那就是定时器.当我触发一个时间时,先setTimout让这个事件延迟一会再执行,如果在这个时间间隔内又触发了事件,那我们就clear掉原来的定时器,再setTimeout一个新的定时器延迟一会执行,就这样. 以下场景往往由于事件频繁被触发,因而频繁执行DOM操作.资源加载等重行为,导致UI停顿甚至浏览器崩溃. 1.

  • js前端实现图片懒加载(lazyload)的两种方式

    在实际的项目开发中,我们通常会遇见这样的场景:一个页面有很多图片,而首屏出现的图片大概就一两张,那么我们还要一次性把所有图片都加载出来吗?显然这是愚蠢的,不仅影响页面渲染速度,还浪费带宽.这也就是们通常所说的首屏加载,技术上现实其中要用的技术就是图片懒加载--到可视区域再加载. 思路: 将页面里所有img属性src属性用data-xx代替,当页面滚动直至此图片出现在可视区域时,用js取到该图片的data-xx的值赋给src. 关于各种宽高: 页可见区域宽: document.body.clien

  • JavaScript性能优化总结之加载与执行

    前言 无论当前 JavaScript 代码是内嵌还是在外链文件中,页面的下载和渲染都必须停下来等待脚本执行完成.JavaScript 执行过程耗时越久,浏览器等待响应用户输入的时间就越长.浏览器在下载和执行脚本时出现阻塞的原因在于,脚本可能会改变页面或 JavaScript 的命名空间,它们对后面页面内容造成影响.一个典型的例子就是在页面中使用document.write(),例如清单 1 清单 1 JavaScript 代码内嵌示例 <html> <head> <title

  • javascript瀑布流式图片懒加载实例

    最近项目使用到了"懒加载",现在更新一般,因为平时主要使移动端的开发所以库文件使用的是zepto.js .当然也可以和jQuery 通用. 代码如下: /** * Created by zhiqiang on 2015/10/14. * hpuhouzhiqiang@gmail.com * 图片的懒加载 **/ function loadImgLazy(node) { var lazyNode = $('[node-type=imglazy]', node), mobileHeight

  • JavaScript性能优化之小知识总结

    随着网络的发展,网速和机器速度的提高,越来越多的网站用到了丰富客户端技术.而现在Ajax则是最为流行的一种方式.JavaScript是一种解释型语言,所以能无法达到和C/Java之类的水平,限制了它能在客户端所做的事情,为了能改进他的性能,我想基于我以前给JavaScript做过的很多测试来谈谈自己的经验,希望能帮助大家改进自己的JavaScript脚本性能. 前言 一直在学习javascript,也有看过<犀利开发Jquery内核详解与实践>,对这本书的评价只有两个字犀利,可能是对javas

  • JavaScript实现图片懒加载(Lazyload)

    懒加载的意义(为什么要使用懒加载) 对页面加载速度影响最大的就是图片,一张普通的图片可以达到几M的大小,而代码也许就只有几十KB.当页面图片很多时,页面的加载速度缓慢,几S钟内页面没有加载完成,也许会失去很多的用户. 所以,对于图片过多的页面,为了加速页面加载速度,所以很多时候我们需要将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区域后再去加载.这样子对于页面加载性能上会有很大的提升,也提高了用户体验. 原理 将页面中的img标签src指向一张小图片或者src为空,然后定义data

  • javascript性能优化之事件委托实例详解

    本文实例分析了javascript性能优化之事件委托.分享给大家供大家参考,具体如下: 为下面每个LI绑定一个click事件 <ul id="myLinks"> <li id="goSomewhere" >Go somewhere</li> <li id="doSomething" >Do something</li> <li id="sayHi" >Sa

随机推荐