乐趣区

关于前端:当前端框架聊性能聊的是同一个性能么

大家好,我是卡颂。

你可能看过上面这张图(或相似的图):

这是一张前端框架性能跑分表,表中每一行都是一个性能度量指标。

据我多年埋伏推特察看,采纳了 细粒度更新 技术的框架开发者广泛喜爱晒跑分表。

比方 Solid.js 作者 Ryan Carniato 写的这篇 2020 年 JS 框架性能比照内含 15 张跑分表

这些跑分表挂车尾的通常是 ReactAngular12 这样的业界出名框架。

不禁让人狐疑,前端提高这么快,React都这么拉跨啦?

本文会分享一些从跑分表中发现的乏味洞察。

虚构 DOM 到底慢不慢?

咱们先截取最后面两行,别离是 页面加载后创立 1000 行表格所需工夫 以及 替换 1000 行列表所需工夫

从左到右性能顺次升高,其中第一列 vanillajs原生 JS,这也是泛滥框架毕生在追寻的指标。

能够看到,尽管 React 以及出名 类 React框架 Preact 排名倒数 3、4,但同样作为 类 React框架的 inferno 排名却很靠前(第三名)。

这示意 虚构 DOM可能并不是性能瓶颈。

实时上,得益于多种 虚构 DOM的优化技巧,比方:

  • 数组两端比拟
  • 查找最小挪动次数

inferno 虚构 DOM可能是业界同类解决方案中最高效的。

这里简略介绍下 两端比拟 ,假如diff 前后的数据别离为:

// diff 前
abcd
// diff 后
abfd

两端比拟 会先排除数组雷同的前、后缀节点。例子中的雷同前缀是ab,雷同后缀是d

所以理论进行比照的是:

// diff 前
c
// diff 后
f

简略、高效的优化策略。

因为 ReactFiber架构应用链表实现,无奈进行两端比拟

细粒度更新 yyds?

尽管 虚构 DOM能够被优化的很高效,但他毕竟为 运行时 带来不少的运算量。

在上表有一行指标,红色特地多(代表性能低),这行度量的是 点击列表某一行使其高亮所需工夫:

这行的跑分后果:SolidJS > Svelte > Vue3.2 > inferno > … > React > Angular

可见,采纳 虚构 DOM的框架性能广泛偏差。排名前 3 的框架技术架构为:

  • SolidJS:预编译 + 细粒度更新
  • Svelte:预编译 + 细粒度更新
  • Vue3:预编译 + 细粒度更新 + 虚构 DOM

这是因为 点击列表某一行使其高亮所需工夫 度量的是 部分的小扭转

这种类型扭转是基于 订阅公布 细粒度更新 最善于的场景。

绝对的,也是 虚构 DOM最不善于的中央。

React 有这么不堪么?

那么基于 细粒度更新 的框架有什么毛病,React又有什么性能长处呢?

答案是:继续的可交互工夫(consistently interactive)。

他度量的是:CPU和网络的闲暇工夫,即 Chrome DevToolslighthouse工具中的 TimeToConsistentlyInteractive 指标。

图中右边绿字 Short Tasks 指向的都是耗时很短的 JS 工作,短耗时意味着浏览器有更多闲暇工夫重排、重绘,更不易卡顿。

与其绝对的是左边红字 Long Tasks,指向的都是耗时很长的JS 工作,此时浏览器更容易卡顿。

细粒度更新 框架初始时会有为节点建设 响应式更新 的过程,比方:

  • Vue2中通过settergetter
  • Vue3中通过proxy

这一过程会有肯定 CPU 及内存开销(尽管随着 proxy 的遍及,JS原生反对 响应式更新 后,这部分开销会越来越低)。

React没有这部分开销,同时借由基于 虚构 DOM 工夫切片 React 能进一步升高 继续的可交互工夫

乏味的是,以上性能跑分表来源于开源我的项目 js-framework-benchmark,该我的项目是有 consistently interactive 这一度量的。

然而有些基于 细粒度更新 的框架并没有抉择在跑分表中退出这一项的比照。

总结

能够看到,不同的技术有不同劣势:

  • 细粒度更新 对于部分更新性能更佳
  • 基于 虚构 DOM 工夫切片 继续的可交互工夫 性能更佳

当大家在聊性能时,最好先明确聊的是哪个指标,否则差别可能很大。

退出移动版