前端面试宝典---事件循环面试题
浏览器进程模型与 JavaScript 执行机制
现代浏览器采用多进程架构,包含浏览器进程、渲染进程、网络进程等多个核心进程。每个标签页会独立创建一个渲染进程,负责页面内容的解析、渲染和执行脚本代码。
JavaScript 的单线程特性
JavaScript 采用单线程执行模型,其主线程同时承担两个关键职责:
- GUI 渲染线程:处理 HTML/CSS 解析、样式计算、布局绘制(每秒 60 帧渲染)
- JS 引擎线程:执行全局代码和回调函数
这两个功能模块存在互斥关系,无法并行执行。单线程设计避免了多线程环境下 DOM 操作的竞态条件问题(如一个线程删除 DOM 时另一个线程在修改),同时也简化了语言实现复杂度。异步机制则解决了耗时操作可能造成的线程阻塞问题。
异步执行原理
同步执行模式可能导致主线程阻塞,引发页面卡顿。浏览器采用异步处理机制:
- 主线程将计时器、网络请求等任务委托给对应线程
- 主线程继续执行后续同步代码
- 任务完成后,回调函数被封装为任务对象加入消息队列
- 主线程通过事件循环机制调度这些异步任务
这种模式确保主线程始终保持响应能力,同时兼顾任务处理的时效性。
任务优先级分级
消息队列采用分级调度策略:
- 宏任务(MacroTask):脚本整体代码、setTimeout、I/O 等
- 微任务(MicroTask):Promise、MutationObserver 等
微任务具有更高优先级,确保关键更新能及时处理(如 Promise 的状态变更),而定时器等相对不敏感的宏任务可以适当延迟执行。
完整事件循环流程
-
同步代码执行阶段
主线程顺序执行全局脚本,遇到异步 API 时移交对应模块处理 -
微任务检查并清空
当前调用栈清空后,立即执行全部微任务队列中的任务 -
宏任务处理
选取最早的宏任务执行,执行期间产生的微任务会在该宏任务结束后立即处理 -
渲染时机判断
若距离上次渲染超过 16ms(60Hz 屏幕),或页面内容发生变化,则执行渲染任务,若没有,回到步骤 3 继续执行下一个宏任务。 -
循环持续
重复上述过程直至所有任务队列清空