[避免]同步和异步import同个文件
按需策略(Lazy)
其实前面有讲到一些按需加载的方案,这里我们适当延伸一下:既然资源包的加载可以做到按需,是否某个组件的渲染可以按需?某个对象实例的使用可以按需?某个数据缓存的生成也可以按需?
懒组件(LazyComponent)
如图,PieArc.private.ts对应一个复杂的React组件,PieArc通过makeLazyComponent封装成默认懒加载的组件,只有在代码执行到此处时,组件才会加载并执行。甚至,还可以通过第二个参数(deps)申明依赖,待依赖(promise)完毕时,才加载和执行。
懒缓存(LazyCache)
懒缓存用于这种场景:需要在任何地方使用到数据流(或其他可订阅数据)中的某个数据经过转换后的结果,且仅在使用的那一刻才进行转换
懒对象(LazyObject)
懒对象意即该对象只有在被使用的时候(属性/方法被访问、修改、删除等等),才会被实例化
如图,globalRecorder被引入时,其并未实例化,仅当调用globalRecorder.record()时进行实例化
数据流:节流渲染中大型项目中为了方便状态管理,通常会使用到数据流的方案,如下流程:
store中存储的数据通常偏原子化,粒度非常小,比如state中有:a、b、c ...等N个原子属性,某个组件依赖这N个属性来作UI渲染,假设N个属性会在不同的ACTION下被改变,且这些改变均在16ms内发生,那么若N=20,则16ms内(1帧)会有20次View更新:
这显然会引发非常大的性能问题,由此,我们需要对短时间的ACTION量作一个缓冲节流,待20次ACTION状态改变完毕后,仅进行1次View更新,如下:
此方案在Quick BI以redux中间件的形式发挥作用,在复杂+频繁数据更新场景起到了不错的效果
思考
“君子以思患而豫防之”,当我们回过头去看看,出现的这些性能问题,在架构设计、编码阶段是可以避免掉80%以上的,20%的则可以“空间<=>时间置换策略”等方式去平衡。所以,最佳的性能优化方案,是在于我们对每一段代码质量的执着:是否考虑到了这样的模块依赖关系,可能带来的构建产物体积问题?是否考虑到了这段逻辑可能的执行频次?是否考虑到了随着数据增长,空间或CPU占用的可控性?等等。性能优化没有银弹,作为技术人,需要内修于心(熟知底层原理),把对性能的执念植入本能思考当中,方为银弹。