秒级 npm 安装方式
如果无法正常显示,请先停止浏览器的去广告插件。
1. 一种秒级安装 npm 的方式
零弌
前端技术专家
2. 目录
01 02 03
性能对比 优化方式 发展路径
3. 01
性能对比
4. 基准性能测试
依赖数量:2211 个
测试
@alipay/smallfish
依赖大小:38.97 MB
网络 千兆网络
规格 8C16G m1 Mac mini
缓存 无缓存
registry 私有 registry
环境
5. 基准性能结果
70
67
52.5
36
35
20
17.5
0
19
10X 提升
6
NPM
YARN
NPM
YARN
PNPM
PNPM
CNPM
CNPM
NPM RAPID
NPM RAPID
6. 02
优化方式
7. 为什么 npm 又慢又大?
共 4422 次请求
依赖树生成耗时 15+ 秒 共 204113 次 IO 操作
下载解压耗时 30+ 秒 占用 445 MB磁盘
大量重复内容
2211 次包信息请求 文件写入 每安装一次新增占用 445 MB
2211 次 tgz 下载
目录创建
bin 文件软链
bin 文件 chmod
8. 优化三大法宝
聚合 中间层 缓存
减少请求量 减少写入量 减少重复数据
9. small sh 依赖图
npm 客户端需要将这星云图一般的依赖信息都拉取到本地进行运算。
图片使用 npmgraph.an 生成
10. 聚合前
npm client
npm registry
递归请求包版本信息
生成 package-lock.json
npm client
npm registry
11. 聚合后
npm client
npm registry
请求依赖树
@npm-cli/
arborist
生成依赖树
registry service
mem cache
distribute
cache
查询依赖版
内存穿透
响应依赖树
npm client
返回依赖树
npm registry
db
@npm-cli/
arborist
mem cache
缓存传统
distribute
cache
db
12. 为什么 npm 又慢又大?
请求次数:4422 次-> 2212 次
服务端生成依赖树
耗时:15 秒 -> 3 秒
(80% off)
共 204113 次 IO 操作
下载解压耗时 30+ 秒
文件写入
目录创建
bin 文件软链
bin 文件 chmod
占用 445 MB磁盘
大量重复内容
每安装一次新增占用 445 MB
13. 20W+ 次 IO
204113 x 76(μs) = 15.2(s)
依赖多 依赖重复
社区复杂,这个不可改变 cnpm/pnpm 通过软链减
少写入量,但是在社区越
来越庞大的情况,已经不
再那么快
14. 潜入更深层
@alipay/small sh
├ README.md
├ bin
│ └ small sh
├ internals
│ └ runtime.d.ts
├ lib
│ ├ index.js
│ └ runtime.d.ts
└ package.json
5 x mkdir
6 x writeFile
1 x symlink
1 x chmod
15. Tar 文件结构
tar -tvf @alipay-small sh-1.0.0.tgz
-rw-r--r-- 0 0
0
110 10 26 1985 package/lib/index.js
-rw-r--r-- 0 0
0
976 10 26 1985 package/package.json
-rw-r--r-- 0 0
0
35 10 26 1985 package/README.md
tar -tvf @alipay-small sh-core-1.0.0.tgz
-rw-r--r-- 0 0
0
110 10 26 1985 package/lib/index.js
-rw-r--r-- 0 0
0
976 10 26 1985 package/package.json
-rw-r--r-- 0 0
0
35 10 26 1985 package/README.md
16. 组织一个新的 tar
解压 拼接
110 10 26 1985 @aliay_small sh@1.0.0/lib/index.js
976 10 26 1985 @aliay_small sh@1.0.0/package.json
35 10 26 1985 @aliay_small sh@1.0.0/README.md
110 10 26 1985 @aliay_small sh-core@1.0.0/lib/index.js
976 10 26 1985 @aliay_small sh-core@1.0.0/package.json
35 10 26 1985 @aliay_small sh-core@1.0.0/README.md
0
0
0
0
0
0
3 次IO
tar -tvf bucket.tgz
-rw-r--r-- 0 0
-rw-r--r-- 0 0
-rw-r--r-- 0 0
-rw-r--r-- 0 0
-rw-r--r-- 0 0
-rw-r--r-- 0 0
26 次IO
17. tar 打破了原来所有的使用习惯!
require
fs.readFile
ls/cat/grep
vi/emacs/nano
查看/编辑
18. 走到最底层
PnP(yarn2)
hijack require api
fs.readFile
require
社区需要为存储方式的改
nodejs API
变付出极大的成本
User Space
uv_req_t
read
Kernel Space
文件系统
libuv API
libc API
19. 计算机科学领域的任何问题都可以增
加一个间接的中间层。
20. FUSE
From :SvenTranslation
CC BY-SA 3.0
https://commons.wikimedia.org/w/
index.php?curid=3009564
21. Overlay
Overlay
Read
Read
Write
Upper
Lower
index.js index.js
README.md README.md
bin/smallfish
bin/smallfish
22. NPM FS
Read
Write
node_modules(Overlay)
work dir(tmpfs)
tar buckets(FUSE)
23. 为什么 npm 又慢又大?
请求次数:4422 次-> 2212 次 IO 操作:204113 次 -> 51359 次
服务端生成依赖树
使用 tar 存储文件
耗时:15 秒 -> 3 秒 耗时:30 秒 -> 3 秒
(90% off)
(80% off)
占用 445 MB磁盘
大量重复内容
每安装一次新增占用 445 MB
24. 聊聊缓存
NPM pnpm
空间占用大
全局缓存 Tar,安装时解压 一改全改
全局缓存文件,安装时硬链
25. 基于 COW 的全局缓存
Read
Write
Read
Write
node_modules(Overlay)
work dir(tmpfs)
单项目修改不会影响到其他项目。
tar buckets(FUSE)
COW(Copy On Write): 写时复制
26. 为什么 npm 又慢又大?
请求次数:4422 次-> 2212 次 IO 操作:204113 次 -> 51359 次 磁盘占用:445XN MB-> 445 MB
服务端生成依赖树
使用 tar 存储文件
耗时:15 秒 -> 3 秒 耗时:30 秒 -> 3 秒
(90% off)
(80% off)
基于 COW 的缓存
项目间隔离的
缓存
27. 03
发展路径
28. 最快且无副作用的 npm 安装器
现在在这
npm
cnpm
软链优化
NPM FS
安装优化
回归 NPM 目
录结构
支持 workspace
29. FAQ
钉钉
微信
30. 谢谢观看