# React
在使用 react 的过程中,我们绕不开渲染性能优化问题,因为默认情况下 react 组件的 shouldComponentUpdate 函数会一直返回 true,这回导致所有的组件都会进行耗时的虚拟 DOM 比较。在使用 redux 作为 react 的逻辑层框架时,我们可以使用经典的 PureComponent+ShallowCompare 的方式进行渲染性能优化
https://foio.github.io/mobx-react/
# MobX
作为一个数据层框架,mobx 基于一个最简单的原则:
当应用状态更新时,所有依赖于这些应用状态的监听者(包括 UI、服务端数据同步函数等),都应该自动得到细粒度地更新。
在使用 mobx 作为 react 的 store 时,我们该如何进行渲染性能优化呢? 通过分析源代码发现,在使用@observer 将 react 组件转换成一个监听者(Reactions)后,mobx 会为 react 组件提供一个精确的、细粒度的 shouldComponentUpdate 函数:
shouldComponentUpdate: function(nextProps, nextState) {
......
// update on any state changes (as is the default)
if (this.state !== nextState) {
return true;
}
// update if props are shallowly not equal
return isObjectShallowModified(this.props, nextProps);
}
借助于 mobx 框架对 Observable 变量引用的跟踪和依赖收集,mobx 能够精确地得到 react 组件对 Observable 变量的依赖图谱,然后再用经典的 ShallowCompare 实现细粒度的 shouldComponentUpdate 函数,以达到 100%无浪费 render。这一切都是自动完成地,fantastic!使用 mobx 后,我们再也无需手动写 shouldComponentUpdate 函数了。
# React Native
# 优势
- 跨平台 (只有 0.2% 的平台特定代码)
- 统一的设计语言,同时还能为不同平台提供不同设计
- React 的 scale 很好。组件化,简单的生命周期,声明式
- 迭代速度快(主要是 hot reloading 很快)
- 大量基础设施的投入值得(网络、国际化、复杂动画、设备信息、用户信息等等都是通过一- 个桥把原生 api 暴露给 RN 的。)
- 同时他们在这里也指出:他们并不相信在一个已有 app 上集成 RN 是一件简单事儿,必须- 要大量且持续地投入基础设施才行(说好的「满意的地方」呢)
- 性能 (尽管大家都担心但是其实基本没有问题)
- 不过首次渲染比较慢,导致不适合用作启动屏、deeplink,也增加了可交互时间(TTI),另外掉帧不好 debug(说好的「满意的地方」呢)
- Redux(好用,虽然废话太多)
- 背后是原生,一些曾经不确定能不能做的功能(Shared element transitions、动画库 Lottie、网络层、核心基础设施)发现都能做
- 静态分析(eslint,prettier,一些性能检测)
- 动画
- JS/React 的开源生态
- Flexbox
- 有时候可以加上 Web 跨三端
# 劣势
- 论成熟度,稳定性,RN 比 不上 iOS 和 Android 原生。
- 由于 RN 的 Bug,有时我们必须维护自己的一个 RN 分支。
- JS 缺少类型系统,Flow 太严格,TS 集成到已有项目也还有问题。
- 不好重构(JS 没有类型无法静态分析,重构引起的错误不能在编译时被捕捉到)
- JavaScriptCore 不一致性,更糟糕的是,现在都 8102 年了,RN (Android)带的还是不支持 ES 6 的 JSC
- RN 开源库质量参差不齐。比如在 iOS 上正常的库在 Android 上可能有意想不到的错误(因为为作者也许只熟悉 iOS 和 RN,并不熟悉 Android) 有时不得不白手起家,因为很多的基础框架中的库还没有 的 RN 封装。
- 崩溃监控库在 RN 上表现不是特别特定业。内没方案,只能自己搞。
- Native Bridge 的由于 JS 的弱类型造成 Native 与 JS 通信 中类型的不匹配,容易造成错误。
- 启动时间,RN 框架初始化需要几秒,即使是在高端机器上。
- 新开页面的渲染时间,0.4 秒左右页面第一次渲染费时。
- APP 大小。至少增加 12M。
- 直到目前都无法在 Android 上支持 64 位。
- 手势,iOS 和 Android 的手势 API 差距很大,不过喜闻 react-native-gesture-handler 发布了 1.0 版本。
- 长列表,虽然 RN 团队很努力了,但是由于 RN 的异步通信机制,长列表的流畅渲染,目前依然无解。
- React Native 升级是个坑。
- RN 中的 Accessibility 就是个大坑。
- 还有一些奇怪的 Bug,暂没有修复。
- SavedInstanceState 在 Android 上跨进程的坑。
# 不是技术问题的问题
- 要用好 RN 你必须同时熟悉 iOS 和 Android ,当然还有 RN 本身,这就对我们工程师提出了更多挑战。
- 团队的管理,责任的划分。
- RN 文档及相关资源不如 iOS 和 Android 的丰富。