H5 资源异步加载策略

1、async & defer

  • 区别
    async异步加载脚本,加载完立马执行
    defer异步加载脚本,并在DOMContentLoaded之前执行,若有多个,按照加载顺序执行脚本;async 对于应用脚本的用处不大,因为它完全不考虑依赖(哪怕是最低级的顺序执行),不过它对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的
执行过程
  • 兼容性
async
defer
  • 使用建议
    1、defer更适合做异步加载,因为其考虑了脚本依赖,并在DOMContentLoaded之前执行;
    2、async不考虑脚本依赖,加载完会立即执行,执行期间还会阻塞DOM解析,只适用不依赖任何脚本或不被任何脚本依赖的脚本;
    3、浏览器遇到 <script>且没有defer或async属性的标签时,会触发页面渲染,因而如果前面CSS资源尚未加载完毕时,浏览器会等待它加载完毕再执行脚本,因此若js文件放头部,最好放css前面或加上defer/async

2、preload & dns-prefetch

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

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

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

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

  • 有3种原因会阻止页面加载资源,包括CSP、Mixed Content、Origin block,CSP是自己手动设置的一些限制,Mixed Content是https页面不允许加载http的内容,Origin Block主要是svg的href只能是同源的资源。
//只允许加载自己域的图片,否则报错
<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源码看浏览器如何加载资源

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • 简单介绍JavaScript的发展历史 JavaScript因互联网而生,回顾它的历史要从浏览器的历史讲起。 19...
    _Dot912阅读 464评论 0 3
  • 本文总结一下浏览器在 javascript 的加载方式。关键词:异步加载(async loading),延迟加载(...
    4ea0af17fd67阅读 995评论 0 2
  • 在线阅读 http://interview.poetries.top[http://interview.poetr...
    程序员poetry阅读 113,848评论 24 450
  • 前端开发面试知识点大纲: HTML&CSS: 对Web标准的理解、浏览器内核差异、兼容性、hack、CSS基本功:...
    秀才JaneBook阅读 2,251评论 0 25
  • 常见试题 行内元素:会在水平方向排列,不能包含块级元素,设置width无效,height无效(可以设置line-h...
    他大舅啊阅读 2,314评论 1 5