乐趣区

关于javascript:这波React属实被针对了

大家好,我卡颂。

昨天在网上欢快冲浪时,看到一篇框架测评,成果属实爆炸。

作者用 ReactSolid.js开发了同样的 Demo。为什么用Solid.jsReact比照呢,让咱们看看 Solid.jsAPI

  • Hooks
  • Context、Portal API
  • Error Boundaries

不能说和 React 多雷同,只能说一摸一样吧。而且 Solid.js 也用 JSX 形容视图,所以一个 React 利用要改为 Solid.js 利用的老本很小。

具体测评后果怎么样呢,差了快 3 倍,这一波 React 属实被针对了。

本文参考 SolidJS vs React: I’ve Built the Same App On Both Libraries.

为啥差这么多

简略介绍下这个Demo,初始渲染空白列表:

首次 mount 实现后发动申请,渲染列表数据:

这是两个利用 Chrome Dev Tools Performance 面板的后果:

解释下其中几个要害指标:

  • Loading:发动网络申请、解析 HTML 的工夫
  • Scripting:解析、编译、执行 JS 的工夫(包含垃圾回收工夫)
  • Rendering:stylelayout 计算
  • Painting:paintcomposite、解码图片

具体关注Scripting,左 475ms(React),右 176ms(Solid.js

2 倍多的差距,这么夸大?

问题出在哪

前端框架的工作流程能够简略用三个步骤总结:

  1. 触发交互
  2. 计算交互会影响哪些DOM
  3. 执行 DOM 操作

这里的交互可能是首屏渲染,可能是点击造成的状态变动、可能是申请数据 ……

React 中,步骤 2 是在运行时实现的,而在 Solid.js 中是在编译时实现的。

具体来说,该步骤在 React 中被称为 reconcile,更广泛的称说是 虚构 DOMdiff 算法。

Performance 面板上面的 Call Tree 中能够看到,执行XHR Load(申请列表数据)前有个很耗时的操作(Function Call),该操作即reconcile

而在 Solid.js 利用中就没有这个耗时的操作:

在编译时,Solid.js会将 JSX 间接编译为 状态 操作 DOM 的办法 之间的分割。

因为 JSX 太过灵便,为了在编译时有更多线索建设这种分割,Solid.jsReact 原有 JSX 组件根底上提供了一些 控制流组件

举个例子,上面是 遍历列表项 在两个框架中的实现区别:

// React
<ul>
  {list.map(item => <li>{item.name}</li>
  )}
</ul>
<ul>
  
// Solid.js
<ul>
  <For each={list}>
    {(item) => <li>{item.name}</li>}
  </For>  
</ul>

For组件代替了 JS 中的数组 map 办法。

Solid.js 在编译时实现这些工作,在运行时每次更新理论只用实现步骤 1 和 3,省去了大部分步骤 2 的工夫。

尽管 Reactreconcile有优化策略,但随着利用体积增大,或者我的项目成员不齐全恪守最佳实际,势必会造成在步骤 2 上破费的工夫越来越多。

Solid.js提前建设 状态 操作 DOM 的办法 之间的分割,尽管须要在运行时占用更多内存保留这种对应关系,然而却省去了大部分步骤 2 的工夫,是一种典型的空间换工夫的策略。

总结

说了这么多,尽管看起来 Solid.js 比照 React 在框架的某些方面是有劣势的,但并不能撼动 React 的统治位置。

毕竟,React这么风行和他快不快一点关系都没有,社区生态凋敝才是最重要的。

还有个有意思的事,这里是文中的 2 个 Demo 地址:

  • Solid.js 版
  • React 版

Demo中获取数据的 API 的域名是rickandmortyapi.com,竟然还有这种网站 ……

欢送退出人类高质量前端框架钻研群,带飞

退出移动版