39

React Native应用性能瓶颈分析和优化

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzI1NDc5MzIxMw%3D%3D&%3Bmid=2247488782&%3Bidx=1&%3Bsn=937fb50b7c78a80226e4001ae1a8b72c
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

导语

本文结合React Native跨平台框架的应用工作原理,分析性能瓶颈,分享实践中的优化性能问题内容输入。

背景

随着移动互联网的高速发展,在很多的业务场景下,传统的纯原生开发已经不能满足日益增长的业务需求。为了提升开发效率,使APP具备动态化能力,同时提升用户体验,项目中引入了React Native框架。使用过程中发现部分React Native页面性能存在一些问题,尤其是复杂页面渲染性能较差,于是决定深入调研和解决这些问题。

React Native工作原理

1.概览

React Native的页面使用JavaScript编写,在JavaScript虚拟机里运行,JavaScript标签/组件最终会被解析为iOS和Android端的View,从而实现跨平台。JavaScript代码运行在一个后台线程,也就是JavaScript虚拟机运行的线程,而不是主线程。这样设计的初衷是为了防止主线程被JavaScript代码执行阻塞,保持UI界面更流畅。JavaScript线程和主线程之间的交互是异步的。

ieaiMf.png!web

React Native概览

2. 定位问题和优化思路

一个React Native页面生命周期,一般包括初始化,加载数据,页面渲染,事件响应,页面刷新,销毁等几个过程。接下来将逐一分析这几个过程中,可能存在的性能瓶颈和优化思路。

2.1 页面初始化

页面初始化时,React Native框架会先从本地文件系统加载JavaScript Bundle文件,并执行文件里的JavaScript代码。

性能瓶颈:

⦁ JavaScript文件加载

⦁ JavaScript代码执行

优化思路:

⦁ JavaScript Bundle拆包,把公用基础代码抽取出来,每次打开页面,只加载业务代码,减少文件大小,同时也可以减少代码执行量。

⦁ 可以考虑使用JS Byte Code,加快JavaScript代码执行速度。

2.2 加载数据

React Native页面加载数据,一般由JavaScript端组装参数,Native端发起网络请求,再将结果返回给JavaScript端。

性能瓶颈:

⦁ 一般JavaScript端组装参数的时候,可能需要从Native端读取数据,会涉及一次或多次JavaScript-Native通信,这个过程是异步的,如果涉及到数据传输,则会经历JS Object->String->Native Object和Native Object->String->JS Object(JSON序列化和反序列化)两个过程,比较耗时。

⦁ 网络请求数据

优化思路:

⦁ 尽量避免每次加载数据时,JavaScript端都要从Native端读取数据,最好有一套比

2.3   页面渲染

先看一下React Native页面渲染过程

uUjAbiZ.png!web

React Native页面渲染过程

⦁APP启动,主线程初始化React Native框架。

⦁主线程创建Bridge,加载JavaScript文件。

⦁JavaScript线程解析执行JavaScript代码,生成DOM Tree结构。

⦁Shadow Thread处理样式信息,生成layout数据,生成Shadow Tree。

⦁主线程根据Shadow Tree的层级关系,和layout数据,创建Native View。

⦁主线程渲染Native View。

性能瓶颈:

React Native页面渲染,经历了多次线程切换和JavaScript-Native通信,组件渲染也是顺序进行,虽然是批量操作,但是无法并发渲染。

优化思路:

尽量减少页面的组件数量和嵌套关系,复杂的页面结构,大量的组件嵌套,首次渲染的时候,会非常慢,会出现明显白屏现象。

2.4 事件响应

R7riQfZ.png!web

React Native事件响应

⦁Native捕捉到Touch,Timer,网络等Event。

⦁Native负责组装数据。

⦁Native通过Bridge将数据序列化为JSON String,传递给JavaScript。

⦁JavaScript反序列化JSON为JavaScript Object,处理Event。

⦁JavaScript组装数据,序列化JSON String,通过Bridge 回调Native方法。

⦁Bridge反序列化JSON为Native Object,执行Native方法。

⦁刷新UI。

性能瓶颈:

在React Native中,Native端负责捕捉事件,通知JavaScript端处理,处理完毕之后,再通知Native端刷新UI。一次事件处理,包括了两次JavaScript-Native通信。

而JavaScript是单线程执行的,如果JavaScript处理逻辑太多,则会出现用户响应不及时。

化思路

在一些事件交互比较多的场景(比如长列表滑动/动画),尽量把大量计算逻辑(cell生命周期维护/动画每一帧属性计算)移到Native端执行,减少JavaScript线程的工作量,避免每一帧都要和Native进行通信。

React Native性能优化实践

1. 信息中心

为了减少JavaScript-Native通信的次数,我们设计了信息中心模块。

JavaScript环境和Native环境各自维护一些状态数据,这些数据互补可见,但是双方都有读取和同步状态数据需要,为了减少JavaScript-Native数据交互次数,我们开发出信息中心模块。

信息中心的目的是建立一种数据同步机制,减少JavaScript-Native的不必要数据交互。

Q32Mza2.png!web

信息中心

我们把需要两端共享的数据分为不变数据,定时更新数据,实时更新数据三种类型,针对不同的数据采用不同的数据同步策略。

⦁不变数据:设备信息,系统信息,软件信息等。

⦁定时更新数据:对精确度要求不高的数据,比如位置信息。

⦁实时更新数据:登录态,网络状态等。

避免每次读取JavaScript或Native数据时,都发起一次数据交互请求,

开发者也不必再关系数据同步问题,降低了开发复杂度。

2. Native驱动的列表页

为了解决React Native长列表页,内存占用大,卡顿,容易白屏的问题,我们设计Native驱动列表组件。

React Native列表页,用户交互比较多,列表Cell的生命周期(创建,展示,刷新,移除,销毁)都是JavaScript端维护,Native端把列表的滚动状态实时传递给JavaScript端,JavaScript维护Cell的生命周期,再通知Native端刷新UI,多次事件交互,导致RN原生列表页性能差,快速滑动有白屏现象。为了减少,JavaScript线程计算压力,减少JavaScript-Native交互,我们推出了Native驱动列表。

VbuYFbE.png!web

Native驱动的列表页

Native驱动列表的优势在于,JavaScript只提供数据源和Cell模版,Cell生命周期由Native维护,减少JavaScript线程计算压力,渲染更快,没有JavaScript-Shadow-Main线程切换,减少JavaScript-Native的事件交互次数,支持Cell回收/重用,节省内存,提升速度,流畅度更高,接近Native原生列表,兼容旧系统的JavaScript Cell模版。

总结

React Native应用JavaScript线程和主线程,任何一个线程被阻塞,都会导致卡顿和掉帧现象。JavaScript端在处理完事件响应或数据更新时,需要通知Native端重新渲染UI,这个过程是异步的,因此会略有延迟。在React Native现在的框架下,主要优化思路就是减少不必要的组件重绘,减少不必要的JavaScript-Native通信,减少JavaScript线程的计算压力,可以把一些原先在JavaScript执行的任务,移植到Native端执行,实现由JavaScript驱动到Native驱动,都会带来显著性能提升。

参考文献

1.   https://www.freecodecamp.org/news/how-react-native-constructs-app-layouts-and-how-fabric-is-about-to-change-it-dd4cb510d055/

2.   https://tech.showmax.com/2018/05/react-native-or-not-react-native/

3.   https://reactnative.cn/docs/performance/

4.   https://www.simform.com/react-native-app-performance/

作者简介

禹潇潇  58集团  HRG技术部 

阅读推荐

1.58安居客小程序平台化与多小程序开发探索与实践

2.金融数仓体系建设

3.数据智能在二手车业务场景中的探索与沉淀-Part2业务标签的挖掘

4.预算平滑技术在58商业的探索与实践

5.房产经纪人页面错误信息采集方案

Nb2iMvQ.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK