大家好,我卡颂。
昨天在网上欢快冲浪时,看到一篇框架测评,成果属实爆炸。
作者用React
和Solid.js
开发了同样的Demo
。为什么用Solid.js
和React
比照呢,让咱们看看Solid.js
的API
:
- 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:
style
和layout
计算 - Painting:
paint
、composite
、解码图片
具体关注Scripting
,左475ms(React
),右176ms(Solid.js
)
2倍多的差距,这么夸大?
问题出在哪
前端框架的工作流程能够简略用三个步骤总结:
- 触发交互
- 计算交互会影响哪些
DOM
- 执行
DOM
操作
这里的交互可能是首屏渲染,可能是点击造成的状态变动、可能是申请数据......
在React
中,步骤2是在运行时实现的,而在Solid.js
中是在编译时实现的。
具体来说,该步骤在React
中被称为reconcile
,更广泛的称说是虚构DOM
的diff
算法。
在Performance
面板上面的Call Tree
中能够看到,执行XHR Load
(申请列表数据)前有个很耗时的操作(Function Call
),该操作即reconcile
。
而在Solid.js
利用中就没有这个耗时的操作:
在编译时,Solid.js
会将JSX
间接编译为状态
与操作DOM的办法
之间的分割。
因为JSX
太过灵便,为了在编译时有更多线索建设这种分割,Solid.js
在React
原有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的工夫。
尽管React
对reconcile
有优化策略,但随着利用体积增大,或者我的项目成员不齐全恪守最佳实际,势必会造成在步骤2上破费的工夫越来越多。
Solid.js
提前建设状态
与操作DOM的办法
之间的分割,尽管须要在运行时占用更多内存保留这种对应关系,然而却省去了大部分步骤2的工夫,是一种典型的空间换工夫的策略。
总结
说了这么多,尽管看起来Solid.js
比照React
在框架的某些方面是有劣势的,但并不能撼动React
的统治位置。
毕竟,React
这么风行和他快不快一点关系都没有,社区生态凋敝才是最重要的。
还有个有意思的事,这里是文中的2个Demo
地址:
- Solid.js版
- React版
Demo
中获取数据的API
的域名是rickandmortyapi.com
,竟然还有这种网站......
欢送退出人类高质量前端框架钻研群,带飞