CSS的网络性能优化
Posted 达内首都教学部
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSS的网络性能优化相关的知识,希望对你有一定的参考价值。
最近有很多小伙伴都在苦恼css的网络性能问题,然而网上的相关资料却并不多。今天我就结合 CSS 与性能这两大主题,为大家带来一篇文章吧。
CSS 是页面渲染的关键因素之一,(当页面存在外链 CSS 时,)浏览器会等待全部的 CSS 下载及解析完成后再渲染页面。关键路径上的任何延迟都会影响首屏时间,因而我们需要尽快地将 CSS 传输到用户的设备,否则,(在页面渲染之前,)用户只能看到一个空白的屏幕。
浏览器直到渲染树构建完成后才会渲染页面;
渲染树由 DOM 与 CSSOM 组合而成;
DOM 是 html 加上(同步)阻塞的 javascript 操作(DOM 后的)结果;
CSSOM 是 CSS 规则应用于 DOM 后的结果;
使 JavaScript 非阻塞非常简单,添加 async 或 defer 属性即可;
相对而言,要让 CSS 变为异步加载是比较困难的;
基于上述考虑,我们需要尽快构建 DOM 与 CSSOM。一般情况下,DOM 的构建是相对较快,(当请求某个页面时,)服务器响应的首个请求是 HTML 文档。但一般 CSS 是作为 HTML 的子资源而存在,因此 CSSOM 的构建通常需要更长的时间。
在这篇文章中,会讲述 CSS 为何是网络瓶颈(无论是对于它自己或是其他资源),该如何突破它,从而缩短关键路径以减少首次渲染前的等待时间。
以非常高的优先级下载符合当前上下文(设备、屏幕尺寸、分辨率、方向等)的 CSS 文件,阻塞关键路径;
以非常低的优先级下载不符合当前上下文的 CSS 文件,不会阻塞关键路径。
为缩短渲染等待时间而努力的下一项任务非常简单:
如果了解 @import 的原理,那应该清楚它的性能并不高,使用它会阻塞渲染更长时间。这是因为我们在关键路径上创造了更多(队列式)的网络请求:
下载 HTML;
请求并下载依赖的 CSS;下载及解析完成后,本该是构造渲染树,然而;
CSS 依赖了其他的 CSS,继续请求并下载 CSS 文件;构造渲染树。
注意:
<script>
var script = document.createElement('script');
script.src = "analytics.js";
document.getElementsByTagName('head')[0].appendChild(script);
</script>
<link rel="stylesheet" href="slow-loading-stylesheet.css" />
<script>
console.log("I will not run until slow-loading-stylesheet.css is downloaded.");
</script>
这是合理的
当 CSS 文件尚未下载完成时,HTML 文档中任何同步的 JavaScript 代码,均不会执行。考虑以下场景: <script> 中的代码会访问当前的页面样式,为确保结果正确,需要等待( <script> 标签前)所有 CSS 文件下载并解析完毕后再获取,否则无法保证正确性。因此,在 CSSOM 构建完成之前,<script> 中的代码不会执行。
根据这现象,CSS 文件的下载时间会对后续 <script> 的执行时间造成影响。
建 议
如果 <script> 中的代码并不依赖 CSS,把它们放在样式表之前。
将无需查询 CSSOM 的 JavaScript 代码放在 CSS 文件之前,需要查询的放在 CSS 文件之后
上文讨论了插入新 <script> 的代码应放在 <link> 之前,那是否能推广到其他的 CSS 与 JavaScript 呢?为了弄明白这个问题,先提出以下假设:
1. CSSOM 的构建会阻塞 CSS 后面同步 JS 的执行;
2. 同步的 JS 会阻塞 DOM 的构建…
1. script 在前 style 在后;
2. style 在前 script 在后?
如果 JS 文件没有依赖 CSS,你应该将 JS 代码放在样式表之前。 既然没有依赖,那就没有任何理由阻塞 JavaScript 代码的执行。
以下是我总结的 CSS 加载相关的一系列的最佳实践,值得参考
如果 JavaScript 依赖 CSS:
这将提高初次渲染的速度使让页面逐步渲染
注意
本文叙述的内容都遵循规范或根据浏览器的行为推导得出,然而,你应该亲自进行测试。尽管理论上是正确的,但在实践中可能会有所不同。记得好好测试!
往期文章:
以上是关于CSS的网络性能优化的主要内容,如果未能解决你的问题,请参考以下文章