render 优化
使用 PureComponent
React Native 0.43.0 以上版本,使用了 React 16.x,自带优化光环,所以推荐使用 PureComponent。
如:export default class NewsView extends PureComponent { }
shouldComponentUpdate
如果 React Native 项目相对较早,也有优化方法:
- shouldComponentUpdate 默认返回 true,就是触发该方法,每次都重新渲染页面。想要优化,就要想办法尽可能的返回 false。那么怎么计算得出 false 呢,请看如下代码:
1 | import { is } from "immutable"; |
页面中调用:
1 | shouldComponentUpdate(nextProps, nextState) { |
列表优化
- 在列表的 item 上设置一个 key,这个 key 必须是唯一,最后不要用 index(用数据库里的 ID), 因为你如果删除一条记录,index 就都变了。
JSX 代码优化
推荐
- 在 render() 里, 将一些三元运算符,条件运算等计算的逻辑抽离到 render 最上面。一是可以复用,二是这类代码比较多了,更方便抽象到独立的方法中。
- 如:
const prizePoolMoneyText = this.props.prizePoolMoney > 0 ?
奖池${formatMoneyText(this.props.prizePoolMoney)}: '奖池过亿';
,使用时<Text>{prizePoolMoneyText}</Text>
不推荐
- 正好与上面相反,即:将一些三元运算符,条件运算等计算写在 JSX 代码里。
- 如:
<Text>{this.props.prizePoolMoney > 0 ?
奖池${formatMoneyText(this.props.prizePoolMoney)}: '奖池过亿'}</Text>
事件优化
推荐使用:
- 在构造函数里
this.handleChange = this.handleChange.bind(this);
- 在类里
handleChange = () => { };
- 柯里化事件绑定
onRouteToPress = name => () => this.props.routeTo(name, { a: '1', b: '2' }); // 柯里化事件绑定
,使用方法this.onRouteToPress('HowToJoin')
- 在构造函数里
不推荐使用:
- 属性里
onChange={this.handleChange.bind(this)}
- 属性里
onChange={e => this.handleChange(e)}
原因:不推荐的两种方式,会在每次执行 render 方法时重新分配资源
- 属性里
安装包大小优化
- 如果 APP 里的小图标没有阴影和渐变,建议用 iconfont 来代替图片 icon。
- 如果 APP 不用考虑 x86 的 Android 设备,包会缩小 40%左右。以我们 100 万+用户后台统计数据,x86 用户不到 0.1%,所以可以忽略不计。
- 尽可能复用 React Native 项目自带的 lib,少重复添加 lib。
- 图片可以转成 WebP 格式,它既支持有损压缩又支持无损压缩的图片文件格式。根据官方介绍其无损压缩后的 WebP 比 PNG 文件少了 45%的文件大小,即使 PNG 文件经过压缩工具压缩之后,WebP 还可以减少 28%的文件大小,这可以大大提高移动端的图片加载速度。
UI 响应优化
- 在对动画中途无取消要求或者其他中途回调要求的,比如局部组件特定显示隐藏动画等。我们可以在调用 setState 之前,调用 LayoutAnimation 方法。
1 | LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); |
- InteractionManager 可以将一些耗时较长的工作安排到所有互动或动画完成之后再进行。这样可以保证 JavaScript 动画的流畅运行,应用这样可以安排一个任务在交互和动画完成之后执行。
1 | InteractionManager.runAfterInteractions(() => { |
- 而对于某些状态更新,
setNativeProps
方法可以让我们直接修改原生视图组件的属性,而不用通过 setState 来重新渲染结构,这样能使整个组件响应速度变快
请求时机优化
网络数据请求,建议放在
componentDidMount
里,因为这时的页面已经渲染结束,至少让用户可以看点内容(componentWillMount
->render
),然后再去请求数据。注意:网络请求回来的数据 setState 或 mapStateToProps,会触发一系列事件:shouldComponentUpdate
->componentWillUpdate
->render
->componentDidUpdate
。
更多官方说明:https://facebook.github.io/react/docs/react-component.html#componentdidmount
样式优化:
尽量使用单个样式,减少使用数组样式
- 推荐:
const textStyle = StyleSheet.flatten([styles.baseText, extraTextStyle]); <Text style={textStyle}>
如果有多个样式(数组),建议使用 StyleSheet.flatten 将样式「打平」,然后赋给控件的 style 里。
- 可以:
<Text style={[styles.baseText, extraTextStyle]}>
<Text style={styles.baseText}>
以上两种写法都是允许
- 禁止:
<View style={[styles.rowWrapper]}>
如果只有一个格式,禁止放到数组里,因为这会生成一个多余的数组对象。下面是用 Jest 生成的控件解析快照(Jest Snapshot),见:
1 | <Text |
禁止这么做
- 禁止在
shouldComponentUpdate
、componentWillUpdate
、render
、componentDidUpdate
修改state
或修改props
,原因是这样会循环触发,最后 APP 会报错或崩溃。