龙空技术网

追本溯源 浏览器渲染机制

嚯哈哈张 139

前言:

当前你们对“加载动画js语句”大约比较注重,大家都需要剖析一些“加载动画js语句”的相关资讯。那么小编也在网上收集了一些对于“加载动画js语句””的相关内容,希望小伙伴们能喜欢,小伙伴们快快来了解一下吧!

现在的前端生活在一个幸福的时代,至少不用再为适配IE而掉头发

常见的浏览器渲染引擎渲染引擎

能加载HTML/css/javascript文本和对应资源文件转换成图像结果

渲染器种类

渲染引擎浏览器TridentIE、Edge(旧)GeokoFirefoxWebkitSafariBlink(Webkit form)Chrom额, Opera,Edge(新)

浏览器的工作流程

image.png

webkit的主要流程

image.png

我们围绕这张图,看下浏览器是如何渲染页面的技术细节

解析dom,生成dom tree(并行)解析css,生成cssom tree(并行)将dom树和cssom规则合并在一起生成渲染树遍历开始布局,计算节点位置大小,生成布局树GPU工作,按照布局树规则在屏幕上绘制页面构建dom树

浏览器接收到html文档之后,遍历文档所有节点,根据深度优先遍历的算法,HTML解析器将HTML标记解析成DOM Tree(就是我们审查元素时的层级结构)。

构建csscom树

css Parse 将每一css 文件都解析成一个styleSheet对象,每个对象包含style Rules,这个也就是所谓的cssom。

不知道大家在这里会不会有和我一样的疑问,既然cssom是为了dom而存在的,为什么不在dom解析的时候,就将对应的样式添加到dom上呢?而且css具有很高的优先级,css会阻塞任何的渲染,在css解析前,页面上不会有任何反应。我想到的解释是,如果css解析之前就渲染了页面,那么每个页面都是无样式的,过一会却突然有了样式,整个页面的渲染就会很糟糕。

生成Render Tree

这个时候,浏览器会将DOM和CSSDOM结合起来生成Render Tree(渲染树)

生成布局树 Layout

创建渲染树之后,构建布局树,分两个部分:

回流

浏览器布局发生改变,需要倒回去重新渲染,这个过程叫做回流(reflow),从root往下递归计算,来确认是渲染树的整体还是一部分发生改变。

引起回流的一些操作

页面第一次渲染(初始化)DOM树变化(如:增删节点)Render树变化(如:padding改变)浏览器窗口resize获取元素的某些属性:offsetLeftoffsetTopoffsetWidthoffsetHeightscrollTop/Left/Width/HeightclientTop/Left/Width/Height、调用了getComputedStyle()

image.png

重绘

改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸和位置没有发生改变,这个过程叫做重绘(repaint)

回流必定引起repaint重绘,重绘可以单独触发

背景色、颜色、字体改变(注意:字体大小发生变化时,会触发回流)

image.png

减少reflow、repaint触发优化用transform做形变和位移可以减少reflow避免逐个修改节点样式,尽量一次性修改使用DocumentFragment将需要多次修改的DOM元素缓存,最后一次性append到真实DOM中渲染可以将需要多次修改的DOM元素设置display:none,操作完再显示。(因为隐藏- - 元素不在render树内,因此修改隐藏元素不会触发回流重绘)避免多次读取某些属性通过绝对位移将复杂的节点元素脱离文档流,形成新的Render Layer,降低回流成本GUI绘制页面 Painting

image.png

根据渲染树,确定了绘制顺序,主线程将信息提交给合成器线程。合成器线程栅格化每个图层。合成器会将图层分为图块,并发送到光栅线程。栅格化每一个tile(瓦片)并存储在GPU中。

把文档的结构、元素的样式、几何形状和绘制顺序转换为屏幕的像素称为光栅化合成是一种将页面的各个部分分层,分别栅格化,在一个被称为合成器线程的独立线程中合成页面的技术。

浏览器内核(渲染进程)中线程之间的关系

image.png

为了防止渲染出现不可预期的结果,GUI线程和JS引擎线程互斥

js是可以操作dom的,如果修改时,在GUI正在渲染,这个时候GUI线程会被挂起,保存在一个队列中,等待js引擎空闲时立即被执行

问:CSS加载会阻塞DOM树的解析,渲染吗?这里说的是头部引入css的情况

答:根据上面的流程图可以看到,dom树和cssom是互相解析的,但是在生成render树的时候,需要等待css解析完,所以CSS加载不会阻塞DOM树的解析,但是会阻塞DOM树的渲染

问:CSS和JS会互相阻塞吗?

答:因为GUI线程和JS引擎线程互斥,我们可以分别尝试分别把js和css放在上面

script标签在style上面使用alert语句,页面不加载,阻塞了css解析style在上面,使用慢网速加载cdn的css样式,样式展示前,js不执行,阻塞了js的执行

结论,CSS加载会阻塞后面JS语句的执行,所以在开始学习前端时,会建议大家将script标签放在body之后,防止影响页面渲染。

总结

我们以谷歌(webkit)为例分析了浏览器的渲染过程,中间生成了四棵树,dom树,cssom树,渲染树,布局树,中间我们可以优化操作来减少回流和重绘,了解这一过程非常必要,可以规范我们的样式书写,减少页面性能不必要的消耗。

标签: #加载动画js语句