首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
01 | 函数式vs.面向对象:响应未知和不确定
02 | 如何通过闭包对象管理程序中状态的变化?
03 | 如何通过部分应用和柯里化让函数具象化?
04 | 如何通过组合、管道和reducer让函数抽象化?
05|map、reduce和monad如何围绕值进行操作?
06 | 如何通过模块化、异步和观察做到动态加载?
07 | 深入理解对象的私有和静态属性
08|深入理解继承、Delegation和组合
09|面向对象:通过词法作用域和调用点理解this绑定
10|JS有哪8种数据类型,你需要注意什么?
11|通过JS引擎的堆栈了解闭包原理
12|JS语义分析该用迭代还是递归?
13 | JS引擎如何实现数组的稳定排序?
14 | 通过SparkPlug深入了解调用栈
15 | 如何通过哈希查找JS对象内存地址?
16 | 为什么环形队列适合做Node数据流缓存?
17 | 如何通过链表做LRU/LFU缓存?
18 | TurboFan如何用图做JS编译优化?
19 | 通过树和图看如何在无序中找到路径和秩序
20 | 算法思想:JS中分治、贪心、回溯和动态规划
21 | 创建型:为什么说Redux可以替代单例状态管理
22|结构型:Vue.js如何通过代理实现响应式编程
23 | 结构型:通过jQuery看结构型模式
24 | 行为型:通过观察者、迭代器模式看JS异步回调
25 | 行为型:模版、策略和状态模式有什么区别?
26|特殊型:前端有哪些处理加载和渲染的特殊“模式”?
27|性能:如何理解JavaScript中的并行、并发?
28|性能:通过Orinoco、Jank Busters看垃圾回收
29|网络:从HTTP/1到HTTP/3,你都需要了解什么?
30|安全:JS代码和程序都需要注意哪些安全问题?
31|测试(一):开发到重构中的测试
32|测试(二):功能性测试
33|测试(三):非功能性测试
34|静态类型检查:ESLint语法规则和代码风格的检查
35|Flow:通过Flow类看JS的类型检查
36|包管理和分发:通过NPM做包的管理和分发
37|编译和打包:通过Webpack、Babel做编译和打包
38|语法扩展:通过JSX来做语法扩展
39|Polyfill:通过Polyfill让浏览器提供原生支持
40|微前端:从MVC贫血模式到DDD充血模式
41|大前端:通过一云多端搭建跨PC/移动的平台应用
42|元编程:通过Proxies和Reflect赋能元编程
当前位置:
首页>>
技术小册>>
JavaScript进阶实战
小册名称:JavaScript进阶实战
### 27 | 性能:如何理解JavaScript中的并行、并发? 在深入探讨JavaScript中的并行(Parallelism)与并发(Concurrency)之前,我们需要先明确这两个概念的区别,以及它们为何在JavaScript的性能优化中占据如此重要的地位。尽管JavaScript最初设计为单线程语言,旨在简化Web开发的复杂性,但随着Web应用的日益复杂和性能要求的提高,理解和利用JavaScript中的并行与并发机制变得至关重要。 #### 一、理解并行与并发的概念 **并发(Concurrency)**:指的是两个或多个任务可以在同一时间段内开始执行,但并不意味着它们在同一时刻点上真正同时执行。在并发系统中,任务可以交替执行,使得从外部观察来看,多个任务似乎是在同时进行的。这种交替执行通常由操作系统的时间片轮转机制(Time-slicing)或事件循环(Event Loop)等机制来实现。 **并行(Parallelism)**:则是指两个或多个任务在同一时刻点上真正同时执行,这需要物理上的多核处理器或多个处理器来实现。并行处理能够显著提高程序的执行速度,尤其是在处理大量计算密集型任务时。 #### 二、JavaScript的单线程模型 JavaScript在浏览器和Node.js环境中都是基于事件循环(Event Loop)的单线程模型运行。这意味着JavaScript代码在单个线程中顺序执行,一次只能处理一个任务。然而,这种设计并不妨碍JavaScript实现并发执行的效果,它通过异步编程模式(如回调函数、Promises、async/await等)来模拟并发行为。 - **事件循环**:JavaScript引擎持续运行一个循环,等待和处理来自浏览器或Node.js环境的各种事件(如用户交互、网络请求响应等)。当这些事件发生时,相应的回调函数会被放入调用栈中执行。如果当前任务执行时间过长或遇到阻塞操作(如同步的XMLHttpRequest调用),则会导致整个事件循环阻塞,进而影响页面或应用的响应性。 #### 三、JavaScript中的并发模拟 虽然JavaScript是单线程的,但它通过以下几种方式实现了并发执行的效果: 1. **回调函数(Callbacks)**:最传统的异步编程方式,通过将函数作为参数传递给另一个函数,并在某个操作完成时调用该函数,以实现非阻塞执行。然而,回调函数容易导致“回调地狱”(Callback Hell),使得代码难以阅读和维护。 2. **Promises**:Promises是处理异步操作的一种更强大、更灵活的方式。它代表了一个尚未完成但预期将来会完成的操作的最终结果。Promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。通过使用`.then()`、`.catch()`和`.finally()`等方法,可以优雅地处理异步操作的成功、失败和最终状态。 3. **async/await**:建立在Promises之上的语法糖,使得异步代码看起来和同步代码一样。`async`关键字用于声明一个异步函数,该函数会隐式返回一个Promise。在`async`函数内部,可以使用`await`关键字等待一个Promise的解决,而不会阻塞整个事件循环。`await`只能在`async`函数内部使用。 #### 四、JavaScript中的并行处理 尽管JavaScript引擎本身是单线程的,但现代JavaScript环境(尤其是Node.js)提供了几种方式来实现并行处理: 1. **Web Workers(仅限浏览器环境)**:Web Workers允许你在浏览器后台运行脚本,而不会干扰页面的性能。它们运行在与主线程不同的线程中,可以执行耗时的计算任务,并通过消息传递机制与主线程通信。但请注意,Web Workers无法直接访问DOM,也无法访问全局变量和函数(除非它们被明确传递到Worker中)。 2. **Node.js中的Worker Threads**:Node.js自v10.5.0版本起引入了Worker Threads模块,允许开发者在Node.js环境中创建多个线程来执行JavaScript代码。这对于执行CPU密集型任务特别有用,因为它可以将这些任务分散到多个核心上并行处理,从而提高性能。但请注意,由于Node.js的许多内置模块(如fs、net等)并不是线程安全的,因此在Worker Threads中需要谨慎使用。 3. **子进程(Child Processes)**:在Node.js中,你还可以使用`child_process`模块来创建子进程,这些子进程可以执行不同的脚本或命令,并与父进程进行通信。虽然子进程并不是严格意义上的并行执行(因为它们可能在不同的进程中运行),但它们提供了一种在Node.js应用中执行并发任务的有效方式。 #### 五、性能优化策略 了解并利用JavaScript中的并发与并行机制,对于提升Web应用的性能至关重要。以下是一些性能优化策略: - **减少同步操作**:尽可能使用异步编程模式来避免阻塞事件循环。 - **合理使用Web Workers和Worker Threads**:对于计算密集型任务,考虑使用Web Workers(在浏览器环境)或Worker Threads(在Node.js环境)来并行处理。 - **优化算法和数据结构**:即使在单线程环境中,高效的算法和数据结构也能显著提升性能。 - **利用缓存**:缓存经常访问的数据或结果,以减少重复计算和数据检索的开销。 - **代码分割与懒加载**:对于大型应用,采用代码分割和懒加载技术可以减少初始加载时间,提高用户体验。 #### 六、总结 JavaScript虽然本质上是单线程的,但通过异步编程模式、Web Workers、Worker Threads等技术,我们仍然可以实现高效的并发和并行处理。在编写高性能的JavaScript应用时,深入理解这些概念并合理运用相应的技术和策略至关重要。随着Web技术的不断发展,我们可以期待未来有更多的创新和改进,进一步推动JavaScript在性能优化方面的进步。
上一篇:
26|特殊型:前端有哪些处理加载和渲染的特殊“模式”?
下一篇:
28|性能:通过Orinoco、Jank Busters看垃圾回收
该分类下的相关小册推荐:
剑指javascript-ES6
JavaScript入门与进阶
npm script实战构建前端工作流
Javascript编程指南
ES6入门指南
Flutter核心技术与实战
JavaScript面试指南
剑指javascript
javascript设计模式原理与实战
Javascript重点难点实例精讲(一)
编程入门课:Javascript从入门到实战
经典设计模式Javascript版