当前位置: 首页 > news >正文

深入理解浏览器的事件循环

浏览器的进程模型

  1. 浏览器进程:负责子进程的管理和用户交互
  2. 网络进程:负责加载网络资源
  3. 渲染进程:浏览器会为每一个标签页开启一个新的渲染进程。
    • 渲染进程中的渲染主线程是我们最关注的,因为浏览器的事件循环就发生在这之中
    • 渲染主进程不仅负责页面的渲染,还负责 JS 脚本的执行
    • 除此之外,渲染进程中还有交互线程,处理定时器的线程等

[!NOTE]

但是每个标签开一个渲染进程,会浪费太多的内存,因此 Chrome 浏览器在尝试以另外的模式(同一个主域名下的子网页共用一个渲染进程)来优化浏览器系统的性能。

如何理解 JS 的异步?

因为 JS 一门单线程语言,他执行在渲染主线程中,当我们遇到一些任务需要长时间等待时,比如定时器,如果他是同步的话,必须等待计时器结束,然后执行定时器的回调之后才能继续执行后续的任务,这样会白白等待太多时间,因此渲染主进程会将异步任务丢给其他线程去处理(比如定时器会调用操作系统来辅助操作),当其他线程的异步任务执行完后,会将回调包装成任务放到消息队列的末尾,等待渲染主线程去调度。

事件循环整体流程:

  1. 浏览器的主线程会进入无限的循环监听(不会结束的 for 循环)
  2. 首先检查调用栈是否为空
  3. 调用栈不为空则先执行当前调用栈中的任务
  4. 调用栈为空的话去消息队列中取所有的微任务来执行
  5. 执行完所有的微任务后,取一个宏任务来执行
  6. 接着循环上述过程

保证浏览器永不阻塞,最大程度保证单线程的流畅执行。

[!WARNING]

但是随着任务类型的愈加复杂,W3C 已不再采用宏任务的说法,而是将异步任务分为很多不同的类型,同一个类型的任务必须放在同一个队列,例如 Chrome 浏览器中将异步任务队列分为:

  • 延时队列:计时器到达后执行的回调任务,优先级 [中]
  • 交互队列:用户交互后产生的事件处理任务,优先级 [高]
  • 微队列:如 Promise、MutationObserver、queueMicroTask,优先级 [最高]

如何理解 JS 会阻塞渲染?

其实浏览器的渲染任务也是异步的,如何在执行 JS 脚本的过程修改了 DOM 的信息,那么浏览器也会把这个渲染任务放到消息队列里,等待事件循环机制取调度它。

为什么计时器不能做到精准计时?

受事件循环的影响,计时器的回调函数只能在渲染主线程空闲时运行,主线程在运行时可能有长时的任务,或者其他优先级更高的消息队列先执行完才能去调用延时队列中的计时器任务。

http://www.dtcms.com/a/109280.html

相关文章:

  • CentOS7 安装Redis
  • HTML应用指南:利用POST请求获取三大运营商5G基站位置信息(二)
  • OpenCV第3课 图像的绘制以及基本操作
  • C++:继承+菱形虚拟继承的一箭双雕
  • Could not find artifact com.microsoft.sqlserver:sqljdbc4:jar:4.0 in central
  • 2025年嵌入式大厂春招高频面试真题及解析
  • 使用Deployment运行无状态应用
  • 前缀和 一维差分和二维差分 差分差分矩阵
  • php的动态扩展模块(php的缓存模块)
  • 创建python虚拟环境
  • 记录一下零零散散的的东西-ImageNet
  • 大模型——如何在本地部署微软的OmniParser V2
  • PyTorch复现线性模型
  • 大模型 PDF解析-MinerU
  • 容器适配器-stack栈
  • AV128音乐播放器
  • 【蓝桥杯】每日练习 Day21
  • 基于Transformer框架实现微调后Qwen/DeepSeek模型的非流式批量推理
  • Unity中优化绘制调用整理
  • set和map封装
  • MySQL 基础入门
  • 时间梯度匹配损失 TGMLoss
  • 蓝桥杯 混乘数字
  • 【Cuda 编程思想】手写一个量化反量化算子Quant
  • 反爬的措施有哪些
  • Mock.js虚拟接口
  • 蓝桥杯15届B组题解第二场
  • 记一次防火墙策略设置不当导致连接异常
  • 2.4路径问题专题:LeeCode 931.下降路径最小和
  • Shiro学习(四):Shiro对Session的处理和缓存