当前位置: 编码机 >> 编码机资源 >> React框架运行时优化方案的演进
作者:ConardLi
上周刚在公司进行了一次React运行时优化方案的分享,以下是分享的文字版,文章比较长,干货也很多,相信你看完后会对React有不一样的理解。
就在前两个月,React刚刚发布了18版本,记得上一次详细阅读React源码,还是在三年前,当时读的是React的15版本,那时候主要是去研究了一下,当时的虚拟DOM的渲染机制、setState的执行机制,以及React的合成事件,也写了下面几篇React的文章:
setState的执行机制React事件机制深入分析虚拟DOM的渲染过程和特性从Mixin到HOC再到Hook
当时研究完了之后,不禁感叹,以后再也不读React源码了,相比其他框架,React的源码实在是太难读了。
但是,后面随着React16-18的更新,React的底层架构发生了非常大的变化,也带了非常多有意思的新特性,这些特性在老的架构下肯定是实现不了的。这也重新勾起了我的好奇心,React源码究竟发生了哪些变化,于是下定决心再读一遍最新版本的源码。
好在前人栽树、后人乘凉,社区里有很多大牛已经做过了非常好的源码解读,比如卡颂的React技术揭秘、7kms的图解React源码。根据这些教程,我重新梳理了新版React架构的源码划分,重新走了一遍整体的流程,并且对重要的模块进行了自己阅读和研究。
再出一个新的源码解读系列,我觉得没有必要,前面两位已经做的很好了,但是,我希望用更简短的方式帮大家分析和解读一下React主要的发展方向、最近的几次重大更新,都做了什么。
从16年到现在,React经历了15-18几个大的版本,除了Hooks,React在新特性上几乎没有什么大的更新,直到前段时间,沉寂了很久的React终于有了一波新的API。
但是,在之前的几个版本他也没有闲着,给我们造了很多概念,ConcurrentMode、Fiber、Suspense、lanes、Scheduler、ConcurrentRendering,这些概念让一些新手开发者望而却步。
这篇文章的主要目,就是根据React主要优化策略几个阶段的演进,来把这些概念梳理清楚,看看React这几年到底在搞什么东西,以及顺便解读一下最新更新的这些特性。在分享里面我们可能不会很详细的去分析具体的调度流程和细节,但是我们会在一些优化策略上节选一些源码进行解读。
那么,为什么本篇文章的主题是运行时呢?我们先来看看几大框架在设计上的对比。
几大JS框架的设计思路
首先,是React,React是一个重运行时的框架,在数据发生变化后,并没有直接去操作dom,而是生成一个新的所谓的虚拟dom,它可以帮助我们解决跨平台和兼容性问题,并且通过diff算法得出最小的操作行为,这些全部都是在运行时来做的。
最近很火的Svelte,就是一个典型的重编译的框架,作为开发者我们只需要去写模版和数据,经过Svelte的编译和预处理,代码基本全部会解析成原生的DOM操作,Svelte的性能也是最接近原生js的。
那么,Vue这个框架,在运行时和预编译取了一个很好地权衡,它保留了虚拟dom,但是会通过响应式去控制虚拟dom的颗粒度,在预编译里面,又做了足够多的性能优化,做到了按需更新。
那么,下面我们再来看看,什么是编译时的优化。
什么是编译时优化?
Vue使用的是模版语法,模版的特点,就是语法受限,我们可以使用v-ifv-for这些指定的语法去编码,虽然这不够动态,但是由于语法是可枚举的,所以它可以在预编译层面做更多的预判,让Vue在运行时有更好的性能。下面我们可以看一个Vue3.0具体在编译时所做的优化。
传统vdom的Diff算法总归要按照vdom树的层级结构一层一层的遍历,所以diff性能会和模版的大小正相关,跟动态节点的数量无关。在一些组件整个模版内只有少量动态节点的情况下,这些遍历都是性能的浪费。
比如说,上面的这个代码示例,这几个静态的节点在组件更新阶段,是不可能发生变化的。如果能在diff阶段跳过静态内容,那我们就可以避免无用的dom树的遍历和比对。
在Vue3.0里面,就有这样一条类似的优化策略,它的
转载请注明:http://www.aideyishus.com/lkzp/2827.html