dns-prefetch/prefetch/preload/defer/async
preload不阻塞文档解析,放在内存中,当遇到script标签加载同样的js时,浏览器才回执行预先加载的js。
prefetch会在空闲时间下载js,使用时直接从磁盘获取。如果prefetch还没下载完之前,script引用相同资源。浏览器会再次发起请求,浪费资源。
defer和async是script标签的两个属性
defer相当于将script放在body后执行;
async不能确定哪个js先执行,下载完就执行;
defer也可以单独使用,如果您的脚本不会改变文档的内容,可将 defer 属性加入到 <script> 标签中,以便加快处理文档的速度。因为浏览器知道它将能够安全地读取文档的剩余部分而不用执行脚本,它将推迟对脚本的解释,直到文档已经显示给用户为止。
- 如果 async="async":脚本相对于页面的其余部分异步地执行(当页面继续进行解析时,脚本将被执行)
https://segmentfault.com/a/1190000011577248
预先解析DNS
非常简单,效果立竿见影,加快页面加载时间,多用于预解析CDN的地址的DNS
<!--在head标签中,越早越好-->
<link rel="dns-prefetch" href="//example.com">
Preload
浏览器会在遇到如下link标签时,立刻开始下载main.js(不阻塞parser),并放在内存中,但不会执行其中的JS语句。
只有当遇到script标签加载的也是main.js的时候,浏览器才会直接将预先加载的JS执行掉。
<link rel="preload" href="/main.js" as="script">
Prefetch
浏览器会在空闲的时候,下载main.js, 并缓存到disk。当有页面使用的时候,直接从disk缓存中读取。其实就是把决定是否和什么时间加载这个资源的决定权交给浏览器。
如果prefetch还没下载完之前,浏览器发现script标签也引用了同样的资源,浏览器会再次发起请求,这样会严重影响性能的,加载了两次,,所以不要在当前页面马上就要用的资源上用prefetch,要用preload。
<link href="main.js" rel="prefetch">
defer和async是script标签的两个属性,用于在不阻塞页面文档解析的前提下,控制脚本的下载和执行。
defer的执行时间是在所有元素解析完成之后,DOMContentLoaded 事件触发之前。
async的执行时间是在当前JS脚本下载完成后,所以多个async script是执行顺序是不固定的。async只能用于加载一些独立无依赖的代码,比如Google Analysis之类。
<html>
<head>
<meta charset="utf-8">
<title>Faster</title>
//提前解析CSS文件所在域名的DNS
<link rel="dns-prefetch" href="//cdn.cn/">
// 下载字体,但不影响解析。可以考虑下次放缓存中
<link rel="preload" href="//cdn.cn/webfont.woff2" as="font">
<link rel="preload" href="//cdn.cn/Page1-A.js" as="script">
<link rel="preload" href="//cdn.cn/Page1-B.js" as="script">
// 下一页可能用到的资源,prefetch
<link rel="prefetch" href="//cdn.cn/Page2.js">
<link rel="prefetch" href="//cdn.cn/Page3.js">
<link rel="prefetch" href="//cdn.cn/Page4.js">
<style type="text/css">
// 这样可以减少关键回路数和关键资源个数,但增加了关键资源大小,策略
/* 首页用到的CSS内联 */
</style>
</head>
<body>
// defer可以单独使用
<script type="text/javascript" src="//cdn.cn/Page1-A.js" defer></script>
<script type="text/javascript" src="//cdn.cn/Page1-B.js" defer></script>
</body>
</html>