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

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


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

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

也就是:

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

Vue-lazyload 在使用方面

组件状态:

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

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

组件类型:

  • lazyImage vs lazyComponent 最终分别转化为这2种vue自定义组件。主要是用于懒加载图片;偶尔用于懒加载组件
  • 【1】懒加载图片:
    • v-lazy和 它的变体vue-lazy:background-image
    • v-lazy-container(v-lazy.container) 指定目标图片的外层容器
  • 【2】懒加载组件:lazyComponent该组件由库方提供,你只需要传入default slot(里面会调用this.$slots.default)就行了,这样可以随便传组件进去

这样总结,是不是比网上的很多文章的脉络清晰多了?一下就能定位到自己想要的实现效果,根据思路一下就能理解它的很多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处理就够了
      • 通过observerOptions提供的数据来判断是否已在preload位置
    • 原理:Intersection Observer api
      • (跟raf在event loop体系中触发的时机差不多)
      • (一般情况下不会设置root的指向,那么其默认值就是视口)
文章目录
  1. Vue-lazyload 在使用方面
    1. Vue-lazyload 好用的地方:
    2. Vue-lazyload 注意的地方(坑):
  2. Vue-lazyload 的实现原理