网站首页 > 技术文章 正文
天文章来聊聊浏览器到底是如何对待下载资源的,比如说 JS、CSS、字体、图片等文件。
CSS、JS 文件冤家路窄
HTML 在解析的过程中遇到同步的 script 会卡住 DOM 解析这个知识点我相信读者们应该都知道。
<!DOCTYPE html> <html lang="en"> <body> <script>console.log(1)</script> <div>1</div> </body> </html>
上述代码中,HTML 遇到 <script>console.log(1)</script> 代码就会停止 DOM 解析了。当然现代浏览器不是说就这样停住啥也不干了,会有个 preload scanner 去扫描底下的文件,然后根据文件类型去制定优先级(这个下面再说)。
上面举得例子是内联代码,如果是一个 JS 文件的话,那么就得等这个 JS 文件下完以后执行代码才行。
但是一般我们文件结构不会那么单一,CSS 文件也肯定是有的。因为 JS 不仅能动 DOM 也能改 style,所以如果遇到 script 之前还有别的 CSS 文件的话,浏览器还得等 CSS 文件下完以后再去执行 JS。
所以说不只是 JS 会阻塞 DOM 解析,CSS 也会。
当然我想现在应该很少再有人直接写同步的 script 了吧。
文件同时遇到,那会同时开始下载嘛?
举个例子,在可以同时下载多个文件的情况下,浏览器在 HTML、CSS 文件中解析到了 img、font、background-image 资源,那么们会同时开始下载嘛?
答案是不会!
这里只有 img 会最先开始下载,其它两块内容都得等到 layout 以后才会开始下载。不信的话我们来看图:
这里以 font 为例
图中右下角框出来的是字体文件,上面是 CSS 文件,字体是从 CSS 文件中得知需要去加载的。
大家可以在图中发现 CSS 文件早早开始下载解析了,但是 font 文件迟迟未开始下载,直到 FP 指标即将出现的时候才开始下载动作,这个时间点是在 layout 完成以后。
图中是以掘金为例,大家可以多试试别的网站,应该能发现是符合预期的。
那么读者可能会有个疑问,按照这个逻辑意思是说能用 img 的都用 img,因为background-image 不是马上开始下载的?道理是这个道理,但是还是得分情况来说,如果图片出现的位置不是首屏,用 background-image 也没啥问题,当然给 img 用上懒加载也能解决问题。
那么到底文件的优先级是如何的?
如果大家有使用过 Performance 测试网站性能的话,可以在 Network 那栏里 hover 下载的资源,此时你能发现资源有优先级的显示。
从图中大家可以发现 CSS 和字体资源的优先级的最高的,JS 文件有高有低(这和类型有关),图片、svg 的优先级为低。
这部分的优先级是指某个时间点上的优先级,而不是适应于整个周期。对于 CSS 文件优先级最高还是挺好理解的,毕竟 JS 文件依赖于 CSS 文件,更加详细的内容大家可以参考 从Chrome源码看浏览器如何加载资源 中的「3. 资源优先级」内容。
网络协议才是最大元凶
浏览器要下载资源,TCP 协议肯定得用上,但是 TCP 协议天生就是一个慢的东西。
先得握手,然后慢开始算法,就和我们用迅雷下载东西一样,带宽很大没用,速度都是得爬升上去的。如果再加个 HTTPS 的话,还得再多个 TLS 的握手。
然后说回 HTTP1.1 协议。Chrome 只支持同个 domain 同时并发 6 个请求,所以在之前的协议中一堆请求都得 block 住等之前的下载完成。
当然现在不同了,HTTP2 的概念基本大家都知道了,没见过猪跑但吃过猪肉,对于这块的知识点聊上几句没啥问题。什么多路复用,header 合并、二进制帧啥的。
得利于 HTTP2 协议中的多路复用,我们不再被浏览器的六个并发所限制,所有同一个 domain 上的请求都能跑在复用的六个网络通道上,下载耗时瞬间减少了几个量级,但是大家有没有考虑过这个 HTTP2 到底是如何对待这些资源的?
如何分配它们的优先级?依赖?带宽或者别的?毕竟一堆资源占用同一个网络通道,那么到底该谁先下载,谁享有的带宽多点都是需要协调的。否则假如一堆图片占用了大部分带宽,其他 CSS、JS 文件下的很慢的话,就会影响整个网页的性能了。
比如说我现在需要下载 CSS、JS、图片和字体这些文件。举个例子在这些文件中我希望 CSS 文件能最先开始下载,并且能分配到的带宽多点;JS 文件呢可以等 CSS 文件下完再去下;其他文件呢优先级比 CSS 文件低点,但是也能够享受到带宽去进行下载。
这个需求我们可以通过二进制帧去实现。HTTP2 协议共存在十个二进制帧,其中你可以通过 HEADERS 帧分配新的优先级,也可以通过 PRIORITY 帧更改优先级。
对于流的优先级,我们可以通过两个方式来实现调整:
- 当我们调整流的依赖时,就可以实现让 JS 文件等待 CSS 文件下载完毕以后再开始
- 当我们调整流的 weight 时,就可以实现带宽的分配,让某些资源能更快地进行下载
如图所示(丑了点)。第一排的文件开始一起下载,weight 相加为 20,那么通过计算可得 CSS 文件享有带宽的一半,其他各占有 1 / 4,JS 文件得等 CSS 完成以后才开始。
那么该如何设置这些东西呢?当然得服务端支持啦,一般都指 CDN 服务商了。
最后
查找了很多资料,如有遗漏,还请见谅。文中如果有误,还望及时指出,感谢
猜你喜欢
- 2025-06-13 周均下载百万的TOP 12前端 Ponyfill !
- 2025-06-13 前端文件下载的N种姿势:从简单到高级
- 2024-10-03 JS 下载/导出 csv、excel、txt 、img等文件的方法总结
- 2024-10-03 技术小白的微信小程序搭建之路(六:前端设置)
- 2024-10-03 springboot:实现文件上传下载实时进度条功能【附带源码】
- 2024-10-03 字节内部前端开发手册(完整版),开放下载
- 2024-10-03 前端 ajax 请求 Excel 文件下载的几种方式
- 2024-10-03 前端常见问题和技术解决方案 前端问题是什么意思
- 2024-10-03 springboot整合前端实现断点续传、大文件秒传以及多线程上传下载
- 2024-10-03 vue前端下载word文档 vue前端文件下载
你 发表评论:
欢迎- 523℃Oracle分析函数之Lag和Lead()使用
- 520℃几个Oracle空值处理函数 oracle处理null值的函数
- 517℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 504℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 501℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 493℃【数据统计分析】详解Oracle分组函数之CUBE
- 472℃Oracle有哪些常见的函数? oracle中常用的函数
- 471℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端react (48)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端富文本编辑器 (47)
- 前端路由 (61)
- 前端数组 (73)
- 前端排序 (47)
- 前端定时器 (47)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle 中文 (51)
- oracle的函数 (57)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)