文档章节

React性能优化

-鹏
 -鹏
发布于 2016/06/21 18:30
字数 1403
阅读 1551
收藏 4
点赞 0
评论 0

一. duplicate code

项目技术栈: 

view :用的是基于react的 antd + ltcrm-component。 

数据流: reflux

路由: react-router

打包:atool-build

由于使用了atool-build导致无法使用webpack2,当然webpack的 新特性 tree-shaking 就更用不了了。详情查看:http://www.2ality.com/2015/12/webpack-tree-shaking.html

所以不得不用以下方案。 webpack不愧称得上是”比你更懂你的代码“

大家用的原生webpack 不妨尝试下,还是不错的,另外一个吹得比较火的是rollup.js ,有兴趣也可以看下。

言归正传,我们的基本组件使用的都是antd,而且antd的组件全部打出来会非常大。不压缩大概8,9百k的样子。所以用react-router-loader(基于webpack code split 的 react-router封装)会导致打包是这样的。

左边是优化前,右边是优化后:

由于之前没有关注过代码优化,所以会导致优化控件很大。

我主要从三个方面优化:

1. 对于react, react-dom 页面都会使用的 单独打包成common.js

webpack配置如下:

webpackConfig.entry.common = ['react', 'react-dom', 'react-router', 'reflux'];

2. 对于antd 这种组件库。

我分析了下页面的使用情况,将使用频率高的打包成antd.js 。 页面用到antd会加载这个公共文件。对于页面使用频率低的组件,不加入到antd.js文件中。

webpack配置如下:

webpackConfig.entry.antd = [
			'antd/lib/button',
			'antd/lib/table',
			'antd/lib/modal',
			'antd/lib/message',
			'antd/lib/form',
			'antd/lib/menu',
			'antd/lib/row',
			'antd/lib/col',
			'antd/lib/tooltip',
			'antd/lib/radio',
			'antd/lib/date-picker',
			'antd/lib/time-picker',
			'antd/lib/input',
			'antd/lib/input-number',
			'antd/lib/notification',
			'antd/lib/pagination',
			'antd/lib/select',
			'antd/lib/tag',
		];

这样打出来antd公共组件压缩前大概是400kb。这样第一个页面加载了antd.js。其他页面就无需加载了,节省了带宽,提升了速度。

PS:  对于方法1,2 都需要先配置CommonsChunkPlugin.  大概是这样的new CommonsChunkPlugin({names: ['antd', 'common'], minChunks: Infinity})

3.分析项目依赖

通过读配置文件,去找对应引入的js大小。通过查找发现,react-time 大小就有200kb左右,但是实际上绝大数功能我们都没有用到。所以就用 new Date().Format('yyyy-MM-dd hh:mm:ss')代替了。 这样部分引入react-time页面就少了200kb左右压缩前大小。 对于工具库的使用,我的理解是在引入对应库之前,要知道你要引入的是什么,以及引入了多少无用的代码。如果引入的代码比较少,你完全可以用几行代码搞定,还是不要引入了,这样会造成系统稳定性降低和 无用代码增加。  其实更推荐大家写一个工具库,然后把工具类都往里面塞。这样一方面大小可控(自己写的),一方面风险降低(出bug随时改)

二. Lazy-Load

    虽然使用webpack code split 和 commonchunkPlugin之后代码比较平均并且小了许多。但是有的页面依旧很大(我这里的原因是页面嵌套了不点击用户无法看到的Modal)。 所以最基本的优化思路是用户不点击的时候不加载js,这样会减少首次加载的js大小。 通过拆分首屏部分,大概抽出了300多k的内容,这取决于页面内容,并不是说抽出非首屏内容一定会提高性能,视情况而定,这点需要注意。

优化后是这样的:

代码是基于webpack require.ensure()的 。 详情查看:https://webpack.github.io/docs/code-splitting.html

三. Prefetch

前一种是为了减少用户首次加载等待时间,这个是为了进一步减少这个时间。虽然两个名词截然相反。

这里的基本原理是分析用户行为,在用户将要发生这个行为之前,预先请求资源。  比如用户鼠标移到菜单上,那么很有可能是要点击,这时候就去加载js。即使用户不想切换也不会带来性能问题。因为用户不可能在页面未加载就把鼠标移上去吧?

这里我写了一个预加载的库。

github 地址 : https://github.com/azl397985856/react-prefetch

这个库目前实现了MPA鼠标移上去加载html。SPA鼠标移上去触发回调函数,回调函数会传url信息,你根据这个信息自己取请求对应资源即可。 我试了下,相比之前,现在页面基本平滑无闪动

四. render

代码优化,主要从一下两方面进行:

1.减少代码运算

比如尽量避免使用闭包。 使用定时器不要忘了清理等。 还有一个就是尽量避免多层嵌套,如果你觉得你必须这么做,很可能你选错了路。

关于代码优化,我之前有专门讲过,不赘述。

2. 减少不必要渲染

react是基于dom-diff 来渲染dom的全局刷新dom,但这建立在你使用良好的基础上。所以审查代码render次数,查找不必要的渲染也是优化的一步。

比较容易有问题的通常是onchange   scroll  这种比较频繁的事件监听。对于这种比较频繁的事件监听,需要单独优化,这一部分有机会再单独谈。

下面是我之前代码对的render情况:

我心里清楚这里面有一些不必要的render,是可以优化的。

优化后:

通过这样分析并去除不必要的渲染,可以进一步提升性能。

 

© 著作权归作者所有

共有 人打赏支持
-鹏
粉丝 20
博文 142
码字总数 91363
作品 0
杭州
前端工程师
React + Redux 性能优化(一):理论篇

React + Redux 性能优化(一):理论篇 轻薄2018-01-031 阅读 React优化性能 本文的叙事线索与代码示例均来自 High Performance Redux ,特此表示感谢。之所以感谢是因为最近一直想系统的整理...

轻薄 ⋅ 01/03 ⋅ 0

React性能优化方案之PureRenderMixin

React性能检测 安装react性能检测工具 npm i react-addons-perf --save,然后在初始化项目的./app/index.js中写入以下代码: 在运行之前,先让react项目启动起来,然后打开开发者调试面板,在...

viyoung ⋅ 06/01 ⋅ 0

【腾讯Bugly干货分享】React移动web极致优化

本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/579083d1c9da73584b02587d 最近一个季度,我们都在为手Q家校群做重构优化,将原有那套问题不断...

腾讯Bugly ⋅ 2016/07/22 ⋅ 0

前端每周清单第 34 期:Vue 现状盘点与 3.0 展望,React 代码迁移与优化,图片优化详论

前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点;分为新闻热点、开发教程、工程实践、深度阅读、开源项目、巅峰人生等栏目。欢迎关注【前端之巅】微信公...

王下邀月熊 ⋅ 2017/10/09 ⋅ 0

使用 proxy 实现的 mobx - dob 介绍

一共有两个套件: dob 类比 mobx dob-react 类比 mobx-react dob 优势,就是由于使用了 proxy,支持跟踪不存在的变量,比如: 很方便吧,实现了 mobx 梦寐以求的夙愿,至今为止希望实现的 do...

黄子毅 ⋅ 2017/09/06 ⋅ 0

在 Angular 中使用 React 组件的开源库--NgReact

React.js库可以用作Web应用程序中的视图组件。 ngReact 让你可以在 AngularJS 应用程序中使用 React 组件。 作用: 您需要比 Angular 更高的性能,而由于虚拟 DOM 和其他优化,React通常性能...

匿名 ⋅ 2017/06/16 ⋅ 0

React.js绑定this的5种方法

this在javascript中已经相当灵活,把它放到React中给我们的选择就更加困惑了。下面一起来看看React 的5种绑定方法。 1.使用React.createClass 如果你使用的是React 15及以下的版本,你可能使...

Monster000 ⋅ 06/03 ⋅ 0

Hybrid App 和 React Native 开发那点事

简介:Hybrid App(混合模式移动应用)开发是指介于Web-app、Native-App这两者之间的一种开发模式,兼具「Native App 良好用户交互体验的优势」和「Web App 跨平台开发的优势」。很多人都知道...

OneAPM蓝海讯通 ⋅ 2016/03/18 ⋅ 0

React-native 拆包

react-native拆包 拆包是React-Native项目不得不面临的一个重要技术门槛。 为什么要拆包? bundle文件过大: 一个Hellworld的App,如果使用0.53RN 官方命令react-native bundle打包出来的JSB...

乘着风 ⋅ 06/17 ⋅ 0

ELSE 技术周刊(2017.12.11期)

业界动态 Angular 5.1 & More Now Available Angular发布5.1版本,同时发布了Angular CLI 1.6版本以及首个稳定版本的Angular Material。CLI支持了Service Worker,以及带来对AppShell更好的支...

风清洋ELSE ⋅ 2017/12/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Nginx服务架构初探(四):nginx服务器的rewrite功能

nginx服务器的rewrite功能 1.nginx后端服务器组的配置 1>upstream name {…} name是给服务器组限的组名 2>server address [parameters]; address为服务器地址 parame......

余温灬未存 ⋅ 今天 ⋅ 0

layer.prompt使文本框为空的情况下也能点击确定

最近一直在使用layui,但是用到弹出层layer.prompt时,如果文本框是空的话点击确定没有反应,不能向下执行。 但是我又需要空值,看看我原来的代码。 123456789 layer.prompt...

孟飞阳 ⋅ 今天 ⋅ 0

Linux普通文件压缩工具gzip、Bzip2、xz

第六章 文件压缩和打包 6.1 压缩打包介绍 Linux环境常见压缩文件类型: .zip,.gz,.bz2,.xz, .tar.gz,.tar.bz2,.tar.xz 压缩打包的目的 方便文件传输 节省磁盘空间 减少传输花费的时间 ...

弓正 ⋅ 今天 ⋅ 0

移动弹窗基础知识浅析——IOS弹窗体系

摘要: 最为常见的【弹窗】反而是最“捉摸不定”的东西。各种类型的弹窗傻傻分不清楚,不知道在什么场景下应该用哪种弹窗。尤其是遇到“二次确认”等场景…… 因此,打算从头整理移动弹窗的基...

阿里云云栖社区 ⋅ 今天 ⋅ 0

zabbix短信报警统计以及报表展示

一、需求 由于我们的业务报警比较频繁,之前是针对每个报警进行具体处理,但是有时还会重复出现,或者后续处理有时忘记跟进等,因此进行报警短信的统计,可以针对一些问题与业务跟进,明确后...

o翡翠谷o ⋅ 今天 ⋅ 0

JNI 输出LOG

1、导入log头文件。在你使用的 .c/ .cpp 文件中,导入 log.h 头文件。 #include<android/log.h> 2、在android.mk 加上 LOCAL_LDLIBS := -llog 或 LOCAL_SHARED_LIBRARIES := liblog 3、定义L......

国仔饼 ⋅ 今天 ⋅ 0

主线程pthread_exit 作用

#include <iostream>#include <pthread.h>#include <unistd.h>using namespace std;#define NUM_THREADS 10void* say_hello(void* args){ int i = *((int*)args);/......

xxdd ⋅ 今天 ⋅ 0

崛起于Springboot2.X之Mybatis-xml方式操作mysql数据库(3)

序言:当第一篇讲道Mybatis的时候,只要使用过mybatis的java程序员100%都会知道这种方式,因为这是最广泛最全面的编写sql操作mysql数据库的方式,高级sql的编写往往通过xml方式,接下来进入正...

木九天 ⋅ 今天 ⋅ 1

移动弹窗基础知识浅析——IOS弹窗体系

摘要: 最为常见的【弹窗】反而是最“捉摸不定”的东西。各种类型的弹窗傻傻分不清楚,不知道在什么场景下应该用哪种弹窗。尤其是遇到“二次确认”等场景…… 因此,打算从头整理移动弹窗的基...

猫耳m ⋅ 今天 ⋅ 0

spring elasticsearch 2.4 date 日期

1.mappingPUT user_behavior { "mappings": { "user_behavior": { "properties": { "date": { "type": "createDate", ......

xiaomin0322 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部