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? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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: