页面的渲染流程、渲染阻塞以及JS Event loop

浏览器与Node的事件循环(Event Loop)有何区别? 前言 本文我们将会介绍 JS 实现异步的原理,并且了解了在浏览器和 Node 中 Event Loop 其实是不相同的。 一、线程与进程 1. 概念 我们经常说 JS 是单线程执行的,指的是一个进程里只有一个主线程,那到底什么是线程?什么是进程? 官方的说法是:进程是 CPU 资源分配的最小单位;线程是 CPU 调度的最小单位。这两句话并不好理解,我们先来看张图: 进程好比图中的工厂,有单独的... 阅读详情

从输入URL到页面渲染过程

首先简单了解一下浏览器请求、加载、渲染一个页面的大致过程:

  • DNS 查询
  • TCP 连接
  • HTTP 请求
  • 服务器响应
  • 客户端渲染

至于客户端渲染之前更具体的说明,👉浏览器导航过程发生了什么?(Chrome)

页面渲染流程

旧版webkit内核浏览器渲染流程图(其他的也大同小异):

在这里插入图片描述

渲染大概可以划分成以下几个步骤:

  • 解析html建立DOM树(深度遍历)
  • 将CSS解析成 CSSOM树
  • 根据DOM树和CSSOM树来构造 Render树
  • 布局render树,负责各元素尺寸、位置的计算
  • 绘制render树,绘制页面像素信息
  • 浏览器会将各层的信息发送给GPU,GPU会将各层合成,显示在屏幕上。

📌上述这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有的html都解析完成之后再去构建和布局render树。它是解析完某一部分(整体大块的)内容就显示一部分内容,同时,可能还在通过网络下载其余内容。

更清晰了解构建渲染树:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Demos</title>
    <style>
        body {font-size: 16px;}
        p {color: red;}
        p span {display:none;}
        span {font-size: 14px;}
        img {float: right;}
    </style>
</head>
<body>
    <p>Hello <span>berwin</span></p>
    <span>Berwin</span>
    <img src="https://p1.ssl.qhimg.com/t0195d63bab739ec084.png" />
</body>
</html>

这段代码构建渲染树图:
在这里插入图片描述

渲染进程里面的线程(浏览器内核)

  • GUI渲染线程

    1. 解析HTML,CSS,构建DOM树和Render树,布局和绘制等
    2. repaint/reflow
    3. GUI渲染线程与JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起,GUI的更新会被保存在一个队列中等到JS引擎空闲时立即被执行。
  • JS引擎线程

    1. 解析Javascript脚本,单线程执行
    2. 与GUI互斥,GUI ON then JS Suspend.等待着任务队列中任务的到来,然后加以处理,JS执行的时间过长会导致页面渲染加载阻塞
  • 事件触发线程

    1. 归属于浏览器而不是JS引擎,用来控制事件循环。(这货是与浏览器进程交互的而非JS引擎)
    2. 当JS引擎执行代码块如click事件时(也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件待处理队列的队尾,等待JS引擎的处理
  • 定时触发器线程

    1. setInterval与setTimeout所在线程
    2. 浏览器定时计数器并不是由JS引擎计数的,因为JavaScript引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确
    3. 计时完毕后,将事件添加到事件队列中,等待JS引擎空闲后执行
  • 异步http请求线程

    1. 在XMLHttpRequest在连接后是通过浏览器新开一个线程请求
    2. 将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中。再由JavaScript引擎执行。

浏览器内核中线程之间的关系

  • GUI渲染线程与JS引擎线程互斥
    由于JavaScript是可操纵DOM的,如果在修改这些元素属性同时渲染界面(即JS线程和UI线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。当JS引擎执行时GUI线程会被挂起,GUI更新则会被保存在一个队列中等到JS引擎线程空闲时GUI线程就执行队列中的UI更新。

  • JS阻塞页面加载
    从上述的互斥关系,可以推导出,JS如果执行时间过长就会阻塞页面,自然会感觉到页面卡顿。

如何解决JS执行时间过长带来的问题?

Web Worker为Web内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面一个worker是使用一个构造函数创建的一个对象(e.g. Worker()) 运行一个命名的JavaScript文件 这个文件包含将在工作线程中运行的代码; workers 运行在另一个全局上下文中,不同于当前的window因此,使用 window快捷方式获取当前全局的范围 (而不是self) 在一个 Worker 内将返回错误。主要用来处理大运算量问题。

  • 创建Worker时,JS引擎向浏览器申请开一个子线程,子线程是浏览器开的,完全受JS主线程控制,而且不能操作DOM,该线程拥有JS执行环境
  • JS引擎线程与worker线程间通过特定的方式通信(postMessage API,需要通过序列化对象来与线程交互特定的数据)

📌拓展:WebWorker与SharedWorker

  • WebWorker只属于某个页面,不会和其他页面的Render进程(浏览器内核进程)共享。
    Chrome在Render进程中创建一个新的线程来运行Worker中的JavaScript程序。
  • SharedWorker是浏览器所有页面共享的,不能采用与Worker同样的方式实现,因为它不隶属于某个Render进程,可以为多个Render进程共享使用。
    Chrome浏览器为SharedWorker单独创建一个进程来运行JavaScript程序,在浏览器中每个相同的JavaScript只存在一个SharedWorker进程,不管它被创建多少次。

本质上就是进程和线程的区别。SharedWorker由独立的进程管理,WebWorker只是属于render进程下的一个线程。

渲染阻塞资源

现代浏览器总是并行加载资源,例如,当 HTML 解析器(HTML Parser)被脚本阻塞时,解析器虽然会停止构建 DOM,但仍会识别该脚本后面的资源,并进行预加载。

阻塞资源分类

  • CSS与JS都被视为渲染阻塞资源 ,浏览器会等到CSSOM 构建完毕,才会进入下一阶段(合成渲染树)。

  • JavaScript 被认为是解析器阻塞资源,JS会阻塞HTML解析。

阻塞资源之间的影响

  • 存在阻塞的 CSS 资源时,浏览器会延迟 JavaScript 的执行和 DOM 构建。

  • 当浏览器遇到一个 <script>标记时,DOM 构建将暂停,直至脚本完成执行。

  • JavaScript 可以查询和修改 DOM 与 CSSOM。

  • CSSOM 构建时,JavaScript 执行将暂停,直至 CSSOM 就绪。

所以,script 标签的位置很重要。

script 标签该放在哪

实际使用时,可以遵循下面两个原则:

  1. CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源。(通常会把css放在头部,js放在body尾,不然js先操作修改DOM节点样式,之后css重新渲染该节点样式,导致渲染效果与预期不一致)

  2. JavaScript 应尽量少影响 DOM 的构建。

css加载是否会阻塞dom树加载?

<link> 标签(或是内联样式或行内样式)会被视为阻塞渲染的资源,浏览器会优先处理这些 CSS 资源,直至 CSSOM 构建完毕。

<link> 引入的css文件是由单独的下载线程异步下载的。

css加载不会阻塞DOM树的解析

CSS 的加载和解析并不会阻塞 DOM Tree 的构建,因为 DOM Tree 和 CSSOM Tree 是两棵相互独立的树结构。

css加载会阻塞DOM树的渲染

构建渲染树同时依赖CSSOM树和DOM树。在没有处理完 CSS 之前,文档是不会在页面上显示出来的,这个策略的好处在于页面不会重复渲染;如果 DOM Tree 构建完毕直接渲染,这时显示的是一个原始的样式,等待 CSSOM Tree 构建完毕,再重新渲染又会突然变成另外一个模样,除了开销变大之外,用户体验也是相当差劲的。

css加载会阻塞后面js语句的执行

如果js先操作修改DOM节点样式,之后css重新渲染该节点样式,导致渲染效果与预期不一致

内联样式和嵌入样式可以减少页面请求,为什么还要使用link外联样式呢?

在构建 DOM Tree 的过程中,如果遇到 link 标记,浏览器就会立即发送请求获取样式文件。

当然我们也可以直接使用内联样式或嵌入样式,来减少请求;但是会失去模块化和可维护性,并且像缓存和其他一些优化措施也无效了,利大于弊,性价比实在太低了;除非是为了极致优化首页加载等操作,否则不推荐这样做。

异步加载脚本 defer与asysn

解析过程中无论遇到的JavaScript是内联还是外联,只要浏览器遇到 <script> 标记,就会唤醒 JavaScript解析器,并暂停解析HTML,并等待 CSSOM 构建完毕,才去执行js脚本。

因为脚本中可能会操作DOM元素,而如果在加载执行脚本的时候DOM元素并没有被解析,脚本就会因为DOM元素没有生成取不到响应元素,但由于JavaScript可以修改CSSOM,所以需要等CSSOM构建完毕后再执行JS。

在实际工程中,我们常常将脚本资源放到文档底部。

defer与async这两个属性会使 <script> 异步加载,只针对外联脚本,对于inline-script是无效的。

在这里插入图片描述

defer

defer 属性会开启新的线程下载脚本文件并延迟执行引入 的JavaScript脚本,即 JavaScript 脚本加载时 HTML 并未停止解析,这两个过程是并行的。

如果声明了多个defer的脚本,则会按顺序下载并在整个 document 解析完毕且 defer-script 也加载完成之后按顺序执行,defer脚本会在DOMContentLoaded之后和load事件之前执行。

async

async 属性表示异步执行引入的 JavaScript,与 defer 的区别在于,如果已经加载好,就会开始执行,无论此刻是 HTML 解析阶段还是 DOMContentLoaded 触发(HTML解析完成事件)之后,但一定在 load 触发之前执行。

声明了多个async的脚本,其下载和执行都是异步的,不能确保彼此的先后顺序。

值得注意的是,通过js向 document 动态添加 script 标签时,async 属性默认是 true。

📌了解更多关于阻塞资源的信息:优化关键渲染路径

从Event Loop谈JS的运行机制

注意,这里不谈可执行上下文,VO,scop chain等概念,这里主要是结合Event Loop来谈JS代码是如何执行的。

事件循环机制

  • JS分为同步任务和异步任务
  • 同步任务都在主线程上执行,形成一个执行栈
  • 主线程之外,事件触发线程管理着一个任务队列,只要异步任务有了运行结果,就在任务队列之中放置一个事件。
  • 一旦执行栈中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。
    在这里插入图片描述

看到这里,应该就可以理解了:为什么有时候setTimeout推入的事件不能准时执行?因为可能在它推入到事件列表时,主线程还不空闲,正在执行其它代码,所以自然有误差。

拓展:聊一聊定时器

什么时候会用到定时器线程?当使用setTimeout或setInterval时,它需要定时器线程计时,计时完成后就会将特定的事件推入事件队列中。

setTimeout(function(){
    console.log('hello!');
}, 1000);

这段代码的作用是当1000毫秒计时完毕后(由定时器线程计时),将回调函数推入事件队列中,等待主线程执行。

setTimeout(function(){
    console.log('hello!');
}, 0);

console.log('begin');

这段代码的效果是最快的时间内将回调函数推入事件队列中,等待主线程执行。

执行结果是:先begin后hello!

虽然代码的本意是0毫秒后就推入事件队列,但是W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms。

(不过也有一说是不同浏览器有不同的最小时间设定)

就算不等待4ms,就算假设0毫秒就推入事件队列,也会先执行begin(因为只有可执行栈内空了后才会主动读取事件队列)

事件循环进阶:宏任务(macrotask)与微任务(microtask)

上述JS事件循环机制梳理了一遍,在ES5的情况是够用了,但是在ES6盛行的现在,仍然会遇到一些问题,譬如下面这题:

let p =new Promise((resolve,reject)=>{
	console.log('before resolve');
	resolve('resolve')
	console.log('after resolve');
}).then(r=>{
	console.log(r);
})

setTimeout(()=>{
	console.log('setTimeout');
},0)

console.log("全局代码块");

在这里插入图片描述

Promise实例创建就会执行。
resolved 的 Promise 是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。
setTimeout是宏任务,会再下一轮循环执行。

JS中分为两种任务类型:macrotask(宏任务)和microtask(微任务)。在ECMAScript中,macrotask称为task,microtask称为jobs。

macrotask

macrotask 可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)

  • 每一个task会从头到尾将这个任务执行完毕,不会执行其它。
  • 浏览器为了能够使得JS内部task与DOM任务能够有序的执行,会在一个task执行结束后,在下一个 task 执行开始前,对页面进行重新渲染
microtask

microtask 可以理解是在当前 task 执行结束后立即执行的任务

  • 在当前task任务后,下一个task之前,在渲染之前
  • 它的响应速度相比setTimeout(setTimeout是task)会更快,因为无需等渲染
    也就是说,在某一个macrotask执行完后,就会将在它执行期间产生的所有microtask都执行完毕(在渲染前)

📌哪些任务属于macrotask或microtask呢?

  • macrotask:主代码块,setTimeout,setInterval等(可以看到,事件队列中的每一个事件都是一个macrotask)
  • microtask:Promise(不是新建实例的情况下),process.nextTick等

补充:在node环境下,process.nextTick的优先级高于Promise,也就是可以简单理解为:在宏任务结束后会先执行微任务队列中的nextTickQueue部分,然后才会执行微任务中的Promise部分。

再根据线程来理解下:

  • macrotask中的事件都是放在一个事件队列中的,而这个队列由事件触发线程维护
  • microtask中的所有微任务都是添加到微任务队列(Job Queues)中,等待当前macrotask执行完毕后执行,而这个队列由JS引擎线程维护

总结下运行机制:

  1. 执行一个宏任务(栈中没有就从事件队列中获取)
  2. 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
  3. 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
  4. 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
  5. 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取)
    在这里插入图片描述

另外,请注意下Promise的polyfill与官方版本的区别:

  • 官方版本中,是标准的microtask形式
  • polyfill,一般都是通过setTimeout模拟的,所以是macrotask形式

请特别注意这两点区别:

有一些浏览器执行结果不一样(因为它们可能把microtask当成macrotask来执行了),但是为了简单,这里不描述一些不标准的浏览器下的场景(但记住,有些浏览器可能并不标准)

========================================================================================================

参看文档:
浏览器渲染原理及流程
从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理
四步带你吃透浏览器渲染基本原理
一文看懂Chrome浏览器运行机制

Vue学习记录之十九 Event Loop,宏任务和微任务 当一个宏任务执行完毕后,会检查是否有微任务队列,如果有,则将微任务队列中的所有任务依次执行完毕,然后再继续选择下一个宏任务执行。这样的过程循环进行,形成了事件循环。微任务通常在宏任务执行完毕后立即执行,因此微任务具有更高的优先级,可以在页面渲染前执行,从而提供更好的用户体验。微任务的优先级高于宏任务,因此微任务会在本轮宏任务执行结束后立即执行,而不是等到下一个事件循环。按顺序执行, 同步任务直接执行,异步任务进入异步队列,执行完以后,在进行入异步列队,然后在看是同步还是异步任务,如此循环执行。 阅读详情

相关推荐

Codex辅助小说创作:零成本AI写作指南与实战技巧

自然语言处理技术通过深度学习模型理解语义上下文,其核心原理是基于大规模文本训练的语言模型预测能力。在创意写作领域,这项技术的价值在于突破传统写作工具的功能局限,实现从内容生成到风格模仿的智能化辅助。特别是提示词工程的应用,让创作者能够精准控制AI输出的内容和风格。在实际应用场景中,AI写作工具显著降低了小说创作门槛,适用于网络小说、奇幻科幻等多种文学类型。本文以OpenAI Codex为例,详细解析如何利用AI技术完成从故事大纲设计、章节生成到平台发布的全流程创作,其中提示词优化和内容质量把控是提升生成效果

weixin_32678995的博客 561

常看:vue面试相关知识

vue常识

weixin_41127362的博客 1335

美团外卖 mtgsig 1.2 逆向工程与补环境实战指南

本文深入解析了美团外卖核心风控参数mtgsig 1.2的生成机制与逆向实战。通过拆解其复杂的JSON结构,揭示了设备指纹、环境信息加密等关键字段。重点阐述了在Node.js中模拟浏览器环境(补环境)的核心方法,包括DOM/BOM对象、本地存储及Canvas/WebGL等高级指纹的模拟技巧,为安全研究和合规自动化测试提供了一套完整的技术指南。

uber9的博客 409

浏览器多进程,浏览器渲染(回流与重绘),JS运行机制(宏任务与微任务的解读 eventLoop)

当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。

qq_34455363的博客 379

QT播放器插件内嵌浏览器配合流媒体实现国标摄像头网页端播放

基本原理在浏览器⽹页中的指定播放窗口的位置和⼤⼩,实现⼀个内嵌到⽹页中显⽰的播放窗⼝,前端还必须可对这个内嵌播放窗⼝进⾏控制,⽽且播放窗⼝必须跟随浏览器窗⼝的移动和缩放、⽹页滚动、标签页切换、关闭等操作进⾏⾃动联动。播放器可以通过QT实现。这个播放窗⼝同时提供Web Socket的服务端和JSON打包命令的解析执⾏模块,前端就可以通过Web Socket连接后发送JSON打包的控制命令实现控制播放窗⼝。

cameravision的博客 562

最全卷积总结篇(分组、深度可分离、空洞、转置等)

分组卷积(Group Convolution)是一种卷积操作方式,它最早在AlexNet中引入,并在深度学习中被广泛使用,尤其是在高效模型设计(如MobileNet和ResNeXt)中。分组卷积通过将输入特征通道分为若干组,并在每组内单独进行卷积操作,可以减少计算复杂度和参数量,同时有效利用模型的结构特性。分组卷积的工作原理通道分组:输入特征图的通道图为C_in,输出特征图的通道数为C_out,将每组的C_in和C_out分为G组,每组的通道数为C_in/G和C_out/G。组内卷积。

qq_44815135的博客 4218

解决:<img>图片地址访问不通时,导致 <img>标签后面的DOM渲染

解决:图片地址访问不通时,导致 标签后面的DOM渲染

pig_ning的博客 358

车载面试题目(ADAS)

多数功能都是依靠的前置传感器(经过Lidar、Radar、Camera融合),比如ACC、AEB、LKA、NOA、TJA、FCW等,只有少数涉及周视传感器,比如BSD、CVW、DOW。③如果前面有车切速度小于自车车速,自车减速对减速度有要求,比如3.5m/m2,④如果前车静止了,自车有个跟停距离要求,比如2-3m。试验场有不同曲率的弯道,比如125m、250m、500m的,根据需求跟车行驶,看是否会减速,能不能驶出弯道等。迭代内容:底层通讯、网络管理、诊断、刷写、信息安全、OTA。

qq_43475097的博客 2297

浏览器页面--阻塞渲染--场景/优化方案

本文介绍浏览器的页面的渲染阻塞的场景及其优化方案。 CSS和JavaScript都会阻塞浏览器的渲染,本文分这两个方面介绍。

IT利刃出鞘的博客 1957

流媒体学习之路(mediasoup)——simulcast 与 svc 简介(7)

流媒体学习之路(mediasoup)——simulcast 与 svc(7) 文章目录流媒体学习之路(mediasoup)——simulcast 与 svc(7)

qw225967的博客 7339

【C语言】一文搞懂C语言文件操作

读写文件、文件相关库函数详解、文件缓冲区介绍

StackFrame 5657

根据浏览器渲染界面原理理解渲染阻塞、浏览器的重绘(repaints)与回流(reflows)...

前面有讲到当用户在浏览器输入url之后,经过一系列的过程,会最终向服务器请求到文档数据,文档数据请求到之后,浏览器会将这些数据传给浏览器渲染引擎,渲染引擎开始正式工作了。 构建dom树,解析css 首先浏览器接收到html文档,就会把HTML在内存中转换成DOM树,HTML中的每个tag都是DOM树中的1个节点,根节点就是我们常用的doc...

weixin_33811539的博客 402

【OpenAI】Python:(1) 基于 Gym-CarRacing 的自动驾驶项目 | 前置知识介绍 | 项目环境准备 | 手把手带你一步步实现

本篇是关于多伦多大学自动驾驶专业项目 Gym-CarRacing 的博客。GYM-Box2D CarRacing 是一种在 OpenAI Gym 平台上开发和比较强化学习算法的模拟环境。它是流行的 Box2D 物理引擎的一个版本,经过修改以支持模拟汽车在赛道上行驶的物理过程。由于内容比较多所以分多次更新,本篇是关于前置知识介绍,以及项目环境准备的。

有道无术, 术尚可求。有术无道, 止于术。 5053

前端进阶-js面试点

asyncdefer。

m0_56770663的博客 189

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

深入剖析JavaScript中的Event Loop机制:异步编程的基石

本文深入解析JavaScript的Event Loop机制,阐述其如何协调单线程环境下的异步任务处理。Event Loop通过调用栈、宏任务队列(如setTimeout)和微任务队列(如Promise.then)的协同工作,确保异步任务有序执行而不阻塞主线程。文章结合实际代码示例,说明定时器、Promise和异步API的执行顺序,并指出过多微任务或不当定时器使用可能导致的性能问题,提出优化建议。理解Event Loop对编写高效异步代码至关重要,能显著提升Web应用性能与用户体验。

你若盛开,清风自来 1973

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

JavaScript之彻底学会Event Loop

前言 学习JavaScript执行机制能更好的理解JavaScript的代码执行顺序,进而更好的理解JavaScript的异步模式。 Event Loop即事件循环,是浏览器或Node解决单线程运行时不会阻塞的一种机制。(也可以理解为经常使用的异步) 在正式学习Event Loop之前,先提出几个问题: 什么是同步与异步? JavaScript是一门单线程语言,那如何实现异步? 同步任务和异步任务的执行顺序如何? 异步任务是否存在优先级? 同步与异步 计算机领域中的同步与异步和我们现实社会的同步和异

战场小包的博客 2445

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

认识Event Loop【1】

这应该是一个系列文章,因为我觉得Event Loop(事件循环)是一件很抽象也很重要的一个机制。eventloop这个知识点处于非常杂糅的位置,和很多其他知识,如运行时、浏览器、渲染流程、数据结构、线程等等,也是正确理解JS异步编程的核心。所以很值得展开来娓娓道来。⚠️强烈建议学完JS异步语法知识后再来学习EventLoop。

2301_80272161的博客 1006

深入理解 JavaScript 异步编程:从 Event Loop 到 Promise

本文系统解析JavaScript异步编程机制,从底层原理到应用实践。首先阐述进程/线程概念,指出JS单线程特性与浏览器多线程支持的关系。重点剖析EventLoop事件循环机制,详解同步/异步任务处理流程及宏任务/微任务优先级。深入讲解Promise核心特性、链式调用和静态方法,并给出手写实现代码。最后介绍async/await语法糖的工作原理。全文构建了从浏览器底层到上层API的完整异步知识体系,帮助开发者彻底掌握JS异步编程精髓。

一位搞嵌入式和前端的genius的博客 861

JavaScript进阶指南之Event Loop

JavaScript进阶指南之Event Loop

fanchen4139的博客 1421

浏览器环境下的JavaScript Event Loop

浏览器环境下的JavaScript Event Loop 正文从这开始~~ 什么是JavaScript的Event Loop? 在JavaScript中有一个很重要的Event Loop概念,从字面意思理解为事件循环,为什么会有Event Loop这个概念呢?我们得先从JavaScript语言的特征说起。 细心的读者可能发现了,文章的标题中我们着重强调了是在浏览器环境,这是为什么呢? 因为JavaScript的Event Loop不仅存在于浏览器环境下,还存在于Node环境下,而且两者还存在一些差别。 本

hkw20的博客 228

JS中的Event Loop 事件循环机制

同步任务都在主线程(JS引擎线程)上执行,形成一个执行栈。 主线程之外,事件触发线程管理着一个任务队列,异步任务有运行结果时,就将事件回调放入任务队列。 执行栈中的同步任务执行完毕,JS引擎线程就会读取任务队列,添加到执行栈中,开始执行。...

VanCzech的博客 522

一次弄懂Event Loop

Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。堆是一种数据结构,是利用完全二叉树维护的一组数据,堆分为两种,一种为最大堆,一种为最小堆,将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。堆是线性数据结构,相当于一维数组,有唯一后继。如最大堆 栈在计算机科学中是限定仅在表尾进行插入或删除操作的线性表。栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要

efew212efe的博客 1276

深入理解JavaScript的事件循环(Event Loop)

本文深入解析JavaScript事件循环机制,比较了浏览器和Node环境下的不同实现。浏览器基于HTML5规范,Node基于libuv库,两者在宏任务(macrotask)和微任务(microtask)处理上存在差异

fjlljf00的专栏 2116

深入理解JavaScript Event Loop:异步编程与性能优化的核心机制

在计算机科学中,并发模型是处理多任务的核心机制,它决定了程序如何高效地执行。JavaScript采用单线程事件驱动模型,通过Event Loop实现非阻塞异步操作。其原理基于调用栈、任务队列和微任务队列的协同工作:主线程执行同步代码,异步回调被放入队列,Event Loop循环调度确保任务有序执行。这一机制的技术价值在于,它使得单线程JavaScript能够处理高并发I/O操作,避免界面卡顿,提升用户体验。在应用场景上,Event Loop是理解现代前端框架如Vue的nextTick、React调度器的基础

weixin_31742871的博客 243

【JS】Event loop、宏队列与微队列

JS 是门非阻塞单线程语言,因为在最初 JS 就是为了和浏览器交互而诞生的。如果 JS 是门多线程的语言话,我们在多个线程中处理 DOM 就可能会发生问题(一个线程中新加节点,另一个线程中删除节点),当然可以引入读写锁解决这个问题。参考 所以需要对异步代码进行特殊的处理才行 macrotask(宏任务) 在浏览器端,其可以理解为该任务执行完后,在下一个macrotask执行开始前,浏览器可以进行页面渲染。(对应了上一篇文章讲的script代码执行完成后,在执行下一段script代码前,页面渲染了之前的dom

Voiceu的博客 510

JavaScript运行机制:Event Loop

JavaScript运行机制:Event Loop 注:对阮一峰老师的JavaScript 运行机制详解:再谈Event Loop,做的学习笔记 1. 为什么JavaScript是单线程的 先来了解一下进程和线程这两个概念 比喻 进程就是一个公司,每个公司都有自己的资源可以调度;公司之间是独立的;线程就是公司里的每一个员工,多个员工一起合作,完成任务,公司可以有一名员工或多个,员工之间共享公司的空间 什么是进程 进程:是cpu分配资源的最小单位;(是能拥有资源和独立运行的最小单位) 什么是线程 线程:是c

weixin_45663697的博客 1133
上一篇: HTTP知识点收录
下一篇: 优化关键渲染路径(如何缩短页面首绘时长)
Free Joe
博客等级 码龄6年 434粉丝 79原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值