🎉尤雨溪为什么要推出Vapor Mode🎉

简介: 🎉尤雨溪为什么要推出Vapor Mode🎉


💎前情提要

在前面两篇文章中反复提到了不同框架编译之后的差异

  • 🚀 React编译之后是Jsx函数返回的虚拟DOM
  • 🚀 Vue编译之后是render函数返回的虚拟DOM
  • 🚀 SolidJS编译之后返回的真实DOM字符串
  • 🚀 Svelte编译之后返回的是真实DOM片段

React由于架构机制决定了每当状态发生改变,从当前组件开始一直到叶子组件重新加载。

Vue由于给每个组件建立了watchEffect监听机制,每当组件依赖的状态发生改变,当前组件重新加载。

SolidJSSvelte由于在编译之后就确定了当状态发生改变UI随之变化的关系,所以仅仅是具体DOM的重新加载。

根据这些不同的更新粗细粒度,他们被分为

粒度 成员
粗粒度 React
中粒度 Vue
细粒度 SolidJSSvelte

💎直观感受

为了直观感受更新时的区别,现在我们设计如下关系的组件:

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仅仅是当前组件重新加载。

SolidJSSvelte仅仅是重新加载组件!

💎总结

在项目比较小时,SolidJSSvelte的优势不会很明显,

但是当面对大型项目时,ReactVue的性能短板就显露出来了。

面对这样的压力,尤雨溪在年初的展望里已经预告了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 } />
}

好了今天的分享就到这了,文章中如果出现问题,有劳各位大佬指正!


相关文章
|
7月前
|
人工智能 JavaScript 前端开发
NUS CS1101S:SICP JavaScript 描述:前言、序言和致谢
NUS CS1101S:SICP JavaScript 描述:前言、序言和致谢
60 0
|
JavaScript Go 开发工具
🎉分享几个从好用到离谱的vs code插件🎉
🎉分享几个从好用到离谱的vs code插件🎉
🎉分享几个从好用到离谱的vs code插件🎉
|
前端开发 JavaScript 调度
🎉干货满满,React设计原理(三):藏在源码里的排位赛,Lane模型🎉
🎉干货满满,React设计原理(三):藏在源码里的排位赛,Lane模型🎉
|
设计模式 前端开发 JavaScript
🎉前端开发书籍推荐🎉
🎉前端开发书籍推荐🎉
|
JavaScript
🎉SolidJS响应式原理和简易实现🎉
🎉SolidJS响应式原理和简易实现🎉
|
缓存 前端开发 JavaScript
🎉干货满满,React设计原理(二):藏在源码里的两个圈🎉
🎉干货满满,React设计原理(二):藏在源码里的两个圈🎉
|
前端开发 调度
🎉干货满满,React设计原理(一):藏在源码里的紧箍咒🎉
🎉干货满满,React设计原理(一):藏在源码里的紧箍咒🎉
Learning C++ No.28 【C++11语法实战】
Learning C++ No.28 【C++11语法实战】
|
存储 网络架构
写作工具可以替代笔记应用吗?我用 Ulysses 做了试验 | Matrix 精选
写作工具可以替代笔记应用吗?我用 Ulysses 做了试验 | Matrix 精选
225 0
|
机器学习/深度学习 人工智能 算法
【花书笔记】 之 Chapter01 引言
【花书笔记】 之 Chapter01 引言
【花书笔记】 之 Chapter01 引言