起因
之前得知 loading="lazy"
新特性,正巧在学习如何使用 html-webpack-plugin,于是就写了个 lazyload-webpack-plugin,可以给页面里所有 <img>
,<iframe>
加上 loading="lazy"
属性,以启动原生 lazyload。
不过当初写得很简单,只会不分青红皂白加属性,甚至可能会覆盖已有的 loading="eager"
属性,引发 bug。所以这几天就想找时间升级一下:
- 不再覆盖
loading
属性 - 根据 browserslist 得到的目标浏览器器列表采取不同策略
- 支持
loading="lazy"
就延续之前的做法 - 不支持的话,用
data-src
替换src
,然后在页面里根据浏览器特性处理
- 支持
caniuse-lite
没想到这个需求还挺难满足,找了一圈竟然没有成型的教程,只好自己摸索一下,还好并不复杂。
以下代码实现了根据环境配置检查目标浏览器是否支持 loading="lazy"
的功能。我用在新版本的 lazyload-webpack-plugin
中,现在可以实现前面说的功能了。
// caniuse-lite 是官方提供的 caniuse 仓库封装,方便我们查询特性支持
const lite = require('caniuse-lite');
const browserslist = require('browserslist');
// `features` 是特性支持列表,`feature()` 可以将其转换成好用的 json 格式
const {features, feature: unpackFeature} = lite;
// 这一步,用特性名 'loading-lazy-attr' 获取支持列表
const feature = unpackFeature(features['loading-lazy-attr']);
// 直接声明 browserslist 实例,它会自动查找本地 `.browserslistrc` 或环境变量 `BROWSERSLIST` 来生成浏览器列表
const browsers = browserslist();
const {stats} = feature;
// 遍历浏览器列表,根据名称、版本验证对 `loading="lazy"` 的支持情况
const isSupport = browsers.every(browser => {
const [name, version] = browser.split(' ');
const browserData = stats[name];
const isSupport = browserData && browserData[version] === 'y';
if (!isSupport) {
console.log(`[lazyload-webpack-plugin] target browser '${browser}' DOES NOT supported \`loading="lazy"\`.`);
}
return isSupport;
});
module.exports = isSupport;
问题
现在的情况是,如果知道特性名称(如“loading-lazy-attr”),可以判断目标浏览器是否支持;但是如果不知道准确名称,就没法判断。如果我想在项目当中使用,比如检查当前代码仓库用到哪些特性不被目标浏览器兼容,并生成 polyfill 套件,就很难操作。
有待进一步学习。
自荐
欢迎有制作静态页面需求的同学使用 lazyload-webpack-plugin 给 <img>
和 <iframe>
添加 loading="lazy"
。关于使用 webpack 制作多页面站点的经验分享,可以阅读我的这篇文章《使用 Webpack 开发多页面站点》。
有任何问题、意见、建议,欢迎通过各种方式提给我。
欢迎吐槽,共同进步