avatar

fengkx's Blog

fengkx

Student & Coder

Guangzhou, China
Build with Hexo and Next.js

Hexo-native-lazy-load 插件

Chrome 原生支持图片 lazy load

前段时间刷推的时候看到了Chrome 开始原生支持 lazy load 的新闻。简单的说就是 Chrome76 开始支持一个 loading 属性。有以下三种取值。

auto: Default lazy-loading behavior of the browser, which is the same as not including the attribute.
lazy: Defer loading of the resource until it reaches a calculated distance from the viewport.
eager: Load the resource immediately, regardless of where it's located on the page.

想到可以把它放在博客里面作为一种额外的优化。(本博客已经上了大杀器 service worker 其实大部分时候图片都是从 service worker 下载的)

花了点时间写了一个 Hexo 插件hexo-native-lazy-load

Hexo native lazy load

这个插件要做的事情就是在 img 标签插入loading=lazy的属性。它使用了 Hexo 的filter API

第一次写 Hexo 的插件。Hexo 的文档给我的感觉很不清楚(看不懂)。很多时候数据结构都要试。有个点一开始不知道。

Hexo 插件的入口文件有全局的hexo对象,对象下有hexo.log等价于hexo-log这个 package 不需要额外引入。

经过了一段时间的迭代了,下面说说具体功能

optional fallback

hexo.config.lazy_load.fallback !== false条件成立时,会给额外加上一个使用lazysizes的 fallback lazy load。像这样

if (!("loading" in HTMLImageElement.prototype)) {
  const srp = document.createElement("script");
  srp.src = "https://cdn.jsdelivr.net/npm/lazysizes@5.1.1/lazysizes.min.js";
  document.body.append(srp);
  const imgs = document.querySelectorAll("img");
  imgs.forEach((el) => {
    el.setAttribute("data-src", el.getAttribute("src"));
    el.removeAttribute("src");
    el.classList.add("lazyload");
  });
}

结合对象检测如果不支持 loading 属性则插入 fallback。

添加本地图片的宽高属性

lazy load 需要尽量减少页面的 reflow。可以通过设置固定的宽高实现。我自己的博客的图片都是放在post_asset_folder下面。那么就可以通过本地读取文件的宽高直接添加到 img 元素的属性里。

插件提供了width_height设置项。当hexo.config.post_asset_folder === true && hexo.config.lazy_load.width_height !== false条件成立时将会就会为本地的图片添加宽高。

最终的效果

支持 loading 属性的浏览器。

loading-lazy

不支持 loading 属性的浏览器

lazysizes

传送门

NPM

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处。

本文链接: https://www.fengkx.top/post/hexo-native-lazy-load/

发布于: 2019-12-01