RN性能
https://facebook.github.io/react-native/docs/performance.html
一个使用RN而不是webView的重要原因是可实现60fps以及更类似原生app的用户体验。RN的性能比较好,但某些地方仍然需要用户去手动优化
帧
打开Show Perf Monitor可以查看到帧率信息。这里有两个不同的帧率
JS帧率
一般来说,业务逻辑运行在JS线程,在每轮事件循环后以及每帧的期限之前,都去更新视图以及把视图发送到原生平台。假如JS线程对一个帧无响应,则这个帧就会被丢弃。如对于一个复杂应用,执行setState重新渲染一颗子树需要消耗200ms,则大概有12帧会丢失,任何JS控制的动画在这段期间都会停止。
这通常发生在Navigator过渡。当我们添加一个路由,为了能发送合适的指令给原生平台来创建视图,JS线程会渲染路由内所有的组件,这需要花费几帧的时间,导致Jank(用户能明显感觉到帧率下降,影响用户体验,这个现象称为Jank),这是因为过渡由JS线程来控制的。而且组件中的componentDidMount内可能还会做其他耗时的事情,这会使动画过渡出现更加明显的卡顿。
另外一个例子就是对触摸的响应。举个例子,如果JS线程执行的逻辑需要消耗几帧的时间,则可以发现TouchableOpacity有延迟。这是因为JS线程正忙,无法处理从主线程发来的原生触摸事件,这就到时TouchableOpacity无法处理触摸事件以及无法调整视图的透明度。
UI帧率
NavigatorIOS的性能要比Navigator要好,这是因为动画的过渡在主线程中完成,而不在JS线程中。如果在JS线程中可能因为逻辑过多导致一些帧被丢弃。
类似地,当JS线程正忙,也可以使用ScrollView,因为它存在于主线程,滚动的事件会传递给JS线程,但JS线程中的对应事件处理器对ScrollView的滚动是无影响的。
常见性能问题的源头
运行在开发环境
在处于开发环境时(dev=true),JS线程性能比较差,这是不可以避免,因为需要在运行时提供警告以及错误信息。但可以在release build(安装的时候执行 react-native run-android --variant=release)下进行性能测试
使用console.log
这个语句在运行的时候,会给JS线程造成巨大的瓶颈,需要保证在发布的时候移除这些日志输出。可以通过babel-plugin-transform-remove-console插件来实现,在项目的目录添加一个.babelrc文件:
{
"env": {
"production": {
"plugins": ["transform-remove-console"]
}
}
}
当发布的时候,这些console.*就会自动被移除了。
ListView
使用FlatList或者SectionList来替换,除了可以简化API,这些新的列表组件由显著的性能增强,主要是当列表item数据量较大时,只消耗常量级别的内存。
假如FlatList渲染较慢,要确保实现了getItemLayout来跳过测量已经渲染过了的item。
重新渲染一个不变化的视图
通过shouldComponentUpdate来决定组件什么时候要重新渲染,可以通过PureRenderMixin + immutable来实现一个纯组件(render的返回由state和props来控制)
JS线程同时做太多工作以至于丢失一些帧
明显的例子就是缓慢的路由过渡
待续。
RN性能的更多相关文章
- RN性能优化(重新探索react吧)
最近做RN遇到了一些性能瓶颈,逼着自己不得不做一些优化 已经做过,或者尝试过得优化方案: 1.点击效果防止重复点击. 2.左右两边分别用两个异步栈进行更新,这样能让右边的缓慢不影响左边的更新. 3.I ...
- RN 性能优化
按需加载: 导出模块使用属性getter动态require 使用Import语句导入模块,会自动执行所加载的模块.如果你有一个公共组件供业务方使用,例如:common.js import A from ...
- 【腾讯Bugly干货分享】跨平台 ListView 性能优化
本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/FbiSLPxFdGqJ00WgpJ94yw 导语 精 ...
- React Native Changed the World? or Nothing.
RN是一个awesome的技术, facebook很有想法的团队创造出一项新的技术改变了native开发界. 但是RN本身又疑点重重, RN是为了解决什么问题而存在的? 在诞生了一年后, RN又解决了 ...
- 新手教程之:循环网络和LSTM指南 (A Beginner’s Guide to Recurrent Networks and LSTMs)
新手教程之:循环网络和LSTM指南 (A Beginner’s Guide to Recurrent Networks and LSTMs) 本文翻译自:http://deeplearning4j.o ...
- React Native在特赞的应用与实践
基于React技术栈构建开发前端项目,并使用React Native开发特赞移动APP 目前正在使用Node.js开发和维护特赞服务网关,希望Node.js能够在更轻量级的微服务架构中发挥重要作用 课 ...
- 选择 React Native 的理由
转载:选择 React Native 的理由 从开始知道 React Native 到现在已经过了5个月,真实的试用也经历了三个月的时间.阅读文档开始,了解是什么,到简单的理解为什么,都是在聆听不同的 ...
- 给所有开发者的React Native详细入门指南
建议先下载好资料后,再阅读本文.demo代码和资料下载 目录 一.前言 二.回答一些问题 1.为什么写此教程 2.本文适合哪些人看 3.如何使用本教程 4.需要先学习JavaScript.HTML.C ...
- 你确信 X-Forwarded-For 拿到的就是用户真实 IP 吗?
X-Forwarded-For 拿到的就是真实 IP 吗? 1.故事 在这个小节开始前,我先讲一个开发中的小故事,可以加深一下大家对这个字段的理解. 前段时间要做一个和风控相关的需求,需要拿到用户的 ...
随机推荐
- 关于idea中使用lamb表达式报错:ambda expressions are not supported at this language level
我使用的是jdk1.8,使用lamb表达式的时候,报错 ambda expressions are not supported at this language level, 后来,设置了 接着重启了 ...
- Syncd-开源自动化部署工具
官网地址:https://gitee.com/dreamans/syncd/issues syncd是一款开源的代码部署工具,它具有简单.高效.易用等特点,可以提高团队的工作效率. 目前只支持类Lin ...
- PostgreSQL-3-DDL数据定义语言
1.创建/删除新的数据库 \l 查看现有数据库 \h CREATE DATABASE 查看CREATE DATABASE语句说明 \h DROP DATABASE 查看DROP DATABASE语 ...
- [JSOI2009]密码
Description Input Output Sample Input 10 2 hello world Sample Output 2 helloworld worldhello HINT 一看 ...
- appium环境搭建思路
1.appium环境是不是需要appium的一个安装包? 2.我们针对android进行测试我们是不是需要android本身的一个android 的sdk? 3.android这个本身就是java基础 ...
- POJ - 3020 Antenna Placement 二分图最大匹配
http://poj.org/problem?id=3020 首先注意到,答案的最大值是'*'的个数,也就是相当于我每用一次那个技能,我只套一个'*',是等价的. 所以,每结合一对**,则可以减少一次 ...
- Ionic之button标签ng-click无反应解决
在使用Ionic中,使用按钮的ng-click事件,竟然点击没有反应,刚开始以为自己写得方法有问题才会不起作用,自己在点击之后就console.log()一个东西,但是console也是无法反应的.& ...
- [转]Cordova android框架详解
本文转自:http://www.cnblogs.com/hubcarl/p/4202784.html 一.Cordova 核心java类说明 CordovaActivity:Cordova Activ ...
- cookie和session基础以及在Django中应用
看了会视频,终于搞懂了~ 1.cookie cookie:保存状态 cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地:当浏览器再次访问时,浏览器会自动带上cookie,这样服务器 ...
- Django模板导入及母版继承和自定义返回Html片段
1.ROOT_URLCONF = '总路由所在路径(比如untitled.urls)'<===默认情况是这样 根路由的路径是可以修改的:ROOT_URLCONF = app01.urls< ...