关于浏览器的渲染机制,先要了解一些基本概念:
- DOM:浏览器解析html构建DOM树
- CSSOM:浏览器解析CSS构建CSSOM规则树
- Render Tree:DOM和CSSOM合并后生成Render Tree
- layout:layout:有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系,从而去计算出每个节点在屏幕中的位置
- painting:按照算出来的规则,通过显卡,把内容画到屏幕上
-
reflow(回流):当浏览器发现某个部分发生了点变化影响了布局,需要倒回去重新渲染,内行称这个回退的过程叫 reflow。reflow 会从 <html> 这个 root frame 开始递归往下,依次计算所有的结点几何尺寸和位置。reflow 几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲 染。通常我们都无法预估浏览器到底会 reflow 哪一部分的代码,它们都彼此相互影响着。
- repaint(重绘):改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸没有变。
流程图如下:
接下来再说说浏览器如何渲染的
加载过程:
当浏览器获取到一个html文件后,会“自上而下”的加载,并在加载的过程中解析和渲染。
加载过程中遇到外部css文件,浏览器另外发出一个请求,来获取css文件。
遇到图片资源,浏览器也会另外发出一个请求,来获取图片资源。这是异步请求,并不会影响html文档进行加载。
但是当文档加载过程中遇到js文件,html文档会挂起渲染(加载解析渲染同步)的线程,不仅要等待文档中js文件加载完毕,还要等待解析执行完毕,才可以恢复html文档的渲染线程。
为什么遇到JS要等待呢?因为JS可能会修改到DOM,导致后面的资源白加载了。(所以这也就是为什么建议将JS文件放在html文档</body>前)
如果在加载的过程中遇到了CSS时,CSS不阻塞DOM的加载和解析,不会阻塞其它资源(如图片)的加载,但是会阻塞 后续JS 文件的执行(原因之一是,js执行代码可能会依赖到css样式。css只阻塞执行而不阻塞js的加载)。
解析过程:
- 1、浏览器通过请求的 URL 进行域名解析,向服务器发起请求,接收文件(HTML、CSS、JS、Images等等)。
- 2、HTML 文件加载后,开始构建 DOM Tree(DOM树)
- 3、CSS 样式文件加载后,开始解析和构建 CSS Rule Tree
- 4、Javascript 脚本文件加载后, 通过 DOM API 和 CSSOM API 来操作 DOM Tree 和 CSS Rule Tree
- 1、浏览器引擎通过 DOM Tree 和 CSS Rule Tree 构建 Rendering Tree(渲染树)
- 2、布局阶段——在屏幕上绘制渲染树中的所有节点的几何属性,比如: 位置,宽高,大小等等,这个过程称为 Flow 或 Layout 。
- 3、绘制元素——绘制所有节点的可视属性。
- 4、合并渲染层——把以上绘制的所有图层(类似于PhotoShop中的“图层”)合并,最终输出一张图片
其中的阶段3、4可称之为Paint
关于浏览器显示白屏和FOUC: