关于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引擎线程执行。