We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
思考一个业务场景:
一个运营活动页面,某些图片相对较大(可能有背景图),20-100k不等,如何让这些图片尽可能快的加载,来保证页面的体验呢?
很久前看过一篇从Chrome源码看浏览器如何加载资源,写的非常好,强烈建议读完这篇文章再继续阅读。
我知道,其实你没好好思考上面的文章😬,那么问题就来了
对浏览器加载资源有很多不确定性:
说了这么多,写个小demo测试一下:
<!DOCTYPE html> <html lang="en"> <head> <link href="http://cdn.bootcss.com/animate.css/3.5.2/animate.css" rel="stylesheet"> <link href="http://cdn.bootcss.com/animate.css/3.5.2/animate.min.css" rel="stylesheet"> <link href="http://cdn.bootcss.com/animate.css/3.5.1/animate.css" rel="stylesheet"> <link href="http://cdn.bootcss.com/animate.css/3.5.1/animate.min.css" rel="stylesheet"> <link href="http://cdn.bootcss.com/animate.css/3.5.0/animate.css" rel="stylesheet"> <script src="http://cdn.bootcss.com/animejs/2.2.0/anime.js"></script> <script src="http://cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script> <script src="http://cdn.bootcss.com/animejs/2.1.0/anime.js"></script> <script src="http://cdn.bootcss.com/animejs/2.1.0/anime.min.js"></script> <link href="http://cdn.bootcss.com/animate.css/3.5.0/animate.min.css" rel="stylesheet"> <link href="http://cdn.bootcss.com/animate.css/3.4.0/animate.css" rel="stylesheet"> <link href="http://cdn.bootcss.com/animate.css/3.4.0/animate.min.css" rel="stylesheet"> <link href="http://cdn.bootcss.com/animate.css/3.3.0/animate.css" rel="stylesheet"> <script> var cssSelector = anime({ targets: '#cssSelector .el', translateX: 250 }); </script> </head> <body> <p id="title">z</p> <script> document.getElementById('title').innerHTML = 'xxx'; </script> <img src="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_20,f_webp" alt=""> <img src="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_10,f_webp" alt=""> <img src="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_24,f_webp" alt=""> <img src="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_26,f_webp" alt=""> <img src="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_27,f_webp" alt=""> <img src="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_28,f_webp" alt=""> <img src="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_30,f_webp" alt=""> <img src="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_31,f_webp" alt=""> <img src="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_32,f_webp" alt=""> <img src="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_33,f_webp" alt=""> <img src="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_90" alt=""> <link rel="preload" as="image" href="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_90"> <link rel="preload" as="image" href="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_99"> </body> </html>
这个html页面中,有css、js、image资源,有些资源使用了preload进行加载。
preload
结果:
很有意思的一点: 使用了preload的image.jpg@q_90这张图片,在html解析后的第一时间被加载了,但是挨着它的另一张preload的q_99图片,是在所有的css、js加载后才开始加载的。
image.jpg@q_90
q_99
这是为什么呢?
上文其实已经写出了答案,复习一下:
在优先级在Medium以下的为delayable,即可推迟的,而大于等于Medium的为不可delayable的。从刚刚我们总结的表可以看出:css/js是不可推迟的,而图片、preload的js为可推迟加载。
还有一种是layout-blocking的请求:
这是当还没有渲染body标签,并且优先级在Medium之上的如CSS的请求。
Chrome 45 以前:
chrome 46 后:
preload技术比较新,通常只有高版本chrome才有支持,好在link标签不支持preload就回忽略。
link
prefetch的优先级相当的低,通常是用来抓取下一屏的资源,这对SPA应用有相当的好处,但对本页面的资源顺序很难影响。
dns-prefetch这个link标签,浏览器后台会开多线程去解析dns,可以用来对域名预读取,也能一定程度上提高页面性能。
dns-prefetch
<link rel="preload" as="image" href="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_99"> <link rel="prefetch" as="image" href="http://imgdoc.bce.baidu.com/bce-documentation/BOS/image.jpg@q_99">
当你对同一资源,同时使用两种预加载方式时,结果可能并不是你想要的那样:
字体资源在浏览器加载顺序表现的有些耐人寻味,来看下面的代码:
<style type="text/css" media="screen, print"> @font-face { font-family: "Bitstream Vera Serif Bold"; src: url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/fonts/fontawesome-webfont.woff2"); } body { font-family: "Bitstream Vera Serif Bold", serif } </style> <link rel="preload" as="font" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/fonts/fontawesome-webfont.woff2">
在head标签中,写入了一段css,使用font-face加载一个字体文件,同时下面一个link标签preload了相同的字体资源。
head
同一资源被加载了两次,发起了两个请求,而且前后顺序不一。
从上图可以看出,preload的字体资源竟然率先加载了,写在内联css中的字体资源更靠后加载,从资源加载的优先级属性可以看到。
第一个问题,需要给link标签设置一个crossorigin属性,就可以解决这个加载两次的问题。
crossorigin
第二个问题,这也是为什么很多公司对字体文件使用了preload加载后,可以明显提高用户感知体验的原因。
字体延迟加载带有一个可能会延迟文本渲染的重要隐藏影响:浏览器必须构建渲染树(它依赖 DOM 和 CSSOM 树),然后才能知道需要使用哪些字体资源来渲染文本。因此,字体请求的处理将远远滞后于其他关键资源请求的处理,并且在获取资源之前,可能会阻止浏览器渲染文本。
网页内容的首次绘制(可在渲染树构建后不久完成)与字体资源请求之间的“竞赛”产生了“空白文本问题”,出现该问题时,浏览器会在渲染网页布局时遗漏所有文本。
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/webfont-optimization?hl=zh-cn
Preload: What Is It Good For?
@font-face mdn
从Chrome源码看浏览器如何加载资源
语言 编辑 高级 通过rel="preload"进行内容预加载
The text was updated successfully, but these errors were encountered:
No branches or pull requests
思考一个业务场景:
一个运营活动页面,某些图片相对较大(可能有背景图),20-100k不等,如何让这些图片尽可能快的加载,来保证页面的体验呢?
回想
很久前看过一篇从Chrome源码看浏览器如何加载资源,写的非常好,强烈建议读完这篇文章再继续阅读。
DL;DR
我知道,其实你没好好思考上面的文章😬,那么问题就来了
对浏览器加载资源有很多不确定性:
第一个问题
第二个问题
第三个问题
测试
说了这么多,写个小demo测试一下:
这个html页面中,有css、js、image资源,有些资源使用了
preload
进行加载。结果:

很有意思的一点:
使用了
preload
的image.jpg@q_90
这张图片,在html解析后的第一时间被加载了,但是挨着它的另一张preload
的q_99
图片,是在所有的css、js加载后才开始加载的。这是为什么呢?
上文其实已经写出了答案,复习一下:
区分 delayable / non-delayable 请求
在优先级在Medium以下的为delayable,即可推迟的,而大于等于Medium的为不可delayable的。从刚刚我们总结的表可以看出:css/js是不可推迟的,而图片、preload的js为可推迟加载。
还有一种是layout-blocking的请求:
这是当还没有渲染body标签,并且优先级在Medium之上的如CSS的请求。
深入
Chrome Resource Priorities and Scheduling
Chrome 45 以前:
chrome 46 后:

兼容性
preload技术比较新,通常只有高版本chrome才有支持,好在
link
标签不支持preload
就回忽略。preload vs prefetch
prefetch的优先级相当的低,通常是用来抓取下一屏的资源,这对SPA应用有相当的好处,但对本页面的资源顺序很难影响。
dns-prefetch
这个link标签,浏览器后台会开多线程去解析dns,可以用来对域名预读取,也能一定程度上提高页面性能。避免同一资源混用preload prefetch
当你对同一资源,同时使用两种预加载方式时,结果可能并不是你想要的那样:
字体资源使用preload
字体资源在浏览器加载顺序表现的有些耐人寻味,来看下面的代码:
在
head
标签中,写入了一段css,使用font-face加载一个字体文件,同时下面一个link
标签preload了相同的字体资源。结果:
第一个问题
同一资源被加载了两次,发起了两个请求,而且前后顺序不一。
第二个问题
从上图可以看出,preload的字体资源竟然率先加载了,写在内联css中的字体资源更靠后加载,从资源加载的优先级属性可以看到。
探究
第一个问题,需要给link标签设置一个
crossorigin
属性,就可以解决这个加载两次的问题。第二个问题,这也是为什么很多公司对字体文件使用了preload加载后,可以明显提高用户感知体验的原因。
网页字体和关键渲染路径
字体延迟加载带有一个可能会延迟文本渲染的重要隐藏影响:浏览器必须构建渲染树(它依赖 DOM 和 CSSOM 树),然后才能知道需要使用哪些字体资源来渲染文本。因此,字体请求的处理将远远滞后于其他关键资源请求的处理,并且在获取资源之前,可能会阻止浏览器渲染文本。
网页内容的首次绘制(可在渲染树构建后不久完成)与字体资源请求之间的“竞赛”产生了“空白文本问题”,出现该问题时,浏览器会在渲染网页布局时遗漏所有文本。
参考
https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/webfont-optimization?hl=zh-cn
Preload: What Is It Good For?
@font-face mdn
从Chrome源码看浏览器如何加载资源
语言 编辑 高级
通过rel="preload"进行内容预加载
The text was updated successfully, but these errors were encountered: