H5 资源异步加载策略

2017-11-01  本文已影响339人  风之化身呀

1、async & defer

执行过程 async defer

2、preload & dns-prefetch

(目前移动端支持度并不好,仅作参考)
DNS prefetching通过指定具体的URL来告知客户端未来会用到相关的资源,这样浏览器可以尽早的解析DNS。比如我们需要一个在example.com的图片或者视频文件。在<head>就可以这么写:

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

项目中有用到第三方的代码时这么做尤其有益(其他的使用场景,比如当静态资源和HTML不在一个域上,而在CDN上;又比如在重定向前可以加上DNS prefetch)

3、资源阻塞及加载优先级

//只允许加载自己域的图片,否则报错
<meta http-equiv="Content-Security-Policy" content="img-src 'self';">
//将网页的http请求强制升级为https
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
//在https的网站请求http的内容就是Mixed Content,例如加载一个http的JS脚本,这种请求通常会被浏览器堵塞掉,有几种资源属于可选阻塞:audio,vedio,favicon,image即浏览器默认可以在https下加载http开头的这几种资源,但是当设置了以下meta时,所有http资源都无法在https下得到加载(image的srcset属性不算可选阻塞,src属性算)。而对于主动混合内容,如果用户设置允许加载也是可以加载的
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
//Origin Block主要是svg使用use获取svg资源的时候必须不能跨域
<!DOCType html>
<html>
<head>
    <meta charset="utf-8">
    <link rel="icon" href="4.png">
    <img src="0.png">
    <img src="1.png">
    <link rel="stylesheet" href="1.css">
    <link rel="stylesheet" href="2.css">
    <link rel="stylesheet" href="3.css">
    <link rel="stylesheet" href="4.css">
    <link rel="stylesheet" href="5.css">
    <link rel="stylesheet" href="6.css">
    <link rel="stylesheet" href="7.css">
</head>
<body>
    <p>hello</p>
    <img src="2.png">
    <img src="3.png">
    <img src="4.png">
    <img src="5.png">
    <img src="6.png">
    <img src="7.png">
    <img src="8.png">
    <img src="9.png">

    <script src="1.js"></script>
    <script src="2.js"></script>
    <script src="3.js"></script>

    <img src="3.png">
<script>
!function(){
    let xhr = new XMLHttpRequest();
    xhr.open("GET", "https://baidu.com");
    xhr.send();
    document.write("hi");
}();
</script>
<link rel="stylesheet" href="9.css">
</body>
</html>

这个html资源加载timeline如下:


timeline

解释1:
(1)每个域每次最多同时加载6个资源(http/1.1)

(2)CSS具有最高的优先级,最先加载,即使是放在最后面9.css也是比前面资源先开始加载

(3)JS比图片优先加载,即使出现得比图片晚

(4)只有等CSS都加载完了,才能加载其它的资源,即使这个时候没有达到6个的限制

(5)head里面的非高优化级的资源最多能先加载一张(0.png)

(6)xhr的资源虽然具有高优先级,但是由于它是排在3.js后面的,JS的执行是同步的,所以它排得比较靠后,如果把它排在1.js前面,那么它也会比图片先加载。
解释2:
(1)高优先级的资源(>=Medium)、同步请求和非http(s)的请求能够立刻加载

(2)只要有一个layout blocking的资源在加载,最多只能加载一个delayable的资源,这个就解释了为什么0.png能够先加载

(3)只有当layout blocking和high priority的资源加载完了,才能开始加载delayable的资源,这个就解释了为什么要等CSS加载完了才能加载其它的js/图片。

(4)同时加载的delayable资源同一个域只能有6个,同一个client即同一个页面最多只能有10个,否则要进行排队。
解释3:
白色条是指queue的时间段,而灰色的是已经in flight了但受到同域只能最多只能建立6个TCP连接等的影响而进入的stalled状态,绿色是TTFB(Time to First Byte)从开始建立TCP连接到收到第一个字节的时间,蓝色是下载的时间。

我们已经解释了大部分加载的特点的原因,对着上面那张图可以再重述一次:
(1)由于1.css到9.css这几个CSS文件是high priority或者是none delayable的,所以马上in flight,但是还受到了同一个域最多只能有6个的限制,所以6/7/9.css这三个进入stalled的状态

(2)1.css到5.css是layout-blocking的,所以最多只能再加载一个delayable的0.png,在它相邻的1.png就得排队了

(3)等到high priority和layout-blocking的资源7.css/9.css/1.js加载完了,就开始加载delayable的资源,主要是preload的js和图片

4、参考

【1】从Chrome源码看浏览器如何加载资源

上一篇下一篇

猜你喜欢

热点阅读