在本地开发时, React Native 是加载本地Node服务, 可以通过npm start 启动, package.json 代码如下:
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
}
加载的地址为:http://localhost:8081/debug.android.bundle?platform=android&dev=true&hot=false&minify=false
首次在电脑上面打开该地址,被庞大的源代码吓一跳。一个简单的HelloWorld App 足足有5万多行JS代码(开发模式)。仔细分析和梳理调用流程后,也没有那么的恐怖。代码主要包括React源码, 所有初始化定义的Native组件定义,Bridge层调用相关的MessageQueue,NativeModules,原生JS常用方法polyfill等代码定义实现。
如果是正式发布包,在应用运行时,是不存在本地nodejs服务器这个概念的,所以JS整合文件都是预先打包到asset资源文件里的,减少网络下载JS耗时。当然也可以从网络下载JSBundle,这时就需要考虑首次启动下载JSBundle的网络耗时和下载失败的情况处理。在项目开发时,其实可以在打包时内置一份JSBundle文件,然后启动后异步去下载最新JSBundle,下次启动时就可以加载新的JSBundle。
针对如此庞大的JSBundle文件,首次启动加载和解析的性能如何呢?
一.远程本地调试
通过创建ReactInstanceManager.builder 设置setUseDeveloperSupport(true)支持远程本地调试。
远程调试时,如果是通过Android studio 打包时,可以先通过npm start启动启动本地服务,启动后服务地址:
http://localhost:8081/debug.android.bundle?platform=android&dev=true&hot=false&minify=false
如果想加载asset下的JSBundle文件,需要先把JSBundle打到本地assets目录下面,可以通过react-native bundle实现。命令自动会分析图片依赖,然后拷贝到res目录下面。
react-native bundle --entry-file ./index.android.js --bundle-output ./app/src/main/assets/index.android.jsbundle --platform android --assets-dest ./app/src/main/res/ --dev false
然后setUseDeveloperSupport(false),之后重新打包即可。
二.远程加载JSBundle文件
在ReactInstanceManager
类里面提供了setJSBundleFile
方法,这个就是动态更新的入口.
public Builder setJSBundleFile(String jsBundleFile) {
mJSBundleFile = jsBundleFile;
return this;
}
由于React Native加载的js文件都打包在bundle中,通过这个方法,可以设置app加载的bundle来源。若检测到远端存在更新的bundle文件,下载好后重新加载即可。
在ReactInstanceManager
类里面提供了recreateReactContextInBackground
方法, 可以通过调用该方法重新加载JSBundle文件.
private void recreateReactContextInBackground(JavaScriptExecutor jsExecutor, JSBundleLoader jsBundleLoader) {
UiThreadUtil.assertOnUiThread();
ReactContextInitParams initParams = new ReactContextInitParams(jsExecutor, jsBundleLoader);
if (!mIsContextInitAsyncTaskRunning) {
// No background task to create react context is currently running, create and execute one.
ReactContextInitAsyncTask initTask = new ReactContextInitAsyncTask();
initTask.execute(initParams);
mIsContextInitAsyncTaskRunning = true;
} else {
// Background task is currently running, queue up most recent init params to recreate context
// once task completes.
mPendingReactContextInitParams = initParams;
}
}
目前该方法访问权限上private,需要通过反射才能调用, 希望未来 React Native 能够从官方支持. 代码如下:
private void onJSBundleLoadedFromServer() {
try {
Class<?> RIManagerClazz = mReactInstanceManager.getClass();
Method method = RIManagerClazz.getDeclaredMethod("recreateReactContextInBackground", JavaScriptExecutor.class, JSBundleLoader.class);
method.setAccessible(true);
method.invoke(mReactInstanceManager, new JSCJavaScriptExecutor(),
JSBundleLoader.createFileLoader(getApplicationContext(), JS_BUNDLE_LOCAL_PATH));
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
三.开启ReactNative日志打印
React Native 增加了关键日志自定义listener回调接口MarkerListener,只要在React Activity onCreate设置ReactMarker.setMarkerListener方法,
实现MarkerListener接口logMarker方法,即可实现控制台日志打印。我们可以记录下每个关键路径的当前时间,即可计算出每个关键路径的执行时间。
ReactMarker.setMarkerListener(new ReactMarker.MarkerListener(){
@Override
public void logMarker(String name) {
Log.i("ReactNativeJS", name.toLowerCase() + " cost:" + System.currentTimeMillis());
}
});
09-03 20:33:47.637 I/ReactNativeJS: process_packages_end cost:1472387627637
09-03 20:33:47.637 I/ReactNativeJS: build_native_module_registry_start cost:1472387627637
09-03 20:33:47.639 I/ReactNativeJS: build_native_module_registry_end cost:1472387627639
09-03 20:33:47.646 I/ReactNativeJS: create_catalyst_instance_start cost:1472387627646
09-03 20:33:47.688 I/ReactNativeJS: create_catalyst_instance_end cost:1472387627688
09-03 20:33:47.688 I/ReactNativeJS: run_js_bundle_start cost:1472387627688
09-03 20:33:47.717 I/ReactNativeJS: loadapplicationscript_startstringconvert cost:1472387627717
09-03 20:33:47.833 I/ReactNativeJS: loadapplicationscript_endstringconvert cost:1472387627832
09-03 20:33:48.787 I/ReactNativeJS: create_react_context_end cost:1472387628786
09-03 20:33:48.787 I/ReactNativeJS: run_js_bundle_end cost:1472387628787
四.简单的React Native View创建流程
1.React View源码
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
{this.state.text}
</Text>
<TouchableOpacity activeOpacity={0.8} onPress={this._getJSNativeCost}>
<Text style={styles.instructions}>
点击我,测试JS调用Native性能
</Text>
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.8} onPress={this._setCache}>
<Text style={styles.instructions}>
点击我,设置缓存测试
</Text>
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.8} onPress={this._getCache}>
<Text style={styles.instructions}>
点击我,获取缓存值
</Text>
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.8} onPress={this._secondActivity}>
<Text style={styles.instructions}>
点击我,打开Android Native Activity页面
</Text>
</TouchableOpacity>
<TouchableOpacity activeOpacity={0.8} onPress={this._secondReactActivity}>
<Text style={styles.instructions}>
点击我,打开Android Second React Activity页面
</Text>
</TouchableOpacity>
<Text style={styles.instructions}>
Shake or press menu button for dev menu
</Text>
</View>
);
}
2.React bundle.js 打包构建后
{key:'render',value:function render()
{
return(
_react2.default.createElement(_reactNative.View,{style:styles.container},
_react2.default.createElement(_reactNative.Text,{style:styles.welcome},
this.state.text),
_react2.default.createElement(_reactNative.TouchableOpacity,{activeOpacity:0.8,onPress:this._getJSNativeCost},
_react2.default.createElement(_reactNative.Text,{style:styles.instructions},'点击我,测试JS调用Native性能')),
_react2.default.createElement(_reactNative.TouchableOpacity,{activeOpacity:0.8,onPress:this._setCache},
_react2.default.createElement(_reactNative.Text,{style:styles.instructions},'点击我,设置缓存测试')),
_react2.default.createElement(_reactNative.TouchableOpacity,{activeOpacity:0.8,onPress:this._getCache},
_react2.default.createElement(_reactNative.Text,{style:styles.instructions},'点击我,获取缓存值')),
_react2.default.createElement(_reactNative.TouchableOpacity,{activeOpacity:0.8,onPress:this._secondActivity},
_react2.default.createElement(_reactNative.Text,{style:styles.instructions},'点击我,打开Android Native Activity页面')),
_react2.default.createElement(_reactNative.TouchableOpacity,{activeOpacity:0.8,onPress:this._secondReactActivity},
_react2.default.createElement(_reactNative.Text,{style:styles.instructions},'点击我,打开Android Second React Activity页面')),
_react2.default.createElement(_reactNative.Text,{style:styles.instructions},'Shake or press menu button for dev menu')));
}}
3.Native View创建之JS调用Native
09-03 20:19:19.462 Running application "SmartDebugReactApp" with appParams: {"initialProps":{},"rootTag":1}. __DEV__ === true, development-level warning are ON, performance optimizations are OFF
09-03 20:19:19.526 'JS->N : ', 8, 18, 'NaN.createView([2,"RCTView",1,{"flex":1}])'
09-03 20:19:19.545 'JS->N : ', 8, 18, 'NaN.createView([3,"RCTView",1,{"collapsable":true,"flex":1}])'
09-03 20:19:19.584 'JS->N : ', 28, 1, 'NaN.createTimer([2,1,1472386759583,false])'
09-03 20:19:19.706 'JS->N : ', 8, 18, 'NaN.createView([4,"RCTView",1,{"flex":1,"justifyContent":"center","alignItems":"center","backgroundColor":-656129}])'
09-03 20:19:19.721 'JS->N : ', 8, 18, 'NaN.createView([5,"RCTText",1,{"fontSize":20,"textAlign":"center","margin":10,"color":-65536,"accessible":true,"allowFontScaling":true,"ellipsizeMode":"tail"}])'
09-03 20:19:19.732 'JS->N : ', 8, 18, 'NaN.createView([6,"RCTRawText",1,{"text":"Welcome to React Native!"}])'
09-03 20:19:19.738 'JS->N : ', 8, 9, 'NaN.setChildren([5,[6]])'
09-03 20:19:19.768 'JS->N : ', 8, 18, 'NaN.createView([7,"RCTView",1,{"accessible":true,"opacity":1}])'
09-03 20:19:19.777 'JS->N : ', 8, 18, 'NaN.createView([8,"RCTText",1,{"textAlign":"center","color":-13421773,"marginTop":15,"marginBottom":5,"fontSize":14,"accessible":true,"allowFontScaling":true,"ellipsizeMode":"tail"}])'
09-03 20:19:19.779 'JS->N : ', 8, 18, 'NaN.createView([9,"RCTRawText",1,{"text":"点击我,测试JS调用Native性能"}])'
09-03 20:19:19.782 'JS->N : ', 8, 9, 'NaN.setChildren([8,[9]])'
09-03 20:19:19.783 'JS->N : ', 8, 9, 'NaN.setChildren([7,[8]])'
09-03 20:19:19.801 'JS->N : ', 8, 18, 'NaN.createView([10,"RCTView",1,{"accessible":true,"opacity":1}])'
09-03 20:19:19.810 'JS->N : ', 8, 18, 'NaN.createView([12,"RCTText",1,{"textAlign":"center","color":-13421773,"marginTop":15,"marginBottom":5,"fontSize":14,"accessible":true,"allowFontScaling":true,"ellipsizeMode":"tail"}])'
09-03 20:19:19.812 'JS->N : ', 8, 18, 'NaN.createView([13,"RCTRawText",1,{"text":"点击我,设置缓存测试"}])'
09-03 20:19:19.813 'JS->N : ', 8, 9, 'NaN.setChildren([12,[13]])'
09-03 20:19:19.814 'JS->N : ', 8, 9, 'NaN.setChildren([10,[12]])'
09-03 20:19:19.834 'JS->N : ', 8, 18, 'NaN.createView([14,"RCTView",1,{"accessible":true,"opacity":1}])'
09-03 20:19:19.849 'JS->N : ', 8, 18, 'NaN.createView([15,"RCTText",1,{"textAlign":"center","color":-13421773,"marginTop":15,"marginBottom":5,"fontSize":14,"accessible":true,"allowFontScaling":true,"ellipsizeMode":"tail"}])'
09-03 20:19:19.851 'JS->N : ', 8, 18, 'NaN.createView([16,"RCTRawText",1,{"text":"点击我,获取缓存值"}])'
09-03 20:19:19.851 'JS->N : ', 8, 9, 'NaN.setChildren([15,[16]])'
09-03 20:19:19.854 'JS->N : ', 8, 9, 'NaN.setChildren([14,[15]])'
09-03 20:19:19.881 'JS->N : ', 8, 18, 'NaN.createView([17,"RCTView",1,{"accessible":true,"opacity":1}])'
09-03 20:19:19.890 'JS->N : ', 8, 18, 'NaN.createView([18,"RCTText",1,{"textAlign":"center","color":-13421773,"marginTop":15,"marginBottom":5,"fontSize":14,"accessible":true,"allowFontScaling":true,"ellipsizeMode":"tail"}])'
09-03 20:19:19.894 'JS->N : ', 8, 18, 'NaN.createView([19,"RCTRawText",1,{"text":"点击我,打开Android Native Activity页面"}])'
09-03 20:19:19.895 'JS->N : ', 8, 9, 'NaN.setChildren([18,[19]])'
09-03 20:19:19.896 'JS->N : ', 8, 9, 'NaN.setChildren([17,[18]])'
09-03 20:19:19.914 'JS->N : ', 8, 18, 'NaN.createView([20,"RCTView",1,{"accessible":true,"opacity":1}])'
09-03 20:19:19.924 'JS->N : ', 8, 18, 'NaN.createView([22,"RCTText",1,{"textAlign":"center","color":-13421773,"marginTop":15,"marginBottom":5,"fontSize":14,"accessible":true,"allowFontScaling":true,"ellipsizeMode":"tail"}])'
09-03 20:19:19.927 'JS->N : ', 8, 18, 'NaN.createView([23,"RCTRawText",1,{"text":"点击我,打开Android Second React Activity页面"}])'
09-03 20:19:19.932 'JS->N : ', 8, 9, 'NaN.setChildren([22,[23]])'
09-03 20:19:19.935 'JS->N : ', 8, 9, 'NaN.setChildren([20,[22]])'
09-03 20:19:19.941 'JS->N : ', 8, 18, 'NaN.createView([24,"RCTText",1,{"textAlign":"center","color":-13421773,"marginTop":15,"marginBottom":5,"fontSize":14,"accessible":true,"allowFontScaling":true,"ellipsizeMode":"tail"}])'
09-03 20:19:19.945 'JS->N : ', 8, 18, 'NaN.createView([25,"RCTRawText",1,{"text":"Shake or press menu button for dev menu"}])'
09-03 20:19:19.946 'JS->N : ', 8, 9, 'NaN.setChildren([24,[25]])'
09-03 20:19:19.950 'JS->N : ', 8, 9, 'NaN.setChildren([4,[5,7,10,14,17,20,24]])'
09-03 20:19:19.951 'JS->N : ', 8, 9, 'NaN.setChildren([3,[4]])'
09-03 20:19:19.962 'JS->N : ', 8, 18, 'NaN.createView([26,"RCTView",1,{"collapsable":true,"position":"absolute"}])'
09-03 20:19:19.963 'JS->N : ', 8, 9, 'NaN.setChildren([2,[3,26]])'
09-03 20:19:19.964 'JS->N : ', 8, 9, 'NaN.setChildren([1,[2]])'
09-03 20:19:19.976 'JS->N : ', 24, 0, 'NaN.getDataFromIntent([0,1])'
09-03 20:19:19.978 'JS->N : ', 1, 1, 'NaN.show(["Toast 是原生支持的!",3000])'
09-03 20:19:20.056 'JS->N : ', 8, 12, 'NaN.updateView([6,"RCTRawText",{"text":"注意:数据为空!"}])'
五.性能测试
1.React Native 简单测试JS调用Native接口性能
准备三组测试数据:
第一组(简单): key: 随机生成 value: 我是来自React Native缓存消息
第二组(长字符): key: 随机生成 value: 我是来自React Native缓存消息(循环50遍)
第二组(JSON): key: 随机生成 value: 下面JSON字符串,循环10遍, 内容不重复
{
"id": 000001,
"title": "React Native接口性能测试",
"summary": "炫斗不停,精彩不断,不要怂就是干的全武将萌化翻转扮演的新式三国策略养成手游《女神三国》邀您...",
"category": "React Native",
"createTime": "2016-09-09 17:48:38",
"publicTime": "2016-09-09 17:48:00"
}
@ReactMethod
public void setCache(String key, String value, Callback successCallback, Callback errorCallback) {
try {
sharedPreference = getCurrentActivity().getSharedPreferences("rn_cache", 0);
sharedPreference.edit().putString(key, value).commit();
successCallback.invoke("save success");
} catch (Exception e) {
e.printStackTrace();
errorCallback.invoke(e.getMessage());
}
}
//Java中的方法需要导出才能给JS使用,要导出Java方法,需要使用@ReactMethod来注解,且方法的返回值只能是void。
@ReactMethod
public void getCache(String key, Callback callback) {
callback.invoke(sharedPreference.getString(key, ""));
}
const start = +new Date();
NativeModules.IntentModule.getCache('RN001',(value)=>{
const time = +new Date()-start;
console.log('>>>>cost[getCache]:', time);
NativeModules.ToastAndroid.show(value+' cost:'+ time, 3000)
});
Native收到JS传递过来的值直接返回给JS, 经过多次对三组进行测试(Nexus 5 Android 5.0, MX3 5.0),时间稳定在2-4ms, 偶尔会出现5ms, 数据的大小对接口调用耗时影响不大.
2.WebView addJavascriptInterface 接口测试
@JavascriptInterface
public void setCache(String key, String value) {
try {
sharedPreference = context.getSharedPreferences("rn_cache", 0);
sharedPreference.edit().putString(key, value).commit();
} catch (Exception e) {
e.printStackTrace();
}
}
@JavascriptInterface
public String getCache(String key) {
return sharedPreference.getString(key, "");
}
function getCache() {
var start = +new Date();
var ret = HybridApp.getCache('RN001');
var end = +new Date();
var str = '>>>cost[getCache]:' + (end - start) + ' result:' + ret;
console.log(str);
}
JS从Native获取数据, 经过多次进行三组数据测试(Nexus 5 Android 5.0),时间稳定在0-3ms, 多次点击后,时间更短,时间稳定范围0s-1s,说明Interface有缓存机制和数据的大小对接口调用耗时影响不大.
3.WebView prompt 接口测试
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
result.confirm(message);
return true;
}
经过多次对三组进行数据进行测试(Nexus 5 Android 5.),时间稳定在1-2ms,数据的大小对接口调用耗时影响不大
4.三种方式耗时总结
从测试效果来看, 三种方式接口调用耗时都在1s-4s级别, 性能表现都非常不错. React Native因为进行了接口封装转换, 比addJavascriptInterface和prompt方式都是简单的数据透传返回要慢1ms-2ms是可以预期的.
说明: 这里只是简单的接口调用测试, 当前运行环境(Native线程切换,Native数据获取方式,数据回调方式等)都可能会影响实际的接口调用耗时.
2.React Native 首次加载性能测试
Nexus5 5.0系统测试
第一次测试
09-08 20:41:39.002 12023-12023/com.react.smart I/ReactNativeJS﹕ >>>react performance react start:1473338499002
09-08 20:41:39.081 12023-12023/com.react.smart I/ReactNativeJS﹕ >>>react performance react end:1473338499081
09-08 20:41:39.601 12023-12052/com.react.smart I/ReactNativeJS﹕ >>>react[runApplication]:1473338499600
09-08 20:41:39.618 12023-12052/com.react.smart I/ReactNativeJS﹕ >>>react#constructor, 1473338499616
09-08 20:41:39.618 12023-12052/com.react.smart I/ReactNativeJS﹕ >>>react#componentWillMount, 1473338499618
09-08 20:41:39.711 12023-12052/com.react.smart I/ReactNativeJS﹕ >>>react#componentDidMount, 1473338499711
cost:1473338499711-1473338499002=709ms
第二次测试
09-08 20:45:42.774 14935-14935/com.react.smart I/ReactNativeJS﹕ >>>react performance react start:1473338742774
09-08 20:45:42.806 14935-14935/com.react.smart I/ReactNativeJS﹕ >>>react performance react end:1473338742806
09-08 20:45:43.300 14935-14965/com.react.smart I/ReactNativeJS﹕ >>>react[runApplication]:1473338743299
09-08 20:45:43.320 14935-14965/com.react.smart I/ReactNativeJS﹕ >>>react#constructor, 1473338743319
09-08 20:45:43.321 14935-14965/com.react.smart I/ReactNativeJS﹕ >>>react#componentWillMount, 1473338743321
09-08 20:45:43.471 14935-14965/com.react.smart I/ReactNativeJS﹕ >>>react#componentDidMount, 1473338743471
cost:1473338743471-1473338742774=697ms
第三次测试
09-08 20:41:39.002 12023-12023/com.react.smart I/ReactNativeJS﹕ >>>react performance react start:1473338499002
09-08 20:41:39.081 12023-12023/com.react.smart I/ReactNativeJS﹕ >>>react performance react end:1473338499081
09-08 20:41:39.601 12023-12052/com.react.smart I/ReactNativeJS﹕ >>>react[runApplication]:1473338499600
09-08 20:41:39.618 12023-12052/com.react.smart I/ReactNativeJS﹕ >>>react#constructor, 1473338499616
09-08 20:41:39.618 12023-12052/com.react.smart I/ReactNativeJS﹕ >>>react#componentWillMount, 1473338499618
09-08 20:41:39.711 12023-12052/com.react.smart I/ReactNativeJS﹕ >>>react#componentDidMount, 1473338499711
cost:1473338499711-1473338499002=709ms
第四次测试
09-08 20:50:46.781 14935-14935/com.react.smart I/ReactNativeJS﹕ >>>react performance react start:1473339046781
09-08 20:50:46.789 14935-14935/com.react.smart I/ReactNativeJS﹕ >>>react performance react end:1473339046789
09-08 20:50:47.213 14935-18051/com.react.smart I/ReactNativeJS﹕ >>>react[runApplication]:1473339047213
09-08 20:50:47.231 14935-18051/com.react.smart I/ReactNativeJS﹕ >>>react#constructor, 1473339047229
09-08 20:50:47.231 14935-18051/com.react.smart I/ReactNativeJS﹕ >>>react#componentWillMount, 1473339047231
09-08 20:50:47.327 14935-18051/com.react.smart I/ReactNativeJS﹕ >>>react#componentDidMount, 1473339047327
cost:1473339047327-1473339046781=546ms
从测试结果来看, Nexus5 时间稳定在500ms-700ms之间, 时间可以接受.
MX3 5.0系统测试
第一次测试
09-11 16:51:36.967 10179-10179/com.react.smart I/ReactNativeJS﹕ >>>react performance react start:1473583896967
09-11 16:51:37.091 10179-10179/com.react.smart I/ReactNativeJS﹕ >>>react performance react end:1473583897091
09-11 16:51:38.349 10179-10209/com.react.smart I/ReactNativeJS﹕ '>>>react#constructor', 1473583898342
09-11 16:51:38.350 10179-10209/com.react.smart I/ReactNativeJS﹕ '>>>react#componentWillMount', 1473583898349
09-11 16:51:38.523 10179-10209/com.react.smart I/ReactNativeJS﹕ '>>>react#componentDidMount', 1473583898523
09-11 16:51:38.528 10179-10209/com.react.smart I/ReactNativeJS﹕ '>>>react#componentDidMount#ToastAndroid.show', 1473583898527
cost:1473583898527-1473583896967=1560ms
第二次测试
09-11 16:53:48.688 11260-11260/com.react.smart I/ReactNativeJS﹕ >>>react performance react start:1473584028688
09-11 16:53:48.887 11260-11260/com.react.smart I/ReactNativeJS﹕ >>>react performance react end:1473584028887
09-11 16:53:50.345 11260-11292/com.react.smart I/ReactNativeJS﹕ '>>>react#constructor', 1473584030342
09-11 16:53:50.346 11260-11292/com.react.smart I/ReactNativeJS﹕ '>>>react#componentWillMount', 1473584030345
09-11 16:53:50.500 11260-11292/com.react.smart I/ReactNativeJS﹕ '>>>react#componentDidMount', 1473584030500
09-11 16:53:50.504 11260-11292/com.react.smart I/ReactNativeJS﹕ '>>>react#componentDidMount#ToastAndroid.show', 1473584030503
cost:1473584030503-1473584028688=1815ms
第三次测试
09-11 17:10:20.694 18623-18623/com.react.smart I/ReactNativeJS﹕ >>>react performance react start:1473585020694
09-11 17:10:20.894 18623-18623/com.react.smart I/ReactNativeJS﹕ >>>react performance react end:1473585020894
09-11 17:10:22.225 18623-18657/com.react.smart I/ReactNativeJS﹕ '>>>react#constructor', 1473585022222
09-11 17:10:22.226 18623-18657/com.react.smart I/ReactNativeJS﹕ '>>>react#componentWillMount', 1473585022225
09-11 17:10:22.405 18623-18657/com.react.smart I/ReactNativeJS﹕ '>>>react#componentDidMount', 1473585022405
09-11 17:10:22.409 18623-18657/com.react.smart I/ReactNativeJS﹕ '>>>react#componentDidMount#ToastAndroid.show', 1473585022408
cost:1473585022408-1473585020694=1714ms
第四次测试
09-11 17:11:25.690 19167-19167/com.react.smart I/ReactNativeJS﹕ >>>react performance react start:1473585085690
09-11 17:11:25.865 19167-19167/com.react.smart I/ReactNativeJS﹕ >>>react performance react end:1473585085865
09-11 17:11:27.173 19167-19199/com.react.smart I/ReactNativeJS﹕ '>>>react#constructor', 1473585087169
09-11 17:11:27.173 19167-19199/com.react.smart I/ReactNativeJS﹕ '>>>react#componentWillMount', 1473585087173
09-11 17:11:27.336 19167-19199/com.react.smart I/ReactNativeJS﹕ '>>>react#componentDidMount', 1473585087335
09-11 17:11:27.340 19167-19199/com.react.smart I/ReactNativeJS﹕ '>>>react#componentDidMount#ToastAndroid.show', 1473585087339
cost: 1473585087339-1473585085690=1649ms
从测试结果来看, MX3 时间稳定在1500ms-1800ms之间, 明显比Nexus5要慢.
3.MX3 内存占用和cpu消耗
内存占用曲线图
从曲线图看出内存占用非常稳定, 一个HellWord的React Native App占用内存大概在20M
cpu曲线图
从曲线图看出启动的时候cpu瞬间飙到40%, 原因是因为启动时涉及Android和React Native JS与Native的大量调用,这个可以从上面View的绘制的过程可以看出.
第二个cpu波动是我这边频繁的点击[点击我]相关测试, 停止点击后, cpu马上就降落下来.