prefetch新能优化及quicklink应用
prefetch 与 preload
webpack优化之preload和prefetch里面介绍了preload和prefetch的区别。
prefetch这段资源将会在未来某个导航或者功能要用到,但是本资源的下载顺序权重比较低。也就是说prefetch通常用于加速下一次导航。
preload通常用于本页面要用到的关键资源,包括关键js、字体、css文件。preload将会把资源得下载顺序权重提高,使得关键数据提前下载好,优化页面打开速度。
preload只是为了处理下载资源优先级,往往我们可以通过标签的先后顺序来解决,例如css前置js后置等等。
<link rel="prefetch">是一种 resource hint,用来告诉浏览器在页面加载完成后,利用空闲时间提前获取用户未来可能会访问的内容
举个栗子
prefetch则会提高下一个页面加载效率,下面是个简单的例子。prefetch一个用户可能点到的链接h5.html。
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="prefetch" href="./h5.html">
</head>
<body>
<div>Hello Index page</div>
<a href="./h5.html">go to H5 Page</a>
</body>
</html>
这时,我们打开Chrome的network devtool。页面还是停留在当前页面,然而会出现一个关于h5.html的301网络请求,然后重新请求了h5.html这个页面。
prefetch的网络情况
如果你用vue脚手架做SPA,脚手架会自动完成prefetch操作。默认情况下,一个 Vue CLI 应用会为所有作为 async chunk 生成的 JavaScript 文件 (通过动态 import() 按需 code splitting 的产物) 自动生成 prefetch 提示。,当然prefetch也会消耗带宽,在移动端请谨慎使用。
quicklink
quicklink是个非常轻量级的库。它的原码也非常简单和清晰。
- 使用 Intersection Observer来检查页面的链接
- 使用 requestIdleCallback来等待页面空闲
- 使用
navigator.connection.effectiveType检查是否在弱网情况 - 使用
using navigator.connection.saveData检查是否开启数据缓存功能 - 可以采用prefetch或者fetch()两种方案,工具的选项由优先级参数
priority决定
其中,quicklink对于requestIdleCallback做了polyfill处理,让较低版本的浏览器也可以使用该控件。
const requestIdleCallback = requestIdleCallback ||
function (cb) {
const start = Date.now();
return setTimeout(function () {
cb({
didTimeout: false,
timeRemaining: function () {
return Math.max(0, 50 - (Date.now() - start));
},
});
}, 1);
};
但是这里没有对intersection observer做兼容处理。它的作用就是将可视区域里面的 <a></a>标签给读取出来提前预加载。
由于在实际项目当中可能不会有那么多a标签,quicklink也提供方法将链接url作为参数传递到quicklink的构造函数。
// If URLs are given, prefetch them.
if (options.urls) {
options.urls.forEach(prefetcher);
} else {
// If not, find all links and use IntersectionObserver.
Array.from((options.el || document).querySelectorAll('a'), link => {
observer.observe(link);
// If the anchor matches a permitted origin
// ~> A `[]` or `true` means everything is allowed
if (!allowed.length || allowed.includes(link.hostname)) {
// If there are any filters, the link must not match any of them
isIgnored(link, ignores) || toPrefetch.add(link.href);
}
});
}
这一系列的操作都非常适合多页面应用的页面跳转,大家可以在项目当中实战一下。
题外话
shopee,又称虾皮,是一家腾讯投资的跨境电商平台。这里加班少,技术氛围好。如果想和我并肩作战一起学习,可以找我内推。邮箱1542453460@qq.com,非诚勿扰。