第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空间