AirJD 焦点
AirJD

没有录音文件
00:00/00:00
加收藏

ReactNative实战优化之路 by 王少鸣@腾讯

发布者 mobile
发布于 1476070184595  浏览 6854 关键词 移动开发, Hybrid混合开发 
分享到

第1页

ReactNative实战优化之路

腾讯QQ空间 王少鸣



第3页

ReactNative

Android Developer

mangosmwang(王少鸣) QQ空间



第4页

About me

15年 至今[Qzone]移动终端开发

负责 Qzone 玩吧业务,专注Hybrid开发,[QQ Js SDK] 研发负责人,专注 ReactNative在Qzone与手Q的应用和推广。

14年 正式跨界移动端

负责碰一碰模块,后续带领团队完成语音广场的开发及微群组2.0上架

13年 加入腾讯

Web前端开发,负责QQ空间Web前端研发工作,参与研发[Qzone V8] ,经历了用户的井喷和Web技术的快速变革,主要完成V8升级引导过程。 智能终端[Qrobot]开发,负责机器内置帐号登录及监控视频上传,后续 单人负责整个项目维护及上架。



mango(王少鸣)



第5页

1.关于ReactNative



第6页

What ReactNative

ReactNative 让开发者使用 JavaScript 和 React 编写应用,利用相同的核心代码 就可以创建 基于Web,iOS 和 Android 平台的原生应用。Facebook 在 2015.9.15发布了 ReactNative for Android,把JavaScript 开发技术扩展到了 Android平台,至此已覆盖当流主流平台。

React Native

A FRAMEWORK FOR BUILDING NATIVE APPS USING REACT

Learn Once , Write Anywhere



第7页

Version of ReactNative



12/7/10



12/5/21



12/4/1 12/2/11



Qzone



11/12/23 11/11/3 11/9/14



QQ Qzone



11/7/26



11/6/6



11/4/17 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27



两个版本/月



第8页

Who Use ReactNative



第9页

Who Use ReactNative Inside



话题圈



情侣空间



留言板



消息流



资料卡



K歌大赛页



第10页

ReactNative 优劣对比

优势

原生控件的体验 Web的版本节奏 Web的开发效率 跨平台

劣势

版本支持度 Android 4.1 (API 16) & iOS 7.0 项目尚不成熟,容易Crash,部分机器存在兼容性问题 性能,在高低端机呈现两极 Android仅基于Gradle,目前业界较多大平台项目均基于 Ant,如Qzone,手Q等



第11页

ReactNative 整体流程



JsBundle1 Data/File



APP Launch



Http Header



SVR



JsBundle2



File ?



JsBundle1



JsBundle2



Render

JSC



第12页

ReactNative 原理

哈哈

JSC

Application Code

JS



Native UI 展示 解析JS,桥接JS<>Java

业务逻辑



<EmojText />



第13页

ReactNative For Android 架 构

Java



ReactCore Fresco



OkHttp



Support



Utils



{moduleID,methodID,args}

C++

JSC Bridge



JSLoader



{moduleID,methodID,args}

Utils



{moduleID,methodID,args}

Js



Component



Lifecycle



{moduleID,methodID,args}



Data



Layout



第14页

ReactNative 通信

.Java|.m

Video



.Js



Pic JavaRegistry



JavaRegistry



Share

AppRegistr y

EventEmitte r





+

JSRegistry



+

JSRegistry



__fbBatchedBridgeConfig



Video

Pic

Share

AppRegistr y

EventEmitte r





第15页

ReactNative For Android 通信 Java ->



Js



1 getJSModule



JavaScriptModuleRegistry



CatalystInstanceImpl



JavaScriptModule



JavaScriptModule



JavaScriptModule



invoke

2 3 callFunction

4 callFunction



JavaScriptModuleInvocationHandler ReactBridge



OnLoad.cpp



Bridge.cpp



JSCExecutor.cpp



JSCHelper.cpp



5 evaluateScript



Module.js



Module.js



Module.js



Module.js



MessageQueue.js



第16页

ReactNative For Android Launch



第17页

ReactNative For Android 通信 Js -> Java



Module1.js



Module2.js



Module3.js



Module4.js





EVENT





MessageQueue.js



CALL1



CALL2



CALL3



2 PUSH

CALL4



4 FLUSH 5 CALL



JavaRegistry



ModuleID



Arguments



MethodID



Module1.java



Module2.java



Module3.java



Module4.java



第18页

从<QzText>到QzTextView



QzTextViewManager

1 add

ReactInstanceManager CatalystInstance



QzTextViewShadowNode



12 return

QzTextView

11 createViewInstance 2 CreateAllViewManagers



CreateReactContext

processPackage



ReactPackage



4 UIManagerModule

CreateNativeModule



5 attachMeasuredRootViewToInstance



13 addView



6 setGlobalVariable



BatchBridge



QzText React



requireNativeComponent







createElement



render



component



UIManager



10 createView



第19页

2.从QQ空间到手机QQ



第20页

Pre Access to ReactNative

包大小

Android HelloWorld工程 约7m



业界尚未有真实外网数据,内 部仅能通过大量机器进行稳定 性测试,但未能覆盖所有机型



性能

业界尚未有真实外网数据 ,仅靠实验室有限数据支 撑





?

Plugin



稳定性





Android 4.1 (API 16) & iOS 7.0



Jsbundle与Native版本兼容



支持版本对机型兼容



兼容性



Jsbundle可能发生被拦截等情 况,容易导致Native Crash

安全性



第21页

Qzone情侣空间RN改造



插件化



+ 独立进程 +



云开关



APK预处理



Qzone切后台



Version



APK 需要更新







本地下载更新安装



Bundle预处理



点击我的空间



Header



bundle需要更 新







本地下载更新 bundle



点击情侣空间



WNS开关



Platform



RUN RN APP



jsbundle



apk



第22页

情侣空间开发流程



2015.10.16 2015.10.30 2015.11.13



第23页

RN情侣空间性能瓶颈· 首屏



插件及进程启动 RN上下文启动

首屏数据 Render



+ + + =插件及进程启动 2.1s



RN上下文启动 1.1s



首屏数据 2s



Render 0.9s



6.1s



第24页

RN情侣空间性能瓶颈· FPS

主观上没明显卡顿,中低端机对比老版本下降明显



第25页

RN话题圈业务开发· 模块梳理



第26页

Ant or Gradle



gradle资源编译问题



8-14 D



gradle分包问题



资源混淆问题



补丁包代码插桩,资源插桩等未接入



debug模式下某些变量的修改也需要加上



签名,checksum及其他还没想到的问题



结论:使用Ant来构建ReactNative



第27页

RN话题圈开发流程



Ant编译RNA



12.7



集成入Qzone



12.15



aar文件拆jar包 jar包&so迁移 project rebuild fix compile exception fix runtime exception



jar包&so迁移 project rebuild fix compile exception fix runtime exception

so精简



业务开发



12.28



模块梳理 API制定 开发联调 业务体验 bug fix



性能优化

包精简 首屏加速

FPS 内存



第28页

Ant编译RNA

Compile Exception

Error:Android Dex: [react_native] Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/facebook/react/BuildConfig;

解决方案:1.gen生成的BuildConfig与React本身jar包的BuildConfig冲突 2.将各模块改为lib模式 3.干掉各个个jar包中的BuildConfig drawee fbcore fresco imagepipeline imagepipelie-okhttp react,以上6个module的重复的cls均需要移除,移聊后重新构建jar包。

Runtime Exception

Error:Caused by: java.lang.VerifyError:com/facebook/react/views/ drawer/ReactDrawerLayoutManager

解决方案:将appcompat中的support v4 包以lib 工程的方式添加到工程中



第29页

RN话题圈业务开发· 接口制定



模块 QzMain QzShare



接口名 接口参数及返回



获取用户信息



@param {Object} params {Object}callback:回调



QzMain.getUserInfo({



getUserInfo



callback:{ code:0, msg:”SUCCESS”,



data:{nickName:”xxx”} }

});



获取QUA



@param {Object} params {Object}callback:回调



getQua



QzMain.getQua({ callback:{ code:0, msg:”SUCCESS”, data:{qua:”xxx”} }

});



调用分享弹框



showShareMen



@param {Object} params {Json}extra:预留参数,



u 目前可为空



QzShare.showShareMenu({ });



iOS 6.3

6.3 6.3



Android 6.2

6.2 6.2



第30页

RN话题圈业务开发· 整体流程



预加载



启动Qzone



feeds渲染完毕



预初始化React上下文



点击发现



WNS Config



Header带上本地上一次下载jsbundle的last-modify-since



Platform



带上登录态,客户端预拉首屏数据



CPU



优先使用SDCard,不存在用 Assets



jsbundle



CDN SVR CGI SVR



render



RUN RN



第31页

RN话题圈性能优化 · FPS

优化后



第32页

ReactNative For Android 启 动



ReactRootView



ReactInstance Manager



startReactApplication



JavaScriptExecutor



ReactContextInitAsyncTask



JSBundleLoader



137createReactContext





doInBackground



onPostExecute



setupReactContext



NativeModul JavaScriptModule CoreModule



eRegistry



Config



Package



ReactPackage



CatalystInstance



ReactApplicatio nContext



CatalystInstance



NativeModule



JsModule



ReactBridge



initializeWithInstance



JSBundleLoader



UIManager Module



AppRegistry



插件及进程启UIM动an0asger

+Module







上A下pp文Re启gis动tr

y



0.4…8s



setGlobalVariable



loadScript



+ +首屏数据 2s



189 291

= 3.38sRenattdacehMr e0as.9ursedRootView runApplication



第33页

RN话题圈性能优化· 首屏数据加速



优化前



Click Tab



Native CXT



Web CXT



前端发起

HTTP REQ



HTTP RSP



Render



优化后



Feeds Rendered



PreInit Native CXT



Cache Context



Click Tab



终端发起

Native WNS REQ



Native WNS RSP



Cache Data



Native CXT



WEB CXT



DataModule



Callback



HTTP REQ



HTTP RSP



Render



第34页

RN话题圈性能优化 · FPS

UI

减少View层级嵌套 合理设置背景色透明

JS

JS层使Listview控件渲染数据,废弃使用ScrollView控件 避免滑动做过多事情,减少JS线程掉帧



第35页

RN话题圈性能优化 · FPS



优化后



高低端手机上差异明显,RN有明显的劣势



高低端手机上基本无差异



第36页

RN话题圈性能优化· 包精简方案



SO



放弃对X86等支持 借用TBS能力,移除JSC



17.2MM

2.3 m

1.4 m



Java



去除暂时不需要Module&UIManager Release 去除Dev Support



120 k



Jar Res



对接平台网络库(WNS,MSF),移除OKHTTP627 k 对接平台图片库(ImageManager),移除Fresco



平台 Support 阉割库 复用补齐



1.1 m



移除无用的Res文件,language val 平台 Support Res复用补齐



242 k



第37页

RN话题圈外网Crash

SO

Cookie操作导致在so层SIGSEGV的crash

解决方案:1.(当前是通过直接修改源码屏蔽getCookie操作)

So兼容问题导致crash

(42,478) could find DSO to load: libreactnativejni.so (12,647) com.facebook.react.bridge.WritableNativeMap.void putString 解决方案:1.根据需要升级React版本。2.屏蔽机型。

Java

AssertError

解决方案:在正式发布需要去除,根治由Assert引起的Crash。



第38页

RN话题圈外网Crash

JS

view property 转换导致Crash

(15,972) Error while updating property 'text' in shadow node of type: RCTRawText (11,621) Error while updating property 'height' in shadow node of type: RCTView

JsFrameWork Exception

(8,168)com.facebook.react.modules.core.JavascriptException: recordEndTouchData



第39页

RN话题圈数据对比



话题圈对比项



jsbridge调用耗时



wifi + Cache



首屏



wifi



2g



AVG FPS



内存



CPU峰值



增加包大小



ReactNative 185ms 1.504s 2.875s 5.93s 52 81m 57.9% 3.2m



H5(WNS-HTML) 417ms 1.608s 2.322s 6.179s 54 80m 62.5% 0m



H5 421ms 2.781s 2.868s 12.65

55 80m 53% 0m



第40页

结合版空间 留言板改造



分包

Base.zip



Jsbundle



Busi.zip



独立进程处理JNI



So层占用内存无法释放



AIDL转发JNI层接口



APK离线包

包大小增量配额



预加载



第41页

RN留言板数据对比



留言板



Android(note3&Mi2) RN H5



wifi + Cache 432.3



825.6



wifi 首屏

3g + Cache



1141.5 430.2



4084.2 1325.5



3g



10171.4





AVG FPS 58 57



MIN FPS



54 51



CPU峰值



49%



35%



Mem



161m



154.9m



增加包大小



约30k(压后)





iOS(5s)



RN H5



142.4



261.5



1010.4



1669.8



154.7



1166.8







54.5



54.8



51 48



50.5%



54.5%



185.7



145.3



约97k(压前)





第42页

3.再多说几句



第43页

ReactNative· DEV Tools

ReactNative Tools adb logcat *:S ReactNative:V ReactNativeJS:V Developer menu.

System Tools 调试GPU过度绘制 GPU呈现模式

Android Tools TraceView Memory Monitor TraceView SysTrace



第44页

小经验分享 · BUG

Problem

在小米系手机出现文字缺失情况 ,终端使用HierarchyView查看 ,发现宽度及文本正常,属于 ROM级Bug。

Solution



第45页

Q&A

?



第46页

Thanks

mangosmwang(王少鸣) QQ空间



支持文件格式:*.pdf
上传最后阶段需要进行在线转换,可能需要1~2分钟,请耐心等待。