最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 简括浏览器渲染机制

    正文概述 掘金(用户764234180127)   2020-12-19   440

    文章引自 前端大全

    前言

    前端仔每天都跟浏览器打交道,那么浏览器到底是怎样渲染的呢?

    我们都知道,JS是单线程的,也就是只有前一个任务执行完成,才会执行下一个任务。如果前一个任务耗时很长,那么下一个任务就只能干等着。显然,这样是非常浪费资源的。那么就要解决这个问题啦,先来了解一下**「Event Loop」**事件循环。

    Event Loop

    我们先来看一下HTML标准的解释:为了协调事件event,用户交互user interaction,脚本script,渲染rendering,网络networking等,用户代理user agent必须使用事件循环**「Event Loop」**。

    **「event-loop」**是解决JS单线程运行阻塞的一种机制,在JS的异步运行机制中,我们需要知道:

    • 所有的**「同步任务」**都在主线程进行

    • **「异步任务」**进入任务队列,任务队列会通知主线程,哪个异步任务可以执行,这个异步任务就会进入主线程。异步任务必须指定回调函数,当主线程开始执行异步任务,其实就是在执行对应的回调函数。

    • 如果主线程的所有同步任务都执行完,系统就会去读取**「任务队列」**上的异步任务,如果有可以执行的,就会结束等待状态,进入主线程,开始执行。

    • 主线程不断的执行第3步

    这就是JS的运行机制,也称为**「Event Loop」**事件循环。

    「宏任务」macrotasks:script(整体代码)、setTimeout、setInterval、setImmediate、I/O、UI rendering**「微任务」**microtasks:process.nextTick(NodeJS)、Promise、Object.observe、MutationObserver

    console.log('script start')setTimeout(() => {  console.log('setTimeout')}, 0)Promise.resolve().then(() => {  console.log('Promise 1')}).then(() => {  console.log('Promise 2')})console.log('script end')//运行结果//script start//script end//Promise 1//Promise 2//setTimeout
    

    过程分析:

    1、task队列中只有script,则将script中所有函数放进函数执行栈按顺序执行 2、接下来遇到setTimeout,这里的setTimeout只是将回调函数在0毫秒后放入task队列(其实是4ms,html5标准中规定中要求setTimeout中低于4ms的时间间隔算为4ms),也就是说回调函数在下一个事件循环执行,setTimeout在这里将回调函数放至task列表后就结束了。3、遇到Promise,属于**「microtasks」**,所以将第一个then的回调放到microtasks队列 4、执行完所有script代码后,检查microtasks队列,发现队列不为空,所以执行第一个回调函数输出'Promise 1',由于then的返回仍然是Promise,因此将第二个then的回调放至microtasks队列并执行输出'Promise 1' 5、此时microtasks队列为空,开始执行下一个事件循环。检查task队列发现setTimeout的回调函数,因此执行输出'setTimeout'

    浏览器渲染

    上面我们已经大致的了解到事件循环,为什么讲浏览器渲染要扯到事件循环呢?这是因为事件循环跟浏览器渲染有大大的关系,我们来一探究竟。

    关键渲染路径指的是浏览器接收最初的HTML,CSS,JS等资源后,解析,构建树,渲染布局,绘制,最后呈现给用户能看到的界面的这个过程。主要过程如下:

    • 解析HTML生成DOM树

    • 解析CSS生成CSSOM规则树(CSS Object Model)

    • 将DOM树和CSSO规则树合并生成渲染树(rendering tree)

    • 遍历渲染树开始布局,计算每个节点的位置大小等信息

    • 将渲染树每个节点绘制到屏幕

    上面的5个步骤并不是一次性执行完成,例如DOM或者CSSOM被修改时,就会有某个过程需要被重复执行,重新计算并重新渲染。实际上,由于JS跟css的操作会多次修改DOM跟CSSOM。

    当浏览器收到HTML文档后,会遍历文档节点,生成DOM树。HTML Parser将HTML标记解析成DOM树。

    CSS Parser将每个CSS文件都解析成一个**「StyleSheet」对象,每个对象都包含「Style Rules」**,也叫做CSSOM。

    有了DOM树跟CSS规则树,浏览器就可以结合他们来构建渲染树了。浏览器会先从DOM树的根节点开始遍历每个可见节点,然后为每个可见节点找到适配的CSS样式规则并应用到DOM树上。

    但是DOM树跟渲染树在结构上又不是完全对应的,区别在于:

    • display:none的元素不在渲染树中

    • visibility:hidden的元素在渲染树中

    生成渲染树之后,还是没有办法直接渲染到屏幕上。因为这时候还不知道每一个节点的位置信息,这就需要布局(Layout)的处理了,这个过程其实就是根据渲染树中渲染对象的信息,计算出每一个渲染对象的位置跟尺寸,将渲染对象放在浏览器相应的位置上。

    回流(reflow):当浏览器发现某个部分发生改变影响了布局,需要重新渲染。回流会从html的root frame开始递归往下,依次计算所有节点的尺寸跟位置。回流几乎是无法避免的,只要行为引起了页面上元素的占位方式,定位方式,边距等属性的变化,这都会引起内部,周围,甚至整个页面的重新渲染。

    重绘(repaint):当改变某个元素的背景颜色,文字颜色,边框颜色等不影响它内部以及周围布局的。屏幕的某一部分要重画,但是元素的尺寸位置都没有改变,这就是重绘。

    • display:none会出发回流,位置发生了变化。而visibility:hidden只会触发重绘,位置没有变。

    • 有些时候,修改了元素的尺寸或者颜色,浏览器不会立即回流或者重绘一次,而是会将这些操作积累下来,然后再做一次reflow,这叫做异步reflow。

    • 浏览器也有立即进行回流的情况,例如resize窗口,改变页面默认字体等。

    浏览器渲染进程

    浏览器的渲染是多进程的,包含了Browser进程第三方插件进程GPU进程浏览器渲染进程(浏览器内核),这里我们重点分析浏览器渲染进程,因为页面的渲染,JS的执行,事件的触发都是在这个进程中进行的。划重点:「浏览器的渲染是多进程的,浏览器的渲染进程是多线程的。」

    浏览器渲染进程有多个线程,下面来介绍浏览器的线程与其作用:

    GUI渲染进程做的事情其实就是上述的**「关键路径渲染」**,这里将不再叙述。而在了解GUI渲染进程的执行过程后,我们可以根据原理进行渲染优化:

    • 尽早引入CSS文件,例如在头部引入

    • 尽可能早的加载在CSS文件引入资源,例如自定义文件。可以使用预加载

    • 在DOM和CSS渲染后加入JS文件,例如可以在尾部加载JS文件

    JS引擎线程,也称为JS内核,负责处理JavaScript脚本程序。JS引擎等待着任务队列任务的到来,然后处理这些任务。无论什么时候,都只有一个JS引擎线程,因为JS是单线程的。

    关于为什么JS是单线程的,这里我想用一个例子来解释一下:假如JS是多线程的,假设现在有2条线程,一条在dom节点上添加节点,另一条删除这个节点。那么问题来了,这时候该以那条线程为准。所以说,JS的主要用途就是与用户互动,操作dom节点,这就决定了JS只能是单线程的。

    事件触发线程用来控制事件循环,当对应的事件符合条件被触发时,该线程会将事件添加到待处理的事件队列中,等待JS引擎的处理。

    上述已经讲到,所有的同步任务都在主线程运行,而异步任务进入任务队列。而异步任务均由事件触发线程控制,只要异步任务有了运行结果,就会在任务队列中放置回调函数,所以说异步任务一定要指定回调函数。

    主线程空了,就会去读取任务队列。这个过程不断的重复,其本质基于JS的事件轮询机制。

    JS是单线程的,当处于阻塞线程的状态会影响计时的准确性,因此需要单独开一个线程来计时。

    当使用setTimeout或者setInterval时,需要定时器线程计时。计时完成后会将特定的事件推进事件触发线程的任务队列中,等待进入主线程执行。

    • XMLHttpRequest在连通后通过浏览器新起一个线程请求

    • 检测到状态变化时,如果有设置回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中,再由JS引擎执行。

    总结

    将相关的知识梳理了一遍,希望本文能帮助各位同学更好的理解浏览器渲染。这是一篇差点鸽掉的文章,哈哈~虽迟但到。接下来的日子会抽更多的时间来学习。学无止尽,keep goging!


    下载网 » 简括浏览器渲染机制

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元