Skip to content

Latest commit

 

History

History
142 lines (108 loc) · 6.34 KB

3.3.3 前端性能优化之 预加载 prefetch,Preload.md

File metadata and controls

142 lines (108 loc) · 6.34 KB

前端性能优化之 预加载 prefetch,Preload

dns-prefetch, subresource, prefetch, preconnect, 和 prerender.

1.dns-prefetch

DNS prefetching通过指定具体的URL来告知客户端未来会用到相关的资源,这样浏览器可以尽早的解析DNS。
比如我们需要一个在 example.com 的图片或者视频文件。在就可以这么写:

<link rel="dns-prefetch" href="//test.com">

front-end-performance-for-web-designers-and-front-end-developers 中建议:

简单的一行就能让支持的浏览器提前解析DNS。也就是说在浏览器请求资源时,DNS查询就已经准备好了。

2.subresource

subresource可以用来指定资源是最高优先级的。
Chromium的文档这么解释:
和 "Link rel=prefetch"的语义不同,
"Link rel=subresource"是一种新的连接关系。
rel=prefetch 指定了下载后续页面用到资源的低优先级,
而 rel=subresource 则是指定当前页面资源的提前加载。
所以,如果资源是在当前页面需要,或者马上就会用到,则推荐用 subresource,否则还是用 prefetch。

比如,在 Chrome 和 Opera 中我们可以加上下面的代码:

<link rel="subresource" href="base.css">

3.prefetch

当能确定网页在未来一定会使用到某个资源时,开发者可以让浏览器提前请求并且缓存好以供后续使用。
prefetch支持预拉取图片、脚本或者任何可以被浏览器缓存的资源。

<link rel="prefetch" href="image.png">

不同于DNS prefetch,上面的写法可是会去请求、下载资源并且缓存起来。当然也是有一些发生条件的。
比如,客户端可能会在弱网络下不去请求较大的字体文件,Firefox则只会在浏览器空闲的时候prefetch资源
(注:这里是MDN上对浏览器空闲的定义和一些FAQ)。

Bram Stein在他的文章中指出
prefetch很适用于优化 webfonts 的性能。
以前,字体文件必须等 DOM 和 CSSOM 创建好后才能下载,
可如果 prefetch 了字体,这个瓶颈就能轻松解决了。

注意:prefetch并没有同域的限制

4.preconnect

和DNS prefetch类似,preconnect 不光会解析 DNS,还会建立TCP握手连接和TLS协议(如果需要)。用法如下:

<link rel="preconnect" href="http://css-tricks.com">

eliminating-roundtrips-with-preconnect篇文章详细说明了这种技术:

现代浏览器竭尽所能的尝试预测网站可能需要哪些链接。
通过提前连接,浏览器可以提前建立必要的通信,消除了实际请求中DNS、TCP和TLS的耗时。
不过,即使是只能的现代浏览器,也没办法为每个网站可靠的预测所有连接。
幸运的是开发者可以告诉浏览器哪些通信需要在实际请求发起前就提前建立连接。

5.prerender

prerender是一个重量级的选项,它可以让浏览器提前加载指定页面的所有资源。

Steve Souders的文章详细解释了这个技术: prerender就像是在后台打开了一个隐藏的tab,会下载所有的资源、创建DOM、渲染页面、执行JS等等。
如果用户进入指定的链接,隐藏的这个页面就会进入马上进入用户的视线。
Google Search多年前就利用了这个特性实现了Instant Pages功能。

<link rel="prerender" href="/nextpage.html"/>

但是要注意,一定要在十分确定用户回点某个链接时才用这个特性,否则客户端就会无端的下载很多资源和渲染这个页面。

正如任何提前的动作一样,预判总是有一定风险出错。
如果提前的动作是昂贵的(比如高CPU、耗电、占用带宽),就要谨慎使用了。
虽然不容易预判用户会点进哪个页面,但还是存在一些典型的场景:

  • 如果用户搜索到了一个明显正确的结果时,那么这个页面就很有可能被点入
  • 如果用户在登录页面,那么登录成功后的页面就很可能接下来会被加载了
  • 如果用户在阅读一个多页面的文章或者有页码的内容时,下一页就很可能会马上被点击了

利用 Page Visibility API 可以用来防止页面在还没真正展示给用户时就触发了JS的执行。

  • Page Visibility API demo:
var videoElement = document.getElementById("videoElement");

// Autoplay the video if application is visible
if (document.visibilityState == "visible") {
  videoElement.play();
}

// Handle page visibility change events
function handleVisibilityChange() {
  if (document.visibilityState == "hidden") {
    videoElement.pause();
  } else {
    videoElement.play();
  }
}

document.addEventListener('visibilitychange', handleVisibilityChange, false);

6.Preload

允许始终预加载某些资源,不像 prefetch 有可能被浏览器忽略,浏览器必须请求 preload 标记的资源。

<link rel="preload" href="image.png">

<link rel="preload" href="late_discovered_thing.js" as="script">

as 属性告诉浏览器 它将要下载什么 . as 值包含以下:

"script",
"style",
"image",
"media",
and "document".

大部分预加载技术移动端都不支持,PC支持有限;
缺点:可能会造成资源的浪费;

参考