前端基础--浏览器的渲染原理

浏览器渲染原理

        question:什么是浏览器渲染(render)?

        answer :浏览器的渲染简单的说就是将html代码解析出来,把解析出来后的结果画到页面上,相当于就是,告诉浏览器,第一个像素点上应该呈现什么颜色,依次类推,占满占满整个页面静态,为什么说是静态的呢,因为当用户发生交互,页面变化(滚动、刷新、跳转等),使页面改变后,浏览器得重新计算整个页面的像素,可想而知,是一个庞大的工作量。

                渲染流程(两大类):网络请求、渲染

当浏览器请求某个网页的时候,网络线程收到html文档,包装成渲染任务,并把它排到渲染主线程的消息队列。在事件循环的机制下,渲染主线程就会收到渲染任务开始渲染。渲染过程好比一个严密的流水线,每个步骤发挥着关键的作用,有条不紊的进行着。

里面包括了多个阶段:html解析、样式计算、布局、计算层级、绘制、分块、光栅化、面页面等。

HTML解析(Parse HTML)

        开始得到的是一个对象,为了后续的操作,浏览器解析后,得到html基本结构(DOM树)和css的样式结构(css object model)CssOM树

 在整个解析过程中,开始会开启一个预解析的线程,跑在主线程之前,提前下载和处理文件中的外部css文件和外部的javascript文件,主线程在解析到link标签时,如果外部的文件还没下载好,主线程会跳过,继续后面的解析。

!注:下载和解析css是在预解析线程进行的,这是css不会阻塞HTML解析的根本原因。

当渲染主线程遇到JS代码时,必须暂停一切行为,等待下载执行完之后,才能继续。在代码中,有JS的代码错误,会阻塞页面的解析(报错)的原因。预解析线程能分担一些下载JS的任务。

计算样式--Recalculate Style

        通过原先的DOM树和CssOM树,遍历后,依次计算出每个节点最终样式。计算后,每个DOM树 的节点上都会绑定一个Computed Style,得到带样式的DOM树。会把预设值变成绝对值,比如red变成rgb(255,0,0),单位都计算为px值。

布局--Layout

        根据带样式的DOM树,计算每个节点的几何信息,得到一个Layout树。两者的机构层级不一定是一一对应的,因为在布局时,涉及到了HTML的元素属性(行内元素、块级元素),在Layout树中,会根据不同的元素,去改变树的结构,例如一个p标签,和一个简单的内容 123 ,Layout树会在p标签结构和p的之间子元素之间生产一个匿名的行盒,在内容 123 之前生成一个匿名的块盒,用来区分两者的位置关系。比如一个元素属性为 display:none ,它在DOM树存在相应的节点,而在Layout树就没有这类的节点存在,伪元素也是一样的,DOM树里并不存在这个节点,而计算出来的Layout树里就会出现对应的节点。

分层--Layer

        主线程会使用一套复杂的策略,对整个HTML页面进行分层处理。

        分层处理,对后续的页面的某一层数据页面更新后,仅对该层的数据和页面进行更新,从而提高页面的渲染效率。就像一栋房子,某一个业主有什么要求,就只对该业主的房子就行特殊的装修,而不影响整栋楼其他层的住户。

       可以打开浏览器的调试工具,选择 更多  ,在More tools 选项中的Layers中查看浏览器分层。

        影响浏览器分层有很多,滚动条单独一层,堆叠上下文(z-index),transform,opacity等样式都会影响分层

绘制--Paint

        简单说就是为每个层生成一个绘制指令,告诉浏览器这个层怎么绘制出来。

        绘制完之后,主线程会每个图层的分层信息告诉合成线程,剩余工作交给合成线程去完成。

分块--Tiling

        在合成线程中,会为每一层分成一些小的区域,就像在一套房子里面,分出主卧、次卧、厨房、卫生间等,之后调用其他多个线程去完成这些分区域工作。

光栅化--Raster

        这个过程就是把每个分块后的信息交给GPU(图形处理器)去完成光栅化,这步骤之后产生的就是像素点信息(在PS里,称为位图),GPU在转换的时候,会优先处理我们视口里面的块,这也是一个用户体验的优化。

        众所周知,GPU和CPU都是处理器,GPU的运算速度远高于CPU的运算速度,那我们为什么不都用GPU呢,还去用CPU?这是因为GPU能做的,CPU都能做,但CPU能做的GPU不一定都能做的,GPU只是趋向于更专业化,专业的去处理图形信息。

画--Draw

        合成线程在计算出每个位图的位置信息后,交给GPU去进行最终的呈现。

        question:为什么合成线程不直接交给我们的显卡去直接呈现呢?

        answer:合成线程和渲染主线程都是属于渲染进程里面的,渲染进程和我们的计算机硬件是相互独立的,也就是说渲染进程在已一个沙箱 里面,这也是一个安全的措施,在我们浏览器网页的时候,可能会遇到一些破坏性的恶意行为,独立出来就会保护我们的计算机安全。

        这时每个位图都有自己的位置信息(指引-quad),GPU会告诉硬件,那个位置该呈现什么图像,最终完成屏幕的呈像。

 彩蛋(面试题)

        1.question:什么是reflow(重呈现)?

        answer:也就是当我们的操作影响了页面的DOM树、CssOM树时,会导致页面的位置信息、分层信息、和块大小的改变时,使得后续的渲染步骤重执行的过程;为了避免连续操作导致的反复计算,浏览器会合并这些操作,等待JS代码执行完成后统一计算,所以,改动属性造成的reflow是异步的。

        2.question:什么是repaint?

       answer: repaint(重绘)的本质就是重新根据分层信息计算绘制指令。带动了可见的样式时,都会重新计算,引发repaint,由于元素的布局信息也是属于可见样式,所以reflow一定会引发repaint。

        3.question:为什么transform的效率高?

        answer:我们在用元素属性改变元素时(包括位置,大小等),这回导致浏览器重新进行一遍渲染流程,而transform去改变元素时,他不会引起页面的reflow,只是对去进行渲染线程的最后一步draw,所以使得他的效率更高。

  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值