先说论断
- dom 节点数量对内存影响没设想中大,js 变量才是内存占用的首恶
- 内存占用及运行性能比照:原生 js < v-for div ≈ v-for 函数式组件 < v-for 一般组件
- 去虚构 dom 化框架正在崛起,成为一种新的抉择
dom 节点数量对内存影响没设想中大(十万 div 仅占用 400mb)
- 测试示例
- 生成 100,000(十万)个 div,内存占用仅 400mb,均匀每个 div 占用内存 400 * 1024 kb / 100,000 = 4kb
- 留神,这里内存占用是动态状态内存,即 div 生成实现后期待一会(约 1min)内存回收实现后的内存占用,div 生成过程中会产生两头变量,内存占用会比动态时高。
- 如果短时间多少清空 div 再从新生成,会导致内存占用变大
组件过多,或者才是 vue 我的项目内存占用大、运行慢的起因
别离以「纯 js 渲染 div」、「v-for 渲染 div」、「v-for 渲染函数式组件」、「v-for 渲染一般组件」为例做性能比照测试
「纯 js 渲染 div」运行示例,对应源码
-
10,000(一万)个 div
- 渲染耗时:26ms,均匀单个 div 渲染耗时:0.0026ms
-
100,000(十万)个 div
- 渲染耗时:265ms,均匀单个 div 渲染耗时:0.0027ms
-
100,000(十万)个 div
- 占用内存:528mb,均匀单个占用内存:528 * 1024 / 100,000 = 5.4kb
「v-for 渲染 div」运行示例,对应源码
-
10,000(一万)个 div
- 应用 key 缓存节点渲染耗时:61ms,均匀单个 div 渲染耗时:0.0061ms
- 不应用 key 缓存节点渲染耗时:91ms,均匀单个 div 渲染耗时:0.0091ms
-
100,000(十万)个 div
- 应用 key 缓存节点渲染耗时:499ms,均匀单个 div 渲染耗时:0.005ms
- 不应用 key 缓存节点渲染耗时:286ms,均匀单个 div 渲染耗时:0.0029ms
-
100,000(十万)个 div
- 占用内存:586mb,均匀单个占用内存:586 * 1024 / 100,000 = 6kb
「v-for 渲染函数式组件」运行示例,对应源码
-
10,000(一万)个 div
- 应用 key 缓存节点渲染耗时:85ms,均匀单个 div 渲染耗时:0.0085ms
- 不应用 key 缓存节点渲染耗时:82ms,均匀单个 div 渲染耗时:0.0082ms
-
100,000(十万)个 div
- 应用 key 缓存节点渲染耗时:392ms,均匀单个 div 渲染耗时:0.0039ms
- 不应用 key 缓存节点渲染耗时:505ms,均匀单个 div 渲染耗时:0.005ms
-
100,000(十万)个 div
- 占用内存:654mb,均匀单个占用内存:654 * 1024 / 100,000 = 6.7kb
「v-for 渲染一般组件」运行示例,对应源码
-
10,000(一万)个 div
- 应用 key 缓存节点渲染耗时:122ms,均匀单个 div 渲染耗时:0.0122ms
- 不应用 key 缓存节点渲染耗时:360ms,均匀单个 div 渲染耗时:0.0325ms
-
100,000(十万)个 div
- 应用 key 缓存节点渲染耗时:918ms,均匀单个 div 渲染耗时:0.0092ms
- 不应用 key 缓存节点渲染耗时:13881ms(13.8s),均匀单个 div 渲染耗时:0.1388ms
-
100,000(十万)个 div
- 占用内存:907mb,均匀单个占用内存:907 * 1024 / 100,000 = 9.3kb
通过上述测试可得
纯 js 渲染 | v-for 渲染 div | v-for 渲染函数式组件 | v-for 渲染一般组件 | |
---|---|---|---|---|
一万 div 复用 key 渲染耗时 | – | 61ms/6.1us | 85ms/8.5us | 122ms/12.2us |
一万 div 不复用 key 渲染耗时 | 26ms/2.6us | 91ms/9.1us | 82ms/8.2us | 360ms/36us |
十万 div 复用 key 渲染耗时 | – | 286ms/2.9us | 392ms/3.9ms | 918ms/9.2us |
十万 div 不复用 key 渲染耗时 | 265ms/2.7us | 499m/5us | 505ms/5us | 13881ms/138.8us |
十万 div 内存占用 | 528mb/5.4kb | 586mb/6kb | 652mb/6.7kb | 907mb/9.3kb |
- dom 节点数量对内存影响没设想中大,10 万 div 占用内存 400mb(只生成一次),均匀单个 div 占用内存仅 4kb
- vue 组件对内存占用较大,仅仅最简略的 div 组件就须要额定增加 9.3 – 5.4 = 3.9kb 内存,若组件复杂度回升,则内存占用将进一步减少。成为内存瓶颈
- vue 函数式组件、v-for div 是否应用 key 缓存节点,对运行耗时变动不大
- vue 组件是 key 缓存节点,对节点更新性能有很大晋升,10 万组件更新,从 13s 耗时优化到 0.9s 耗时,缩小近 13 – 0.9 / 13 = 93% 运算耗时
- vue 组件并非越细越好,颗粒度太细,将导致 vue 组件数量急剧减少,内存占用急剧减少
- 纯 js 渲染 div 最快,应用 v-for div,v-for 函数式组件的渲染耗时至多是 纯 js 渲染耗时的两倍,这是因为虚构节点 vnode 须要执行 diff 算法决定的。
去虚拟化正在崛起
既然 vnode 计算如此耗费性能,那可否舍弃 vnode 来进步性能呢?答案是必定的,svelte(相似 vue),solid(相似 react) 就是这么做的
Svelte,新兴前端框架 Svelte 从入门到原理,Virtual DOM is pure overhead,虚构 DOM 是纯正的节约
Solidjs,SolidJS 入门