首页 / 文章 / 为什么 pnpm 的安装速度比 npm 更快:缓存、链接与严格的 node_modules 管理

为什么 pnpm 的安装速度比 npm 更快:缓存、链接与严格的 node_modules 管理

pnpm 通过使用内容可寻址存储、硬链接而非复制文件,以及严格管理的 symlinked node_modules 结构来避免昂贵的代码提升操作,因此在安装速度上优于 npm。

774 词

将仓库从 npm 移动到 pnpm 后,安装时间通常会显著缩短。这一差异并非想象所致。pnpm 是为解决传统 npm 安装过程中的性能与存储问题而设计的,两者存储包的方式存在巨大差异,因此速度上的提升是架构层面的改变,而非微小的调整。

以下内容将详细说明为何 pnpm 更具优势,尤其是在应用和单仓库项目规模变大时。

1. 基于内容寻址的存储方式,而非重复文件

其核心优势体现在包在磁盘上的存储方式上。使用 npm 时,每个项目都会在 node_modules 下拥有属于自己的依赖项目录结构。因此,若有十个应用都需要 lodash,那么磁盘上就会保存该版本的十份独立副本。

pnpm 为机器维护一个全局内容寻址存储。每个版本在该存储中占据一个位置;需要该版本的项目会从该存储获得硬链接(或写时复制引用),并将其放入本地的 node_modules 中。其优势包括:

  • 当存储已包含该版本时,可跳过重新下载
  • 无需重复写入磁盘上已存在的字节
  • 多个项目共享库时占用的空间大幅减少

由于安装过程主要依赖磁盘 I/O,避免重复写入正是减少延迟的关键所在。

2. 使用硬链接和符号链接而非复制

npm 的安装机制会将包文件复制到 node_modules 中。在层级复杂的目录结构中复制数千个文件成本极高。

pnpm更倾向于使用从全局仓库到项目的硬链接,以及能够根据依赖关系图调整嵌套结构的符号链接。与复制相比,链接几乎无需成本:操作系统只需记录指向相同数据块的另一个指针,而无需复制这些数据块。

3. 跨项目的高效缓存

npm也会对下载内容进行缓存,但它仍会从该缓存中提取并复制内容到每个项目中。在pnpm的仓库模型下,一旦某个版本存在于机器上的任何位置,将其引入全新的项目几乎可以立即完成——无需再次下载,也几乎没有额外的处理工作。

以下情况尤其能体现这一优势:

  • 在锁定不同依赖集的分支之间切换
  • 维护多个共享相同库的仓库
  • 运行在多次构建之间恢复共享仓库的CI任务

4. 避免额外解析工作的非扁平化 node_modules 结构

旧版本的 npm 会通过展平 node_modules 来减少重复内容,但这种策略会带来额外的开销:需要耗费大量资源来确定每个包应放置何处以避免冲突。

pnpm 采用严格的符号链接式 node_modules 结构,使得每个包仅能看到其自身声明的依赖项(不会出现意外的隐式导入)。更安全的解析机制只是其优势之一——它还省去了 npm 那种耗时的展平规划过程,从而在安装时降低 CPU 使用率。

5. 并行化操作

pnpm 会在条件允许的情况下尽可能同时执行解析、获取和链接操作,其并行程度远超 npm 的常规处理方式。再结合“链接而非复制”的 I/O 模式,整体执行时间会进一步缩短,尤其是在依赖关系极为复杂的场景中。

6. 项目规模越大,实际影响越显著

对于只有少数几个模块的简单应用,其优势可能并不明显。但以下情况会放大这种优势:

  • 单仓库架构,其中多个模块共享相同的库
  • 团队同时处理多个依赖相同组件的产品
  • CI/CD流水线,在每次构建时都会重复安装依赖
  • 庞大的依赖树,这是现代前端技术栈的典型特征

在这类环境中,原本通过npm需要数分钟才能完成的安装操作,现在可缩短至几秒。

7. 节省磁盘空间是附带效果,而非额外好处

速度是核心优势,但同样的设计也能解决存储问题。由于不会为每个项目单独复制包文件,团队往往能节省大量磁盘空间。在速度较慢的磁盘上,需要处理的数据量减少,也会间接提升传输效率。

一个简单的类比

可以把 npm 想象成一家为每位借阅者复印相同书籍的图书馆。而 pnpm 则像是一个所有人共享同一书架的图书馆,每位读者只需拿到该共享版本的标记页即可。复印需要时间和纸张,而直接使用现有副本几乎无需成本。

结论

pnpm 相比 npm 的优势并非表面上的功能差异,它重新设计了存储与链接机制:避免重复下载,优先使用链接而非复制文件,同时省去不必要的操作。通常是最耗时的前端工作流程中的安装步骤,也因此变得更快、更高效。

对于拥有多个项目或使用单仓库结构的团队而言,采用 pnpm 是提升安装速度和减少磁盘占用最简单的方案之一。