💎前情提要
在前面两篇文章中反复提到了不同框架编译之后的差异
- 🚀 React编译之后是
Jsx
函数返回的虚拟DOM
- 🚀 Vue编译之后是
render
函数返回的虚拟DOM
- 🚀 SolidJS编译之后返回的
真实DOM
字符串 - 🚀 Svelte编译之后返回的是
真实DOM
片段
React
由于架构机制决定了每当状态发生改变,从当前组件开始一直到叶子组件重新加载。
Vue
由于给每个组件建立了watchEffect
监听机制,每当组件依赖的状态发生改变,当前组件重新加载。
SolidJS
和Svelte
由于在编译之后就确定了当状态发生改变UI
随之变化的关系,所以仅仅是具体DOM
的重新加载。
根据这些不同的更新粗细粒度,他们被分为
粒度 | 成员 |
粗粒度 | React |
中粒度 | Vue |
细粒度 | SolidJS ,Svelte |
💎直观感受
为了直观感受更新时的区别,现在我们设计如下关系的组件:
GrandFather | Father | Child
每个组件的背景色都是随机的,并且在Father
组件中,实现了一个Count
功能。
我们用四个框架分别实现。下面只给出一个例子。
生成随机颜色:
`#${(~~(Math.random()*(1<<24))).toString(16)}`
Father
组件如下:
// Father.jsx import React, { useState } from 'react' const Father = () => { const [count, setCount] = useState(0) const onClick = () => setCount(count => count ++) return ( <div style={{ display: "flex" }}> <div onClick={() => onClick()} style={{ height: 100, width: `40vw`, background: `#${(~~(Math.random() * (1 << 24))).toString(16)}`, }} > {count} <Child /> </div> <div onClick={() => onClick()} style={{ height: 100, width: `40vw`, background: `#${(~~(Math.random() * (1 << 24))).toString(16)}`, }} ></div> </div> ) } export default Father
接下来,我们看看他们在触发onClick
时的不同表现吧。
🚀 React
🚀 Vue
🚀 Svelte
🚀 SolidJS
🚀 结论
上面的图中,可以直观的看到:
React
在当前组件状态发生变化时,从当前组件开始,包括子组件都被重新加载了。
Vue
仅仅是当前组件重新加载。
SolidJS
、Svelte
仅仅是重新加载组件!
💎总结
在项目比较小时,SolidJS
、Svelte
的优势不会很明显,
但是当面对大型项目时,React
和Vue
的性能短板就显露出来了。
面对这样的压力,尤雨溪在年初的展望里已经预告了Vapor mode
,该模式的灵感就是受到了SolidJS
的启发。
它可以在给定相同的Vue SFC
前提下,与当前基于虚拟DOM
的输出相比,Vapor Mode
将其编译成性能更高、使用更少内存且需要更少运行时支持代码的JavaScript
输出。
对于React
由于架构机制的限制,目前很难做出根本性的改变,
对于开发者,我们可以选择手动优化。例如,将组件使用memo
包裹起来。
const Child = memo(() => <Comp>your comp</Comp>)
此时上面的例子中,React
的效果更新效果就和Vue
类似了。
我们为了演示每次dom
都是重新加载的,所以样式是直接这样写的。
background: `#${(~~(Math.random() * (1 << 24))).toString(16)}`
在实际开发中,要尽量避免无意义的重复计算,尤其React
中,比如:
// bad <Comp style={ margin: window.screen.width / 3 * 2 } />
// good const App = () => { const margin = useMemo(() => window.screen.width / 3 * 2, []) return <Comp style={ margin } /> } // bettter const margin = window.screen.width / 3 * 2 const App = () => { return <Comp style={ margin } /> }
好了今天的分享就到这了,文章中如果出现问题,有劳各位大佬指正!