Gahing's blog Gahing's blog
首页
知识体系
  • 前端基础
  • 应用框架
  • 工程能力
  • 应用基础
  • 专业领域
  • 业务场景
  • 前端晋升 (opens new window)
  • Git
  • 网络基础
  • 算法
  • 数据结构
  • 编程范式
  • 编解码
  • Linux
  • AIGC
  • 其他领域

    • 客户端
    • 服务端
    • 产品设计
软素质
  • 面试经验
  • 人生总结
  • 个人简历
  • 知识卡片
  • 灵感记录
  • 实用技巧
  • 知识科普
  • 友情链接
  • 美食推荐 (opens new window)
  • 收藏夹

    • 优质前端信息源 (opens new window)
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Gahing / francecil

To be best
首页
知识体系
  • 前端基础
  • 应用框架
  • 工程能力
  • 应用基础
  • 专业领域
  • 业务场景
  • 前端晋升 (opens new window)
  • Git
  • 网络基础
  • 算法
  • 数据结构
  • 编程范式
  • 编解码
  • Linux
  • AIGC
  • 其他领域

    • 客户端
    • 服务端
    • 产品设计
软素质
  • 面试经验
  • 人生总结
  • 个人简历
  • 知识卡片
  • 灵感记录
  • 实用技巧
  • 知识科普
  • 友情链接
  • 美食推荐 (opens new window)
  • 收藏夹

    • 优质前端信息源 (opens new window)
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 前端基础

    • 编程语言

    • 开发工具

    • 前端调试

    • 浏览器原理

      • V8 执行引擎

      • 渲染机制

        • Edge 浏览器在亚像素宽度计算的表现差异
        • 从输入url后浏览器发生了什么
        • chromium 资源加载优先级
        • 你不知道的回流与重绘
        • 浅谈合成层
        • 浅谈屏幕刷新与浏览器渲染机制
        • 浅谈现代浏览器渲染过程
        • 精读 Event loops 规范
          • 前言
          • 查找规范
          • 背景知识
            • JavaScript Engine, JavaScript Runtime, Rendering Engine
            • 调用栈
          • 规范
            • 定义
            • 任务队列
            • 处理模型
            • 通用任务源(Generic task sources)
            • 微任务检查点
            • UI Render 阶段
            • 总结
          • Q&A
            • IE 的 event loop
            • 示例1xxx
            • UI rendering 属于 task 么
            • 渲染是同步还是异步的
            • 浏览器渲染时机
            • requestAnimationFrame
          • 参考文档
    • 浏览器生态

  • 应用框架

  • 工程能力

  • 应用基础

  • 专业领域

  • 业务场景

  • 大前端
  • 前端基础
  • 浏览器原理
  • 渲染机制
gahing
2019/12/10
目录

精读 Event loops 规范

# 前言

以前回答别人浏览器中 Event loops 过程的问题时,只懂得说:

  1. 执行一次宏任务;
  2. 执行并清空微任务队列
  3. 回到1

这样说也不算错,直到有一天有人问我, UI Render 属于什么任务,执行时机是什么?这属实把我整蒙圈了,于是就有了本文

本文主要从以下几点入手

  • 查找规范
  • 背景知识
  • 规范的内容和注意事项
  • Q&A

# 查找规范

ECMAScript 中没有定义 Event loops ,根据我的另外一篇文章 通读 HTML Standard ,得知其定义在 HTML 规范中,由 WHATWG 维护

# 背景知识

# JavaScript Engine, JavaScript Runtime, Rendering Engine

先理清几个概念。

  • JavaScript 执行引擎(JavaScript Engine (opens new window)):将 js 脚本转换为可运行的机器代码指令,实现 ECMAScript 标准。常见的执行引擎有 chrome 的 v8 ,Firefox 的 SpiderMonkey 等等。不限于在浏览器中使用,如 Node.js 的 JavaScript 执行引擎也是用的 v8 。

  • JavaScript 运行时环境(JavaScript Runtime): 为 JavaScript 引擎的执行提供一个运行环境,包括解释编译,内存管理,事件循环,使用程序库(如 Web API)等等。JavaScript 引擎的实现完全独立于运行时环境,因此其可以运行于不同的环境,这些运行时环境由宿主程序提供,如浏览器,Node.js,所以有浏览器运行时环境、 Node.js 运行时环境等等。下面用一张图来展示浏览器运行时环境

  • 渲染引擎(Rendering Engine): 用于渲染网页内容,通过共享的 DOM 数据结构与 JavaScript 执行引擎协同工作。常见的有 chrome 的 Blink, Firefox 的 Gecko, Safari 的 WebKit 。渲染引擎还可用于除 Web 浏览器外的应用程序,如电子邮件客户端。

  • 浏览器内核:倾向于只指渲染引擎。

  • 浏览器:包括用户界面、渲染引擎、网络、数据存储、用户界面后端(如 alert)、浏览器引擎(传递用户指令给渲染引擎)、等。好像有点旧?

为什么有的浏览器支持新语法,有的不支持?因为它们的执行引擎不同,并且同种浏览器的不同版本用的执行引擎版本也就不同,比如新版的 chrome 能用 es 新语法而旧版不行

为什么不同浏览器渲染出来的页面样式可能不一样或者它们支持的 css 程度不一样?因为它们的渲染引擎不同

为什么 Node.js 上调用不了 DOM 的 API?因为该 API 由浏览器运行时环境提供,而 Node.js 运行时环境中没有该 API ,类似的也没有 localStorage 等 api

为什么不同浏览器支持的音视频编解码不一样?也是渲染引擎不同的原因。

chrome 的 video 标签会经 Blink 创建 WebMediaPlayer 实例,该 player 将 buffer 传给 FFmpeg 进行解码,然后将解码后数据丢给渲染器对象进行渲染,最后让 video 标签进行播放显示
参考自 从Chrome源码看audio/video流媒体实现 (opens new window)

浏览器运行时, html 规范, event loop

# 调用栈

JavaScript 是单线程的,意味着它只有一个调用栈,同一时间只能执行一个任务。

调用栈也叫执行上下文栈(Execution Context Stack),当调用一个函数时就会产生一个新的执行上下文,并将该执行上下文入栈

JavaScript 执行引擎只会一直执行栈顶的函数,它根本不知道什么是 microTask , event loop 丢给它什么他就执行什么

# 规范

接下来,我们将对 Event loops 规范进行解读,本文的引用部分,均翻译自规范。

规范原文地址 (opens new window)

题外话: 发现 whatwg 有个中文站 (opens new window) ,前面的基础部分可以对照着看,其他的翻译不及时且较为生硬建议看原文

# 定义

为了协调事件,用户交互,脚本,渲染,联网等,用户代理必须使用本节所述的事件循环。每个代理都有一个关联的事件循环。

该标准目前还没有定义何时创建或重用事件循环

窗口事件循环被用于相似源窗口代理,他们之间共享事件循环。

相似源之间切换的处理,没有定义。。

# 任务队列

# 处理模型

# 通用任务源(Generic task sources)

由用户代理根据某种规则去选择一个 task queues ,从该 task queues 中取出队头 task

① The DOM manipulation task source

a/area标签的导航

history 部分操作

某些条件的iframe加载

img的启动和数据更新动画

BroadcastChannel

# 微任务检查点

多个地方,并不只是在任务结束后执行

# UI Render 阶段

rAF 在 ui render 阶段执行

但是 ui render 的执行时机是不可控的

# 总结

每个 event loop 有多个任务队列,每轮 event loop 会根据某种规则去选择一个 task queues,从该 task queues 中取出队头 task 进行执行,而后执行 microTask queue ,再进行页面渲染

# Q&A

# IE 的 event loop

ie 整个浏览器只有一个 event loop ,某个页面死循环了会导致其他页面也崩溃?

# 示例1xxx

q:ssss

平时所说的触发回流是在哪进行的,getBoundingClientRect 触发的回流和 UI render 有什么关系么

a:xxx

# UI rendering 属于 task 么

# 渲染是同步还是异步的

# 浏览器渲染时机

刷新频率, 规范没有规定策略,不同浏览数实现不同

# requestAnimationFrame

在下次重绘之前调用指定的回调函数更新动画

在 UI Render 阶段执行。但是具体在哪轮 event loop 后,由浏览器决定

# 参考文档

  1. Event loops 规范 (opens new window)
  2. Web标准阅读入门之如何使用官网 - 人马座的文章 - 知乎 (opens new window)
  3. 从event loop规范探究javaScript异步及浏览器更新渲染时机 (opens new window)
  4. 跟着 Event loop 规范理解浏览器中的异步机制 (opens new window)
  5. 【朴灵评注】JavaScript 运行机制详解:再谈Event Loop (opens new window)
编辑 (opens new window)
#HTML#精读
上次更新: 2024/09/01, 23:56:56
浅谈现代浏览器渲染过程
定制 devtools-fe

← 浅谈现代浏览器渲染过程 定制 devtools-fe→

最近更新
01
浅谈代码质量与量化指标
08-27
02
快速理解 JS 装饰器
08-26
03
Vue 项目中的 data-v-xxx 是怎么生成的
09-19
更多文章>
Theme by Vdoing | Copyright © 2016-2024 Gahing | 闽ICP备19024221号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式