进阶篇:浏览器渲染 & 白屏和FOUC(1)
饥人谷学习进阶第 1 天
JavaScript
- 网页 = Html + CSS + JavaScript
-
Html
:网页元素内容 -
CSS
:控制页面样式 -
JavaScript
:操作网页内容,实现功能或者效果
JavaScirpt 发展历史
浏览器的渲染机制
- 解析HTML标签,构建DOM树
- 解析CSS标签,构建CSSOM树
- 把DOM和CSSOM组合成渲染树(render tree)
- 在渲染树的基础上进行布局,计算每个节点的几何结构
- 把每个节点绘制到屏幕上(painting)
浏览器渲染.png
浏览器的工作原理,可参考How browsers work
关于 Repaint 和 Reflow
对于DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式(浏览器的、开发人员定义的等)来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow;当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为repaint。
CSS 和 JS 放置顺序,异步机制
- 使用 link 标签将样式表放在顶部
- 将 JS 放在底部
- 脚本会阻塞后面内容的呈现
- 脚本会阻塞其后面组件的下载(如:图片)
对于图片和CSS,在加载时会并发加载(如一个域名下同时加载两个文件),但在加载JS时,会禁用并发,并阻止其他内容的下载,所以把JS放在页面顶部会导致白屏
现象
白屏 & FOUC(Flash of Unstyled Content)无样式内容闪烁
-
白屏:打开浏览器时白屏,经过一定时间,正确的样式突然出现(白色的时间就是白屏)
-
无样式内容闪烁:
1.打开一个页面,先是一种样式,突然样式变了或变了几次
2.打开一个页面,里面的元素先是无样式,然后突然样式出现
不同浏览器对资源加载页面渲染不同的处理方式
异步加载
-
没有 defer 或 async
<script src="script.js"></script>
浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。 -
deger
:脚本延迟到文档解析和显示后执行,有顺序
<script defer src="script.js"></script>
有defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但script.js的执行要在所有元素解析完成之后,DOMContentLoaded事件触发之前完成。 -
async
:不保证顺序
<script async src="script.js"></script>
有async,加载和渲染后续文档元素的过程将和script.js的加载与执行并行进行(异步)。