大家好,我是Kason。你可能见过下图(或类似的):这是一个前端框架性能基准表,表中的每一行都是一个性能指标。根据我潜推多年的观察,采用细粒度更新技术的框架开发者普遍喜欢发跑分。例如,Solid.js作者RyanCarniato撰写的这份2020JS框架性能比较包含15个跑分表。这些跑分表通常与React和Angular12等业内知名框架相关联。不禁让人疑惑,前端进步这么快,React就这么捉襟见肘?本文分享了基准测试中的一些有趣见解。虚拟DOM慢吗?我们先截取前两行,分别是页面加载后创建1000行表所需时间和替换1000行列表所需时间:从左到右,性能依次递减,第一列vanillajs指的是原生JS,很多框架也是如此。终生追求的目标。可以看到虽然React和知名的类React框架Preact分列倒数第3和第4,但同为类React框架的inferno排名非常靠前(第三)。这意味着虚拟DOM可能不是性能瓶颈。在实时方面,得益于多种虚拟DOM优化技术,例如比较数组的两端以找到最小移动次数,inferno的虚拟DOM可能是业界同类解决方案中最高效的。这里简单介绍一下两端的比较,假设diff前后的数据是://abcdbeforediff//abfdafterdiff,两端比较会先排除前面和后缀具有相同数组的节点。例子中相同的前缀是ab,相同的后缀是d。所以实际比较是://cbeforediff//fafterdiff是一种简单高效的优化策略。由于React的fiber架构是使用链表实现的,不可能在两端进行yyds的细粒度更新?虚拟DOM虽然可以非常高效的进行优化,但是毕竟给运行时带来了大量的计算量。上表中有一排指标,有很多红色(代表低性能)。这一行衡量的是点击列表中某一行使其高亮所花费的时间:这一行的跑分:SolidJS>Svelte>Vue3.2>inferno>...>React>Angular可以看出性能使用虚拟DOM的框架通常会有所不同。Top3框架技术架构分别是:SolidJS:预编译+细粒度更新Svelte:预编译+细粒度更新Vue3:预编译+细粒度更新+虚拟DOM衡量的是局部小改动。这种变化是基于订阅发布的细粒度更新的最佳场景。相比之下,也是虚拟DOM不擅长的地方。React有那么糟糕吗?那么基于细粒度更新的框架有哪些缺点,而React有哪些性能优势呢?答案是:持续互动。他测量的是:CPU和网络空闲时间,也就是ChromeDevTools的灯塔工具中的TimeToConsistentlyInteractive指标。图中左边的绿字ShortTasks指的是耗时较短的JS任务。耗时短意味着浏览器有更多空闲时间重新排列和重绘,更不容易卡顿。与之相对的是右边红色的LongTasks,指的是耗时较长的JS任务,此时浏览器更容易卡顿。在细粒度更新框架的开始,会有一个为节点建立响应式更新的过程。比如Vue2中传递setter的过程,Vue3中传递代理的过程,都会有一定的CPU和内存开销(虽然随着代理的普及,JS原生支持响应式更新后,这部分开销会更低,降低)。React没有这部分开销,并且凭借基于虚拟DOM的时间分片,React可以进一步减少连续交互的时间。综上所述,我们可以看到不同的技术有不同的优势:细粒度更新更适合局部更新性能,基于虚拟DOM的时间片更适合连续交互时间。大家在讲性能的时候,最好先讲清楚是哪个指标,不然会相差很大。欢迎加入人类优质前端框架群,与大家一起成长
