浏览器的渲染机制,白屏和FOUC

关于浏览器的渲染机制,先要了解一些基本概念:

  • 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:

不同的浏览器对于CSS和HTML的处理方式不同,有的是等待CSS加载完成之后,对HTML元素进行渲染和展示(白屏问题)。有的是先对HTML元素进行展示,然后等待CSS加载完成之后重新对样式进行修改(FOUC无样式内容闪烁)
 
 
 

 
自己也是小白,没法写出什么技术高深的博客,很多知识点也是参照大神写的内容,自己理解后再做个读后感
 
参考:
浏览器是怎样加载js代码的? - 第七星尘的回答 - 知乎 https://www.zhihu.com/question/263866883/answer/276139578
李某龙:https://www.cnblogs.com/slly/p/6640761.html
原文地址:https://www.cnblogs.com/ianyanyzx/p/9151826.html