问题梳理

180 阅读3分钟

关于async/awit的执行顺序

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

console.log('script start');
async1();
console.log('script end');

// 输出顺序:script start->async1 start->async2->script end->async1 end

遇到await关键字,会立即执行跟在await后面的代码,然后将await下方的代码变成一个微任务,加入到webAPI中进行监听,等待状态改变后加入到EventQueue中等待执行

描述回流和重绘

首先关于浏览器的渲染原理:

  • 1,浏览器解析css和dom结构生成dom树和css树
  • 2,结合dom树和css树生成渲染树
  • 3,回流:浏览器根据渲染树,生成对应节点的布局信息。
  • 4,重绘,浏览器根据布局信息和渲染树,生成对应的像素点
  • 5,diaplay阶段将像素点传送给GPU,GPU会根据像素点在屏幕绘制对应的视图。 浏览器的自身优化
    浏览器自身对回流和重绘有一定的优化能力,会将一些回流和重绘操作放到队列里,等到一定值的时候才会进行回流和重绘,但是也会遇到强制刷新队列的情况,那就是在获取布局信息的时候,浏览器需要重新进行计算,这个时候一定会强制刷新队列。

回流一定会发生重绘,重绘不一定会发生回流

减少回流和重绘

  • css中样式的统一修改使用cssText和class
  • dom使用虚拟dom,批量修改dom,虚拟dom,使用隐藏元素等等
  • 动画使用绝对定位使其脱离标准流,能够减少动画的回流和重绘
  • Gpu加速也能够在某些情况下使动画减少重拍重绘。

node事件循环

  • Node端,microtask 在事件循环的各个阶段之间执行

浏览器内核

浏览器内核通过获取数据,整合数据,然后处理之后将对应的信息显示在界面上,也成为渲染引擎。浏览器内核时多线程,主要由以下几个线程组成:

  • 1,GUI渲染线程
  • 2,js引擎线程
  • 3,定时器触发线程
  • 4,事件触发线程
  • 5,异步http请求线程 GUI渲染线程:
    负责css,html结构的解析,回流与重绘等。与javascript引擎线程互斥。

js引擎线程:
负责脚本逻辑代码的执行。和异步准备好的事件,与GUI渲染进行互斥

定时器触发线程:
主线程遇到setTimeout等定时器的时候,会将此任务交给定时器触发线程处理。事件触发事件会将计时完毕的计时器事件加入要执行的任务队列中,等待js引擎线程执行。

事件触发线程:
定时器时间到的时候,请求成功并触发回调函数的时候,时间触发线程会将对应的事件放入到执行队列中等待js引擎线程执行。

异步http请求线程:
负责执行异步请求一类的函数的线程,如: Promise,axios,ajax等。
主线程依次执行代码时,遇到异步请求,会将函数交给该线程处理,当监听到状态码变更,如果有回调函数,事件触发线程会将回调函数加入到任务队列的尾部,等待JS引擎线程执行。