浏览器多进程,浏览器渲染(回流与重绘),JS运行机制(宏任务与微任务的解读 eventLoop)

一、前言

部分参考:https://juejin.cn/post/6844903553795014663#heading-8

个人笔记知识点,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正。最后有笔试题

二、大纲

  1. 进程和线程
  2. 浏览器是多进程的
  3. 浏览器内核-渲染进程(五个渲染线程)
  4. 浏览器渲染步骤流程
  5. 回流与重绘
  6. 从Event Loop谈JS的运行机制
  7. 微任务,宏任务
  8. 微任务,宏任务笔试题

进程和线程

进程是由一个线程或者多个线程组成的。
他们关系相当于“工厂”与“打工人”关系

u=1086966994,1021503877&fm=253&fmt=auto&app=138&f=JPEG.webp

- 进程是一个工厂,工厂有它的独立资源 
- 工厂之间相互独立 
- 线程是工厂中的打工人,多个打工人协作完成任务
- 工厂内有一个或多个打工人
- 打工人(线程)之间共享空间

进阶

webpack 的 thread-loader多进程打包

webpack 的 happypack多线程打包

浏览器是多进程的

浏览器是多进程的。

例如:windows电脑中,可以打开任务管理器

image.png

浏览器包含了以下四个进程

  1. Browser进程:浏览器的主进程

    • 网络资源的管理,下载等
    • 负责浏览器界面显示,与用户交互。如前进,后退等
  2. 第三方插件进程

  3. GPU进程:用于3D绘制等

  4. 浏览器渲染进程(浏览器内核)

    • 页面渲染,脚本执行,事件处理等

重点是浏览器内核(渲染进程)

浏览器的渲染进程是多线程的

1. GUI渲染线程

  • 负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。
  • 当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行

2. JS引擎线程

  • 也称为JS内核,负责处理Javascript脚本程序。(例如V8引擎)
  • JS引擎线程负责解析Javascript脚本,运行代码

js为单线程

**  js是单线程的,也就代表js只能一件事情一件事情执行,那如果一件事情执行时间太久,
**  后面要执行的就需要等待,需要等前面的事情执行完成,后面的才会执行。****


同样注意,GUI渲染线程与JS引擎线程是互斥的,所以如果JS执行的时间过长,
这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞。
当JS引擎执行时GUI线程会被挂起(相当于被冻结了),
GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。

3. 事件触发线程

  • 归属于浏览器而不是JS引擎,用来控制事件循环(可以理解,JS引擎自己都忙不过来,需要浏览器另开线程协助)

  • 当JS引擎执行代码块如setTimeOut时(也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件线程中

  • 当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理

  • 注意,由于JS的单线程关系,所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)

4. 定时触发器线程

  • 传说中的setIntervalsetTimeout所在线程

  • 浏览器定时计数器并不是由JavaScript引擎计数的,(因为JavaScript引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确)

  • 因此通过单独线程来计时并触发定时(计时完毕后,添加到事件队列中,等待JS引擎空闲后执行)

5. 异步http请求线程

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

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

image.png

浏览器渲染步骤流程

浏览器器内核拿到内容后,渲染大概可以划分成以下几个步骤:

  1. 解析html建立dom树
  2. 解析css建立CSSOM树,然后结合DOM合并成render树
  3. 布局render树(Layout/reflow),负责各元素尺寸、位置的计算
  4. 绘制render树(paint),绘制页面像素信息
  5. 浏览器会将各层的信息发送给GPU,GPU会将各层合成,显示在屏幕上
    渲染完毕后就是load事件了,之后就是自己的JS逻辑处理了

image.png

回流与重绘

什么是回流

当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。

什么是重绘

当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。

区别:

他们的区别很大:

  • 每个页面至少需要一次回流,就是在页面第一次加载的时候,这时候是一定会发生回流的,因为要构建render tree。

  • 回流必将引起重绘,而重绘不一定会引起回流
    。比如:只有颜色改变的时候就只会发生重绘而不会引起回流

从Event Loop谈JS的运行机制

  • JS分为同步任务和异步任务

  • 同步任务都在主线程上执行,形成一个执行栈

  • 主线程之外,事件触发线程管理着一个任务队列,只要异步任务有了运行结果,就在任务队列之中放置一个事件。

  • 一旦执行栈中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行,如此循环这个步骤,被称为事件循环(Event Loop)

image.png

微任务,宏任务

概念:

宿主环境提供的叫宏任务,由语言标准提供的叫微任务

  • 宿主环境宏任务

    简单来说就是能使javascript完美运行的环境,只要能完美运行javascript的载体就是javascript的宿主环境。目前我们常见的两种宿主环境有浏览器和node。

    常见的两个宏任务:

    • setTimeout

    • setInterval

  • 语言标准微任务

    由语言标准提供的就是微任务,比如ES6提供的promise。
    常见的微任务:

    • Promise.then()
    • Object.observe
    • MutationObserver
    • process.nextTick(Node环境独有)

    微任务和宏任务的工作流程总结:有微则微,无微则宏)

    1. 看微任务队列是否有微任务
    2. 没有微任务执行下一个宏任务
    3. 有微任务将所有微任务执行
    4. 执行完微任务,执行下一个宏任务

image.png

微任务,宏任务面试题

async function async1() {
  console.log('async1 start')
  await async2()
  console.log('async1 end')
}

async function async2() {
  console.log('async2')
}

console.log('script start')

setTimeout(function () {
  console.log('setTimeout')
}, 0)

async1();

new Promise(function (resolve) {
  console.log('promise1')
  resolve();
}).then(function () {
  console.log('promise2')
})

console.log('script end')

这段代码的执行结果会是什么呢?

知识点:

解析:
1.await 执行完后,。async 标记的函数会返回一个 Promise 对象,等promise对面都执行完后再执行下面的语句**

2.await asyn2()后面的代码console.log(")相当于.then的微任务

最终答案为
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值