性能优化之图片懒加载使用vue-lazyload或IntersectionObserver观察检测者

云英
• 阅读 1899

懒加载问题描述

  • 网站上有大量图片,若一次性直接请求所有的图片资源,很显然时间等待过长,浪费资源。
  • 所以我们就需要需要给图片做一个懒加载,即:等看到图片,或者快看到图片时,才去加载
  • 就像移动端下拉加载一样
  • 也有种数据分页的感觉

懒加载问题解决思路

  • 第一步,初始时,先给图片一个loading.gif作为imgsrc的值,使其显示加载中,如:img.src = loading.gif
  • 第二步,判断元素是否进入视口,是否(即将)能看到,再将imgsrc的值,替换为真正的需求请求地址的值
  • 第三步,当imgsrc的值的时候,就会立刻发请求,请求服务器的资源,请求成功了,就成功了,就达到我们想要的效果
  • 第四步,兜错,若图片加载请求失败的话,再将imgsrc替换成一张加载失败错误的图片src即可

这里有两个重点,大家需要注意:

问题一:如何判断元素是否进入可视区域?

问题二:如何判断图片加载成功或失败了?

这两个问题的答案后文会提到,大家继续往下阅读

图片懒加载效果

最终实现的就是这样的效果

性能优化之图片懒加载使用vue-lazyload或IntersectionObserver观察检测者

也可以去笔者的个人网站上,看效果图:http://ashuai.work:8888/#/img...

解决方案

  • 或者使用现有的插件
  • 或者自己写一个

方案一 插件就是好!vue-lazyload

推荐使用vue-lazyload插件各方面都很优化,官方地址:https://www.npmjs.com/package...

使用步骤,这里笔者就不赘述了,上述的效果图,也是通过这个vue-lazyload插件实现的,对应代码,在笔者的GitHub仓库中:https://github.com/shuirongsh...

方案二 自己手写一个自定义指令v-lazyload

写一个自定义指令,便于逻辑复用

如何判断元素是否进入视口了?

麻烦一些的方案:监听拥有滚动条的scroll事件,去计算元素距离拥有滚动条的位置,这里笔者总结了一个公式:

  • 滚动距离出现 = .target距顶部高度 - .scrollBox距顶部高度 - .scrollBox自身高度
  • 边界值 = 目标元素距顶部高度 - 滚动盒子容器距顶部高度 - 滚动盒子容器自身高度

相关代码案例,请看笔者的这篇文章:https://segmentfault.com/a/11...

使用IntersectionObserver类构造函数,去判断元素是否进入视口

IntersectionObserver是一个非常强大的api,可以观测很多东西的变化,very good,在浏览器版本不断更新迭代的现在,其兼容性已经非常不错了,大家可以放心使用。

关于IntersectionObserver的语法,笔者不赘述了,咱们直接上自定义指令代码

自定义指令代码

// let loadimage = "http://ashuai.work:10000/imgGifSrc/loading.gif" // 服务器加载中图片
// let errorimage = "http://ashuai.work:10000/imgGifSrc/error.gif" // 服务器加载中图片

let loadimage = require('../../assets/imgLazyload/loading.gif')  // 本地加载中图片
let errorimage = require('../../assets/imgLazyload/error.gif')  // 本地加载失败图片

export default {
    inserted(el, binding, vnode) { 
        // 1. 先让图片显示加载中...
        el.src = loadimage.default 
        // 2. 实例化一个:观察检测者
        const observer = new IntersectionObserver((entries) => {
            // 4. 在观察监测者的对应执行函数中获取到isIntersecting属性(是否交叉)
            let isIntersecting = entries[0].isIntersecting 
            // 5. 如果交叉了,就让其去加载对应src的真正的地址
            if (isIntersecting) { 
                el.src = binding.value
                // 6. 加载成功就不用管它
                el.onload = (res) => console.log('加载成功', res); 
                // 7. 加载失败了就去做一个错误图片的占位
                el.onerror = (err) => {
                    console.log('加载失败', err);
                    el.src = errorimage.default
                }
                // 8. 无论加载成功或失败,都停止观察任务了
                observer.unobserve(el)
            }
        })
        // 3. 让这个观察检测者去观察对应img标签图片
        observer.observe(el)
    },
}

使用代码

使用的话,很简单,直接:

<img class='imgLazy' v-lazyload="'http://ashuai.work:10000/imgSrc/doupo.png'" />
<img class='imgLazy' v-lazyload="'http://ashuai.work:10000/imgSrc/douluo.png'" />
<img class='imgLazy' v-lazyload="'http://ashuai.work:10000/imgSrc/tunshi.png'" />
注意使用自定义指令别忘了要注册哦

最后,烦请各位道友去笔者的GitHub仓库看看,如果觉得对您有一点点帮助的话,不妨不吝star😀

自定义指令的完整代码也在笔者的GitHub仓库中哦
点赞
收藏
评论区
推荐文章
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Jacquelyn38 Jacquelyn38
4年前
Vue.js的图片加载性能优化你可以试试
前言图片加载优化对于一个网站性能好坏起着至关重要的作用。所以我们使用Vue来操作一波。备注以下的优化一、优化二栏目都是我自己封装在Vue的工具函数里,所以请认真看完,要不然直接复制的话,容易出错的。资源Vue.jsElementUI优化一:图片加载动画只有当图片加载完成后才可以显示图片,加载动画结束。我们使用ElementUI
Dax Dax
4年前
前端性能优化
前端性能优化1、减少资源的请求次数和大小压缩合并js和css文件,减少http请求次数和请求资源的大小;在项目中使用webpackglup等打包编译工具2、尽量使用字体图标或者svg图标代替传统的png(jpg)图渲染更快,减少代码体积,且放大不会出现变形等3、使用图片懒加载目的是减少页面第一次加载的http请求次数,实现思路:
Easter79 Easter79
4年前
vue 路由 懒加载
原文链接: vue路由懒加载(https://my.oschina.net/ahaoboy/blog/1618024)路由懒加载当打包构建应用时,Javascript包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。结合Vue的异步组
浩浩 浩浩
4年前
【Flutter实战】图片和Icon
3.5图片及ICON3.5.1图片Flutter中,我们可以通过Image组件来加载并显示图片,Image的数据源可以是asset、文件、内存以及网络。ImageProviderImageProvider是一个抽象类,主要定义了图片数据获取的接口load(),从不同的数据源获取图片需要实现不同的ImageProvi
Stella981 Stella981
4年前
JavaScript——图片懒加载
前言有一个朋友问我这个问题,刚好有时间,现在就简单的写个Demo~github|https://github.com/wangyang0210/bky/tree/picLoadLazy(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fgithub.com%2Fwan
Stella981 Stella981
4年前
Cocos Creator 资源加载流程剖析【三】——Load部分
Load流程是整个资源加载管线的最后一棒,由Loader这个pipe负责(loader.js)。通过Download流程拿到内容之后,需要对内容做一些“加载”处理。使得这些内容可以在游戏中使用。这里并不是所有的资源都需要进行一个加载处理,目前只有图片、Json、Plist、Uuid(Prefab、场景)等资源才会执行加载的流程,其他的资源在Downloa
Wesley13 Wesley13
4年前
mysql查询每个学生的各科成绩,以及总分和平均分
今天看一个mysql教程,看到一个例子,感觉里面的解决方案不是很合理。问题如下:有学生表:!在这里插入图片描述(https://oscimg.oschina.net/oscnet/07b001b0c6cb7e0038a9299e768fc00a0d3.png)成绩表:!在这里插入图片描述(https://oscimg.o
程序员小五 程序员小五
1年前
融云IM干货丨有没有插件能帮我优化uni-app的页面加载速度?
根据您的需求,以下是一些可以帮助优化uniapp页面加载速度的插件和方法:1.图片懒加载插件:使用图片懒加载可以显著减少首屏的加载时间。可以在页面滚动时才加载图片,减少初次加载的压力。2.代码拆分和懒加载:根据页面和功能的使用情况,将代码拆分为多个模块,并
布局王 布局王
7个月前
鸿蒙Next仓颉语言开发实战教程:懒加载
今天要分享的是仓颉开发语言中的懒加载。先和初学者朋友们解释一下什么是懒加载。懒加载在代码中叫做LazyForEach,看到名字你一定能猜到它和ForEach的功能类似。只不过和ForEach的一次性加载所有数据不同,懒加载会根据屏幕可使区域按需加载数据,并
云英
云英
Lv1
春蚕到死丝方尽,蜡炬成灰泪始干。
文章
4
粉丝
0
获赞
0