浏览器对内容的渲染分为5个部分
- 处理 HTML 标记并构建 DOM 树。
- 处理 CSS 标记并构建 CSSOM 树。
- 将 DOM 与 CSSOM 合并成一个渲染树。
- 根据渲染树来布局,以计算每个节点的几何信息。
-
将各个节点绘制到屏幕上。
这五个部分并不一定按顺序完成,首先浏览器几乎是并行加载资源,但浏览器的渲染有先后。
默认情况下,CSS 被视为阻塞渲染的资源,这意味着浏览器将不会渲染任何已处理的内容,直至 CSSOM 构建完毕。存在阻塞的 CSS 资源时,浏览器会延迟 JavaScript 的执行和 DOM 构建。
而JavaScript 不仅可以读取和修改 DOM 属性,还可以读取和修改 CSSOM 属性。当浏览器遇到一个 script 标记时,DOM 构建将暂停,直至脚本完成执行。
JavaScript 可以查询和修改 DOM 与 CSSOM。
CSSOM 构建时,JavaScript 执行将暂停,直至 CSSOM 就绪。
所以,script 标签的位置很重要。实际使用时,可以遵循下面两个原则:
CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源。
JavaScript 应尽量少影响 DOM 的构建。
白屏&FOUC(flash of unstyled content)无样式内容闪烁
白屏和 fouc 是不同浏览器的渲染机制,不是bug
白屏:CSS全部载入解析完后渲染展示页面。如果没有加载完,就会出现白屏
FOUC:CSS未完全加载前,会先渲染显示已经解析的HTML内容,然后CSS完全加载完成后,再次渲染。
repaint & reflow
当样式如颜色、字体等更改时浏览器会进行重绘,但是当样式的更改涉及到尺寸的更改时,会回流处理——重新计算位置,再重绘。下面是一些可能导致重绘和重流的样式:
var bstyle = document.body.style;//cache
bstyle.padding = "20px";//reflow,repaint
bstyle.border="10px solid red";//reflow,repaint
bstyle.color="blue"//repaint
bstyle.fontSize="2em";//reflow,repaint
css 会阻碍图片的加载,而浏览器在遇到 js 时会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行,js在加载时,渲染文件的加载会停止。
但是给script标签增加async和defer关键词后,渲染问价可以与js文件同步加载,并且使用defer关键词,js的加载完成后不会马上执行,会等候后续所有元素解析完成后再执行
<script async src="script.js"></script>
<script defer src="script.js"></script>
参考文献
https://juejin.im/entry/59e1d31f51882578c3411c77
https://zhuanlan.zhihu.com/p/33448591
https://zhuanlan.zhihu.com/p/29418126