大家好,我是Kason。对于“前端框架”,长期以来一直存在着各种争议。其中,争议最大的是以下两个:性能之争和API设计之争。比如各大新兴框架都会拿出benchmarks来证明自己出色的运行时性能,而React通常在这些benchmarks中垫底。在API设计方面,Vue爱好者认为:“更多的API约束了开发者,不会因为团队成员水平的不同而导致代码质量有较大差异。”而React爱好者认为:“Vue大量的API限制了灵活性,JSXyyds”。归根结底,以上讨论是框架在“性能”和“灵活性”之间的权衡。本文将介绍一个名为[1]的状态管理库,它在设计理念上与其他状态管理库有很大不同。在React中合理使用legendapp可以大大提高应用程序的运行时性能。但这篇文章的目的不只是“介绍一个状态管理库”,而是要和大家一起体验“随着性能的提高,框架在灵活性上的变化”。React性能优化React性能确实不是很好,这是不争的事实。原因是React的自上而下的更新机制。每次状态更新时,React都会从根组件开始深度优先遍历整个组件树。既然遍历方式是固定的,那么如何优化性能呢?答案是“找到遍历时可以跳过的子树”。什么样的子树可以跳过遍历?显然是“没有改变的子树”。在React中,“改变”主要是由以下三个要素引起的:statepropscontext,它们都可能改变UI,或者触发useEffect。因此,如果一个子树中的上述三个元素有变化,则可能发生变化,不能跳过遍历。我们从“变”的角度来看一下React中的性能优化API。对于下面两个:useMemouseCallback,它们的本质都是为了减少props的变化。对于下面两个:PureComponentReact.memo,它们的本质是——直接告诉React这个组件没有变化,你不需要检查上面三个元素。状态管理库能做的优化了解了React的性能优化之后,我们来看看状态管理库能为“性能优化”做些什么。性能瓶颈主要出现在更新时,所以性能优化主要有两个方向:减少不必要的更新和减少每次更新时要遍历的子树,像Redux上下文中的useSelector就是第一种方式。对于后一种路径,“减少更新时遍历的子树”通常意味着“减少上面介绍的三个元素的变化”。PS:黄轩开发的ReactForget是一个“可以生成相当于useMemo和useCallback代码的编译器”,目的是减少三个元素之间props的变化。状态管理库在这方面能起到的作用非常有限,因为无论状态管理库封装得多么巧妙,都掩盖不了“它其实就是一个React状态”的事实。例如,虽然Mobx为React带来了“细粒度更新”,但它并没有带来匹配Vue中“细粒度更新”的性能,因为Mobx最终会触发自上而下的更新。legendapp的思路本文要介绍的legendapp也是走的第二条路,但是它的思路比较特别——如果减少3个元素的数量,那不就可以减少3个元素的变化吗?举个极端的例子,如果在一个庞大的应用中没有状态,更新时可以跳过整个组件树。以下是Hook实现的计数器示例。useInterval每秒触发一次回调,回调中触发更新:functionCounter(){const[count,setCount]=useState(1)useInterval(()=>{setCount(v=>v+1)},1000)return
