HTML link标签中preload,prefetch,dns-prefetch,preconnect,prerender

Posted chaoguo1234

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTML link标签中preload,prefetch,dns-prefetch,preconnect,prerender相关的知识,希望对你有一定的参考价值。

Preload

在我们的浏览器加载资源的时候,对于每一个资源都有其自身的默认优先级,倘若我们能修改每一个资源的默认优先级,那我们几乎可以按照我们的预期加载想要加载的资源。

以谷歌浏览器为例,我们打开控制台,并切换到Network选项,点击刷新页面,在网络下面的title一行点击鼠标右键,勾选Priority即可看到加载资源的优先级,我们可以看到样式的级别比脚本的优先级高,毕竟页面的一加载进来肯定是样式首先需要渲染的,不然整个页面便会四分五裂,用户体验不好。

 

preload一旦启用后便会告知浏览器应该尽快的加载某个资源,如果提取的资源3s内未在当前使用,在谷歌开发工具将会触发警告消息:

 

 

preload语法如下:

1 <link rel="preload" as="script" href="foo.js">
2 <link rel="preload" as="style" href="bar.css">

除了以上指定的资源外,还可以加载audio、font、video以及document等,详情点击这里了解。

 

跨域资源处理

如需加载跨域的资源列表,则需要正确设置CORS,接着便可以在<link>元素中设置好crossorigin属性即可:

1 <link rel="preload" as="font" crossorigin="crossorigin" type="font/woff2" href="foo.woff2">

这里有一个特例便是无论是否跨域,字体的获取都需要设置crossorigin属性,这是由于历史原因造成,有兴趣了解可移步这里了解,另外我们还可以使用media响应式的加载图片,比如:

1 <link rel="preload" href="bg@2x.png" as="image" media="(max-width: 325px)">
2   <link rel="preload" href="bg@3x.png" as="image" media="(min-width: 400px)">

另一个重要的地方便是如果预加载一个脚本,它并不是执行:

 1 //只拉取下载不执行
 2 var preloadLink = document.createElement("link");
 3 preloadLink.href = "foo.js";
 4 preloadLink.rel = "preload";
 5 preloadLink.as = "script";
 6 document.head.appendChild(preloadLink);
 7 
 8 //如果需要执行
 9 var preloadedScript = document.createElement("script");
10 preloadedScript.src = "foo.js";
11 document.body.appendChild(preloadedScript);

 

preload兼容性

兼容似乎IE全体阵亡,edge也得17+才能勉强支持,火狐需要手动启动支持,移动端支持程度还是挺好的。

 

 

Prefetch

简而言之预提取就是在我们页面加载完成后,在带宽可用的情况下,加载用户下一步期待的页面资源,比如企业认证,一般都是分好几个页面进行认证的,在用户从第一个页面进行认证的时候,在页面加载完成,用户正在填写表单数据之时,加载第二个页面的部分资源,从而使用户更快打开下一个页面,从而增加用户体验,示例:
1 <link rel="prefetch" href="demo.html">
2 <link rel="stylesheet" href="demo.css">
当浏览器解析到link标签时,读取到rel的值为prefetch,便会将这一个资源添加的队列中,当浏览器空闲时便会预提取资源,但是在demo.html页面中只是加载HTML,不会加载demo页面里面的任何其他资源,除非你在demo页面也明确使用了预提取。
Pretetch兼容性
各大浏览器支持都还挺好,IE11+以上,但是Safari貌似到现在还没支持(但是看WKWebView的源码,是支持了的)
 

DNS-Prefetch

我们都知道,当我们在浏览器的地址栏输入域名的时候,首先要进行的就是域名解析,因为我们需要加载域名对应的资源,这个过程很快,但是如果在移动端,那可是一个分秒必争的地方,当一个页面需要访问许多外部域名的资源的时候,如果我们能在用户浏览页面的时候,在浏览器空闲的时间,把可能需要访问的域名都提前做好了域名解析,那是不是大大增加了用户打开页面的响应时间,增加用户体验,为了解决这个问题,w3c便提出来一个标准,学名叫dns-prefetch。
 

 

使用方法上面中已经支持了,指定rel=”dns-prefetch”,在href中指定页面需要解析的域名即可,你可能已经注意到了上面的图中域名使用了双斜杠,这个双斜杠表示URL以主机名开头,和你使用完整URL(比如http://g.alicdn.com/)是等效的。在RFC1808中被指定。

当然并不是所有的页面需要用到的外部域名都需要做这样的域名解析,浏览器默认会解析超链接属性的href里面的域名,并且你的网站域名还不能是HTTPS,如果是HTTPS,则需要设置请求头或加入一段强制开启域名解析的meta标签。

1 //HTTP
2 <link rel="dns-prefetch" href="//a.com"> //多余
3 <a href="http://a.com">
4 //HTTPS
5 <meta http-equiv="x-dns-prefetch-control" content="on">//强制开启
6 <a href="http://a.com">

当然,并不建议对HTTPS网站开启强制解析的方式,因为这样会带来一些安全隐患,具体可参考这里

 

Preconnect

预连接,也就是启动早期连接(包括DNS查找,TCP握手和可选TLS协商),我们来看一个例子:

1 <link href=\'https://fonts.demo.com\' rel=\'preconnect\' crossorigin>
2 <link href=\'https://demo.com/css?family=黑体\' rel=\'stylesheet\'>

一个网络字体正常加载一般都包括:

  • 页面加载样式,解析样式用到的网络字体
  • 网络字体开始下载,首先开始DNS的查找
  • 然后TCP握手
  • 如果是HTTPS,还有TLS协商,最后下载字体

当然如果是跨域资源,不要忘了加上crossorigin属性。

 

Preconnect兼容性

IE15+以上部分兼容,移动端兼容良好。

 

 

Prerender

预渲染,简单来说就是浏览器会下载指定链接的资源,并下载以及渲染它,就好比我们打开了一个新的Tab标签页,静默的在后台的下载执行,当然,浏览器也不一定会下载渲染它,这取决预很多情况,比如浏览器是否空闲以及操作系统是否会放弃下载过慢的资源文件。

除非你真的能十分的肯定用户接下来一定会触发你所指定的资源地址,否则对于用户来说这是一种带宽的浪费,使用例子如下:

1 <link rel="prerender" href="https://www.apple.com/">

 

Prerender兼容性

虽然是prerender是HTML5规范的一部分,但是似乎很多厂商都还没有实现,但是IE11竟然支持。

 

 

结尾

讲了这么多,最后整理了一个表格,帮助大家快速查阅参考,每个浏览器的实施细节都有所区别,这里以Chrome浏览器表格为例:

 

 

 

以上是关于HTML link标签中preload,prefetch,dns-prefetch,preconnect,prerender的主要内容,如果未能解决你的问题,请参考以下文章

<link rel=preload> 必须有一个有效的 `as` 值

通过link的preload进行内容预加载

通过link的preload进行内容预加载

Vue-cli 正确处理<link rel="preload/prefetch">

如何将 <link rel=preload> 应用于@font-face?

页面性能优化:preload预加载静态资源