我有很丰富的 React Native 开发经验。但是由于接触它太早了,所以我跟它之间的恩怨是有点多的,曾经在各种场合吐槽了它无数次。主要是早期的版本坑确实多,开发体验并不是很友好,React Native 在国内社区的发展也并不是很好,要解决一个坑的成本非常高。
所以,其实我曾经一度放弃过 React Native,在非工作项目中几乎不会想到要使用它。
直到最近,我迷上了 tailwindcss!
虽然我写了好几篇文章来表达 tailwindcss 为啥那么爽,但是我还是收到了大量的朋友的反馈,他说他也不太理解 tailwindcss 为啥会那么有魔力,感觉这玩意儿没啥用,从各种角度去担心用了这个东西会导致什么什么后果...
也有可能是有的道友在工作中并没有那么多写 css 的场景,对我写样式的痛点无法感同身受。不过我已经尽力。好东西分享给你了,感受不到那只能说明缘分还未到。
在我的理念里边,tailwindcss 对开发体验的提升是巨大的,他对于我个人的意义,不亚于 React 从 class 组件到 hooks 思维的转变,我甚至因此有一种冲动把之前所有的项目都翻新重造。也因为这个冲动,我又重新花了很长时间去重新审视我以前并不喜欢的技术栈,比如 Vue,比如 Angular,比如 React Native。
✓当然,用好 tailwind 是有挺高的学习成本的,不要把它当成什么上手即用的简易工具。
当我重新关注 React Native 之后,我才发现,他原来已经如此成熟了。
新的 JavaScript 引擎 Hermes
JavaScript 是一门运行时框架。它的解析、编译、执行都发生在程序运行的过程中。也因此 JavaScript 的性能问题成为了限制 React Native 发展的一个瓶颈。
为了解决这个问题,React Native 团队 在 @0.64
版本中引入了一个新的 JavaScript 引擎:Hermes。这是一个专门针对 React Native 进行优化的 JS 引擎。
Hermes 把 JS 的解析和编译过程前置到项目打包阶段,应用程序运行时可以直接执行字节码,从而极大的提高了 runtime
的执行效率。
这种预编译的优化思路除了可以有效的提高程序的执行效率之外,由于直接放弃了 JIT 编译器,所以执行引擎的体积大小和内存损耗都可以得到极大的优化。如下图所示
新的 通信方式:JSI
在以前的版本中,RN 代码与客户端原生 UI 的交互的成本是非常高的,他们之间通过 JSBridge 进行通信和数据的转化。JSBridge 虽然功能上非常强大,他能够实现 JS 层与原生环境的双向通信,但是由于通信过程需要经历如下步骤,所以他的通信成本非常高。
这也导致了 JS 层与原生层的通信变成了一个异步过程,所以在老版本中,ReactNative 总是被吐槽性能不好。特别是在一些需要高频交互的场景中,例如拖拽等表现不是很理想。
新的通信方式 JSI 的出现解决了通信成本高的问题。
JSI 是一个基于 C++ 编写的轻量级通信工具,他最厉害的地方就是能够让 JS 直接调用 native 的方法。也就是说,JS 可以非常轻松的持有 Native 方法的引用,从而低成本的直接调用 native 的方法。这种线程共享的方式极大的拉进了 JS 和 native 之间的距离,不在需要 JSON 序列化和反序列化这种极大损耗性能的操作。
新的 UI 渲染引擎:Fabric
得益于 JSI 能够直接调用 native 层的方法,新的渲染引擎使用 c++ 实现了核心渲染系统。
Fabric 的性能足以支撑渲染器同步得测量和渲染 React 界面。这使得我们在实现一些高频次交互的事件交互中可以获得足够流畅的体验。
Fabric 在底层使用 c++ 进行 diff 操作,从而让 diff 的执行效率也得到了极大的提高。除此之外,借助多优先级和事件同步的能力,渲染器可以自由的提高交互事件的优先级,从而确保它们的操作可以得到及时的处理。
Fabric 将 React 的更新逻辑深度集成到系统底层,使得 Suspense,Concurrent,Next.js 都能够得到更强的性能支持和实践落地。得益于 React 体系对不可变数据的严格践行,在类型安全上也得到了极大的保障。
新的垃圾回收逻辑:Hades
和过去就的 GenGC 只能在单个线程与解释器抢占执行资源不同,新的垃圾回收器 Hades 可以将回收工作在后台与 JavaScript 解释器同时执行。
这样做的好处就是你的应用程序不会因为垃圾回收而导致长时间的延迟,从感官上来说,程序的运行流畅度将会因此得到巨大的提升。
Hades 依然基于新生代和老生代的分配进行垃圾回收处理,但是不同的是,Hades 的老生代具有不同的分配策略。
这里主要的目的是为了能够在后台并行运行回收垃圾,因此 Hades 的老生代被设计为一个堆内存块的列表。例如一个堆内存块 8 个字节,这里我们可以把它理解为最小分配单位。这样做的好处是在内存分配上可以变得更快,坏处就是内存的利用并不充分,可能会出现空闲内存间隔无法被使用。 不过这是被允许的,因为我们更需要方便的并行去标记内存块,并回收他们,这是实现多线程并行回收的重要基础条件。由于回收得非常快,因此浪费的内存间隔是可以被允许的。
除此之外,也正是由于这个设计,我们可以把回收任务轻松的拆分为多个子任务,从而方便实现 React 中一致践行的并发模式,对于大任务的中断会非常友好。这也是 Hades 可以以极短的时间来暂停任务的核心原因,垃圾回收工作对程序的正常运行几乎不会有什么的影响。
上手即用的完整应用层框架:Expo
上面我分享的这些都比较偏底层,更多的是他们在性能上带来了非常大的提高。
Expo 则是在开发体验上带来的巨大提升。
在以前开发 React Native 最痛苦的,莫过于三方工具库的不成熟,从而导致了在调用系统级的能力时对开发人员的要求非常高,有的团队甚至还搞不定某些需求。
但是这些问题,都被 Expo 解决了。
Expo 已经发展成为了生态完整,上手即用的成熟框架。他对系统级的能力支持也非常完整,对于开发的门槛要求也变得非常低。
除此之外,它提供的沙箱能力,也能够低成本让你在真机调试自己开发的应用。所以,如果你的网络没有问题的话,使用 Expo 开发能够极大的减少上手成本。
可惜的是,它的利好更多的是在国外。国内的网络环境需要我们自己单独解决。因此,如果能力足够的话,可以选择自己散装,以获得更好的开发体验。
React Native IDE
React Native IDE 是最近才流行起来的一个专门为 React Native 开发调试而设计的一款高性能 VSCode 插件。
在 VSCode 插件中找到并安装之后,我们可以在 VSCode 中新增设备模拟器。这为我们开发和调试提供了极大的便利。
这个插件目前在国外非常火,但是在国内知道的人还不是很多。目前我也只是简单的体验了一下,确实感觉在开发调试上会方便很多。
✓目前还不够成熟,正式版也还没有发布
完善的 React 支持
因为隶属于一个团队,React Native 的发展与 React 的更新是同步进行的。因此我们可以在 React Native 中体验到所有 React 中提到的新特性。
所以 React 中的并发模式,React 中的 use + Suspense 等特性都可以在 React Native 中得到体验。
我们甚至还可以利用 Next.js 在 React Native 中感受服务端渲染的魅力。
由于我系统学习了 React 19,也因此深刻的感受到了 React 19 在开发体验上带来的巨大提升,这些开发体验都可以在 RN 中感受到,包括 React Compiler 也有机会运用在 RN 中。
开发体验一致的 tailwindcss 支持
终于可以不用在 React Native 中写 Styles 代码了。在我的感受中它非常不方便。这是以前我一直觉得 ReactNative 开发体验不好的主要原因。虽然这是一种 css in js 的方案,但是我觉得它甚至还不如 css 开发体验好。
我昨天花了一点时间,成功的在 React Native 中集成了 tailwindcss。编写的代码如下
起飞。
集成 tailwindcss 之后,有一个巨大的好处,就是我可以在所有类型的项目中,获得完全一致的开发体验。等我在此基础之上封装一套通用基础组件库,那我的开发就会变得比以往更加简单。
总结
React Native 生态现在已经比较成熟了。他的新架构在性能上的表现非常优秀。与此同时,他的开发体验也随着 React 新版本的发布将会迎来一次巨大的提升。对我个人来说,最关键的是,它的生态中获得了 tailwindcss 一致性开发体验的支持,因此我非常看好 React Native 的发展。
未来我将会不定期为大家分享 React Native 的开发知识,欢迎感兴趣的朋友持续关注我。