浏览器工作原理与实践
李兵
前盛大创新院高级研究员
56402 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 46 讲
浏览器工作原理与实践
15
15
1.0x
00:00/00:00
登录|注册

15 | 消息队列和事件循环:页面是怎么“活”起来的?

JavaScript回调功能
引入微任务
监控DOM节点变化
引入微任务的优势
微任务的定义
线程模型总结
主线程执行过程
Performance页面
解决单个任务执行时长过久的问题
处理高优先级任务
退出线程循环
退出标志变量
页面相关事件
内部消息类型
消息队列设计
渲染进程接收其他进程消息
示例代码
消息队列
线程模型改进
渲染主线程接收其他线程任务
示例代码
引入事件
引入循环机制
任务执行代码示例
任务执行顺序
思考时间
总结
实践:浏览器页面是如何运行的
页面使用单线程的缺点
如何安全退出
消息队列中的任务类型
处理其他进程发送过来的任务
处理其他线程发送过来的任务
在线程运行过程中处理新任务
单线程处理安排好的任务
页面的事件循环系统
消息队列和事件循环系统
消息队列和事件循环系统

该思维导图由 AI 生成,仅供参考

前面我们讲到了每个渲染进程都有一个主线程,并且主线程非常繁忙,既要处理 DOM,又要计算样式,还要处理布局,同时还需要处理 JavaScript 任务以及各种输入事件。要让这么多不同类型的任务在主线程中有条不紊地执行,这就需要一个系统来统筹调度这些任务,这个统筹调度系统就是我们今天要讲的消息队列和事件循环系统。
在写这篇文章之前,我翻阅了大量的资料,却发现没有一篇文章能把消息循环系统给讲清楚的,所以我决定用一篇文章来专门介绍页面的事件循环系统。事件循环非常底层且非常重要,学会它能让你理解页面到底是如何运行的, 所以在本篇文章中,我们会将页面的事件循环给梳理清楚、讲透彻。
为了能让你更加深刻地理解事件循环机制,我们就从最简单的场景来分析,然后带你一步步了解浏览器页面主线程是如何运作的。
需要说明的是,文章中的代码我会采用 C++ 来示范。如果你不熟悉 C++,也没有关系,这里并没有涉及到任何复杂的知识点,只要你了解 JavaScript 或 Python,你就会看懂。

使用单线程处理安排好的任务

我们先从最简单的场景讲起,比如有如下一系列的任务:
任务 1:1+2
任务 2:20/5
任务 3:7*8
任务 4:打印出任务 1、任务 2、任务 3 的运算结果
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了消息队列和事件循环系统在页面活动中的关键作用。文章首先介绍了单线程处理任务的方式,然后详细讲解了事件循环机制在线程运行过程中处理新任务的方式。接着,文章引入了消息队列的概念,并通过代码示例展示了消息队列的实现。此外,还探讨了处理其他线程和进程发送过来的任务以及消息队列中的任务类型。最后,文章提到了如何安全退出页面主线程。整体来说,本文深入浅出地介绍了页面的事件循环系统,对于想深入了解页面运行机制的读者来说,是一篇值得阅读的文章。 文章中还介绍了如何处理高优先级任务和解决单个任务执行时长过久的问题,以及浏览器页面的运行实践。通过实例和图表,读者可以清晰了解浏览器页面的执行过程和任务处理方式。最后,文章总结了不同版本的线程模型和消息队列的设计,以及引入微任务的优势。 总的来说,本文内容涵盖了消息队列、事件循环系统和页面运行机制的重要内容,对于技术人员来说具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《浏览器工作原理与实践》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(111)

  • 最新
  • 精选
  • 肥嘟嘟左卫门
    老师,我感觉最近学起来很迷茫。我本身是非计算机专业的,转行前端将近一年,也能照搬代码去干活,但是总感觉很多东西不通,整个就是一个闭塞的状态,于是我把今年的目标定为恶补计算机基础知识,然后我就找计算机网络方面的知识,浏览器方面的,也包括您的这个专栏,并且也结合着极客时间另外一个关于http的专栏,感觉看的时候好像是懂了(其实我也知道也只是停留在我这个知识层面的“懂了”),会有那种原来平时工作时候他们说的那些概念是这样的意思,也会觉得曾经觉得很难得东西,一下子就通了的感觉,但是另一边我又发现一个问题就是看到现在,像之前专栏讲的我就忘了,平时打通的点也都没有太多印象。我有点迷茫了,我不知道是不是因为我实操太少了,平时遇到的问题太少,所以在学这些的时候会印象不深刻。难道我现在应该把更多的精力放在框架的使用,不停的写代码,而不是基础上吗?

    作者回复: 首先我的观点是工作和知识体系的构建都是重要的,这两者向铺相成。 所以学习过程也是停不下来的,基础知识的学习不要间断。 工作是实践的好机会,但是在工作中你涉及到内容通常会限定在一个很窄的领域,要想通过工作拓宽自己的知识边界,那该如何突破呢? 我是这样做: 把工作中的项目看成是一个探险游戏,游戏中有你熟悉的领域,也有你不熟悉的领域,通常你所做的工作都是在你最熟悉的领域。 不过我还会做另外一件事,就是把游戏地图画出来,画地图的过程也就是全面熟悉项目架构的过程,其中可能涉及到很多你不熟悉的领域,然后你要做的事逐步拓宽这张地图! 当然人的精力是有限的,所以搭建知识架构很重要,然后再找几个领域深耕。

    2019-09-09
    10
    164
  • 易儿易
    宏任务是开会分配的工作内容,微任务是工作过程中被临时安排的内容,可以这么比喻吗?

    作者回复: 这个比喻形象

    2019-09-08
    3
    146
  • 拖鞋
    老师请教个问题 用CSS3实现动画是不是不会影响主线程,和用JS实现动画会影响主线程,这个说法对么

    作者回复: 是这样的,部分css3的动画效果是在合成线程上实现的,不需要主线程介入,所以省去了重拍和重绘的过程,这就大大提升了渲染效率。 JavaScript都是在在主线程上执行的,所以JavaScript的动画需要主线程的参与,所以效率会大打折扣!

    2019-09-16
    89
  • 阿桐
    老师,为什么说页面是单线程架构? 默认情况下每个标签页都会配套一个渲染进程,而一个渲染进程里不是有主线程、合成线程、IO线程等多个线程吗 是因为【排版引擎 blink】 和【JavaScript引擎 v8】都工作在渲染进程的主线程上并且是互斥的,基于这点说页面是单线程架构?

    作者回复: 是的,他们都是在渲染进程的主线程上工作,所以同时只能执行一个。 比如v8除了在主线程上执行JavaScript代码之外,还会在主线程上执行垃圾回收,所以执行垃圾回收时停止主线程上的所有任务,我们把垃圾回收这个特性叫着全停顿。

    2019-09-22
    49
  • mfist
    微任务的本质结合消息队列和事件循环我理解:当事件循环接受到消息时候,判断是否是优先级高的任务,选择插入消息队列的位置不同,进而影响消息执行的顺序。 很期待通过js回调方式解决一次执行很长js带来的页面卡顿的问题。 今日总结 为了应对渲染进程主线程繁琐的任务(DOM解析、样式计算、布局、处理js任务、各种输入事件),引入了消息队列和事件循环系统。 从任务的复杂度逐渐增加,循序渐进的分析每种场景的处理方式。 1. 单线程处理安排好的同步任务 2. 引入事件循环接受新的任务 3. 引入消息队列处理其他进程发来的任务 4. 引入宏任务和微任务解决任务优先级的问题 5. 通过Js回调功能解决单个js任务执行时间过长的问题。

    作者回复: 你对微任务的理解还是有些偏差的! 每个宏任务都有一个微任务列表,在宏任务的执行过程中产生微任务会被添加到改列表中,等宏任务快执行结束之后,会执行微认为列表,所以微任务依然运行在当前宏任务的执行环境中,这个特性会导致宏任务和微任务有一些本质上的区别!我们后面再介绍,你可以重点关注下。

    2019-09-07
    13
    38
  • 六个周
    由于是多个线程操作同一个消息队列,所以在添加任务和取出任务时还会加上一个同步锁。 请问老师,JS执行不是单线程的吗?为什么这里会说是由多个线程操作同一个队列?

    作者回复: 这里提到的任务是指浏览器所以需要处理的任务! 浏览器是基于多进程+多线程架构的,所以多进程通讯(IPC)和多线程同步的问题! 因为JavaScript引擎是运行在渲染进程的主线程上的,所以我们说JavaScript是单线程执行的!

    2019-11-25
    5
    32
  • 蚂蚁内推+v
    老师,请问浏览器的事件循环和js event loop是一回事吗?

    作者回复: JavaScript没有自己循环系统,它依赖的就是浏览器的循环系统,也就是渲染进程提供的循环系统! 所以可以说是一回事

    2019-12-20
    23
  • L-Chris
    事件循环的本质是for循环,循环不会一直迭代导致主线程卡主吗?

    作者回复: 不会,实际过程中采用系统级中断机制,也就是有事件时,线程才会被激活,没事件时,线程就会被挂起

    2020-05-14
    17
  • Rapheal
    老师,可以请问下:渲染进程的主线程和V8执行机主线程是同一个线程吗?一个渲染进程有几个线程,分别有啥作用?

    作者回复: 主要有IO线程,用开负责和其它进程IPC通信的,然后主线程主要跑页面的! V8是在主线程上执行的,因为dom操作啥的都是在主线程上执行的。 当然还有其它很多辅助线程,比如预解析DOM的线程,垃圾回收也有一些辅助线程。

    2019-09-08
    13
  • 阿段
    每一个宏任务都有一个微任务队列?还是整个任务队列有一个微任务队列?

    作者回复: 每个宏任务都有微任务队列

    2019-09-19
    3
    7
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部