Vue-lazyload 原理和使用 个人总结

Vue-lazyload 这个话题,可谓“前人之述备矣”。这里主要写写一些我认为比较重要的点,能够快速回顾这个“第三方组件”的原理和使用方法。


Vue-lazyload 是主要由程序员界网红 hilongjw 打造的一款用于图片或Vue组件懒加载的组件。

它用于性能优化并且对于懒加载的一些基本的需求都有解决方案。所以选择该领域作为开源的方向,可谓非常明智,(虽说现在的issue数量还是挺多的),另可以作为开源项目的一个范本。

也就是:

  • 用于图片或Vue组件懒加载优化
  • 适用于没有做分页的长列表、适用于超过两三屏的内容
  • 懒加载的一些基本的需求都有解决方案

Vue-lazyload 在使用方面

组件状态:

  • (pending --> success 略)
  • pending --> loading
  • pending --> error
  • (兼容原生html,用到data-src,data-error,data-loading)
  • 相关的api:可以设置遇error重新请求的次数。loading的图片,error的图片。对应的回调能获取该img元素。
  • 样式钩子:内容没加载好之前,是需要显示loading的:loading的时候,会给img元素加上lazy="loading"的属性,就用这个属性钩子来作为css的钩子就行了

-------------------------------- 【我是分割线】 ----------------------------------

组件类型:

  • lazyImage vs lazyComponent 最终转化为这2种自定义组件
    • 主要是懒加载图片,偶尔懒加载组件
    • lazyComponent该组件由库方提供,你只需要传入default slot(里面会调用this.$slots.default)就行了,这样可以随便传组件进去
  • v-lazy vs v-lazy-container(v-lazy.container) + vue-lazy:background-image
    • v-lazy-container:更精确指定被监听滚动的容器,若未定义则为最近一个overflow值为auto或scroll的父元素,这个规则很实用

这样总结,是不是比网上的很多文章的脉络清晰多了?一下就能定位到自己想要的实现效果,根据思路一下就能理解它的很多api。

Vue-lazyload 好用的地方:

1、filter:比如我七牛url想要后面追加参数,可以用这个。在某种程度上和vue filter比较接近。文档原文:「filter: img未加载之前,解析到 src 的时候注册的回调函数.可以在加载图片之前,对src进行修改.注册在filter下的所有的函数都会执行。」

2、监听事件,可以监听的事件有很多种类型['scroll', 'wheel', ..., 'animationend', 'touchmove']等等,主要是监听页面的。然后按对应的模式(mode)去检查是否满足触发加载的条件。在监听方面,比较重要且有特色的一个属性是preLoad:「preLoad:类型Number,默认1.3. 表示lazyload的元素距离页面底部距离的百分比.计算值为(preload - 1).」

Vue-lazyload 注意的地方(坑):

  • 首先有很多老 issue 没有解决
  • 缺点是error之后,没有办法让用户点击一下手动启动重新加载一次??????
  • 如果组件是在布局的最后才比较适合用“vue-lazyload组件模式”,不然切换生硬、重排比较多
  • 图片相对路径怎么用:
    • 【解决办法之一】你可以将本地图片放在web-dev-server 管理的静态目录里,就可以访问了,比如 vue-cli 模板里的 dist/ (也就是所谓的publicPath)。这样的缺点是本地调试的时候可能会引用路径错误。
    • 还有 container图片路径的使用规则又不一样

Vue-lazyload 的实现原理

监听sroll等等事件,可以选择 2 种模式(mode)的其一:

一个是先保存引用作为订阅,之后再批量触发查询;另一个是观察者模式

  • event模式
    • 目标容器添加监听scroll等等事件
    • 遍历listenerQueue,每个linster的checkInView方法判断其可见性
    • 一个很典型的毛病就是频繁查询可能触发强制重排或者强制重绘
  • observer模式: observer模式主要是想提高性能
    • 初始的重置工作:该"模式"下的函数给目标容器解除监听目标对象scroll等等事件绑定
    • 只针对和该api的“根元素”(默认就是视口viewport了)和目标对象做dom处理就够了
      • 原理:Intersection Observer api (跟raq在event loop体系中触发的时机差不多)
        • (通过observerOptions提供的数据来判断是否已在preload位置,一般情况下不会设置root的指向,那么其默认值就是视口)
文章目录
  1. Vue-lazyload 在使用方面
    1. Vue-lazyload 好用的地方:
    2. Vue-lazyload 注意的地方(坑):
  2. Vue-lazyload 的实现原理