浏览器渲染页面机制——流程图

为了能更好、更快的为用户呈现出他们想要的页面,基于浏览器的渲染机制,我们在开发中应该了解浏览器,了解浏览器的运行机制,以及在开发中我们能更好的提高性能,虽然现在市面上流行的VUE和react,但也应该了解内在的机制,更好的去理解框架的思想,后续再介绍Vue等。
1.浏览器开辟的线程
我们都知道计算机在运行的时候,为了提升CPU的利用率,会开辟不同的进程和线程,进程和线程的关系不再赘述。浏览器在运行的时候,就会开辟一个进程,然后计算机把相应的资源分配给这个进程来供浏览器的使用,为了提高性能,异步操作每一个任务,浏览器会开辟多个进程来进行页面的渲染,浏览器开辟的主要线程,包括以下五个:GUI渲染线程渲染和绘制页面
、 JS引擎线程运行和渲染JS
、 事件触发和管控线程、 定时器触发和管控线程、 异步HTTP请求线程。

2.页面的组成以及浏览器的处理
在浏览器渲染页面的时候,由GUI渲染进程从头到尾的渲染页面的各个组成部分,包括HTML/CSS/JS,针对于HTML,浏览器按部就班的执行,当遇到css时,基于css的导入方式有很多,渲染的时候分三种情况:①link导入浏览器碰到link,则会新开辟一个HTTP请求线程,专门去加载css样式。@import导入浏览器不会新开辟一个线程专门去加载,主线程GUI进行渲染,主线程收到阻碍。③style内嵌式适用于css代码较少,减少开辟新的进程。
3.浏览器渲染页面的步骤
- 生成DOM-TREE:渲染页面中所有的HTML,生成DOM树

- 生成CSS-TREE:渲染所有的CSS

- 生成RENDER-TREE:把DOM-TREE和CSS-TREE合并,形成RENDER-TREE

- 进行计算:按照RENDER-TREE,在设备的视口中进行结构和位置的计算。
- 绘制:通过从RENDER-TREE得到的几何信息,得到节点的绝对像素绘制或者栅格化。
4.优化方案
为加快浏览器的渲染,根据浏览器的渲染机制,可以通过以下几个方面来优化渲染速度:
-
标签语义化
-
CSS选择器渲染是从右到左,尽量避免css选择器嵌套太多
-
尽早尽快地把CSS下载到客户端(充分利用HTTP多请求并发机制) 基于浏览器对css导入方式有不同的处理:我们优先选择link导入式,代码量少优先选择内嵌式
-
避免阻塞的JS加载:给script设置标识来异步修饰
- defer:需要等待GUI渲染后统一按照之前编写的script顺序依次执行。
- async:是在加载回来文件之后,立即去执行(此时会阻碍GUI线程的渲染)
在项目中,为了防止加载JavaScript阻塞GUI渲染线程,一般要把
<scrip></script>
放在尾部,让DOM-TREE等尽快加载渲染完成,并且在绘制完页面之后更好的获取相应的DOM元素,进而来操作。- 事件监听处理
window.onload = function(){...}
window.addEventListener('DOMContentLoaded',function(){...})
俩者的区别:第一个方式是等待多有的资源加载完,再触发js加载渲染。第二个方式是在DOM加载完成之后触发js的加载并渲染。
4.DOM的回流和重绘
- 重绘 元素的样式发生改变,但是其宽高、大小、位置、并没有改变,比如透明度的改变。
- 回流 元素的大小、位置发生了改变,就会触发一次回流,导致页面的布局发生了改变
回流一定触发重绘,重绘不一定触发回流
5.如何减少回流和重绘在不使用框架
首先在新版本浏览器中,也做了相应的优化,为了提高性能,浏览器增加了渲染队列机制以减少回流和重绘。
渲染队列的运行机制:在代码从上往下执行的时候,把所有要修改DOM样式的代码都放入队列中,然后一次性统一渲染,从而只触发一次回流和重绘。利用该运行机制可以分离读写,来控制浏览器渲染次数。
在实际开发中如何做到减少回流和重绘?有以下几种方案:
- 分离读写 把设置样式和读取样式分离开
- 集中改变样式有俩种方式:
- ①给盒子添加类名,基于类名选择器来一次性添加样式。
- ②通过box.style.cssText = '';来一次性设置样式。
/* 方案二:集中改变样式 */
box.className = 'active';
box.style.cssText = 'width:200px;height:200px;';
- 动态操作DOM建立一个文档碎片临时存放动态创建的DOM元素,把所有需要动态创建的元素都创建完成后,再一次性的放到页面中。
比如:字符串的拼接
- 动画效果 应用到盒子position属性为absolute上
- css3硬件加速
- 牺牲平滑度换速度
- 避免table布局和使用JavaScript表达式