线上工具

加速网页加载速度开源程序:Quicklink,提升网站速度与流畅度

Quicklink 加速网页加载速度开源程序,提升网站速度与流畅度

quicklink 是一个通过预加载资源来提升后续方案速度的轻量级工具库。旨在提升浏览过程中,用户访问后续页面时的加载速度。

当我们提到性能优化,往往都会着眼于对当前用户访问的这个页面,如何通过压缩资源大小、删减不必要资源、加快页面解析渲染等方式提升用户的访问速度;而 quicklink 用了另一种思路:我预先帮你加载(获取)你接下来最可能要用的资源,这样之后的真正使用到该资源(链接)时就会感觉非常顺畅。

照着这个思路,我们需要解决的问题就是如何预先帮用户加载资源呢?这里其实涉及到两个问题:

  • 如何去预加载一个指定资源?(预加载的方式)

  • 如何确定某个资源是否要加载?(预加载的策略)

下面就结合 quicklink 源码来看看如何解决这两个问题。

注:下文提到的“预加载”/“预获取”均指 prefetch

2. quicklink 实现原理

2.1. 如何去预加载一个指定资源?

首先要解决的是,通过什么方式来实现资源的预加载。即预加载的方式。

我们这里的预加载对应的英文是 prefetch。提到 prefetch 自然会想到使用浏览器的 Resource Hints,通过提示浏览器做一些“预操作”(例如 DNS 解析、资源下载等)来加快后续的访问。

如果对 prefetch 与 Resource Hints 不熟悉,可以看看这篇《使用Resource Hint提升页面加载性能与体验》

只需要下面这样一行代码就可以实现浏览器的资源预加载。是不是非常美妙?

<link rel="prefetch" href="/my.little.script.js" as="script">

因此,要预加载一个资源可以通过下面四行代码:

const link = document.createElement(`link`);
link.rel = `prefetch`;
link.href = url;document.head.appendChild(link);

然而,我们不得不面对兼容性的问题,在低版本 IE 与移动端是重灾区。

美梦破灭。既然如此,我们就需要一个类似 prefetch shim 的方式:在不支持 Resource Hints 的浏览器中,使用其他方式来预加载资源。对此,我们可以利用浏览器自身的缓存策略,“实实在在”预先请求这个资源,这也形成了一种资源的“预获取”。而这最方便的就是通过 XHR:

const req = new XMLHttpRequest();
req.open(`GET`, url, req.withCredentials=true);
req.send();

这样 shim 也完成了。最后,如何检测浏览器是否支持 prefetch 呢?

我们可以通过 link 元素上 relList 属性的 support 方法来检查对 prefetch 的支持情况:

const link = document.createElement('link');
link.relList || {}).supports && link.relList.supports('prefetch');

结合这三个段代码,就形成了一个简易的 prefetcher:判断是否支持 Resource Hints 中的 prefetch,支持则使用它,否则回退使用 XHR 加载。

值得一提的是,使用 Resource Hints 与使用 XHR 来预加载资源还是有一些重要差异的。草案中也提到了一些(主要是与性能以及与浏览器其他行为之间的冲突)。其中还有一点就是,Resource Hints 中的 prefetch 是否执行,完全是由浏览器决定的,草案里有句话非常明显 —— the user agent SHOULD fetch。因此,所有 prefetch 的资源并不一定会真正被 prefetch。相较之下,XHR 的方式“成功率”则更高。这点在 Netflix 实施的性能优化案例中也提到了。

题外话:quicklink 中使用 fetch API 实现高优先级资源的加载。这是因为浏览器中会为所有的请求都设置一个优先级,高优请求会被优先执行;目前,fetch 在 Chrome 中属于高优先级,在 Safari 中属于中等优先级。


相关主题

评论

回复