项目技术栈: javascript
view :用的是基于react的 antd + ltcrm-component。 html
数据流: refluxjava
路由: react-routerreact
打包:atool-buildwebpack
因为使用了atool-build致使没法使用webpack2,固然webpack的 新特性 tree-shaking 就更用不了了。详情查看:http://www.2ality.com/2015/12/webpack-tree-shaking.htmlgit
因此不得不用如下方案。 webpack不愧称得上是”比你更懂你的代码“。github
你们用的原生webpack 不妨尝试下,仍是不错的,另一个吹得比较火的是rollup.js ,有兴趣也能够看下。web
言归正传,咱们的基本组件使用的都是antd,并且antd的组件所有打出来会很是大。不压缩大概8,9百k的样子。因此用react-router-loader(基于webpack code split 的 react-router封装)会致使打包是这样的。antd
左边是优化前,右边是优化后:react-router
因为以前没有关注过代码优化,因此会致使优化控件很大。
我主要从三个方面优化:
webpack配置以下:
webpackConfig.entry.common = ['react', 'react-dom', 'react-router', 'reflux'];
我分析了下页面的使用状况,将使用频率高的打包成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})
经过读配置文件,去找对应引入的js大小。经过查找发现,react-time 大小就有200kb左右,可是实际上绝大数功能咱们都没有用到。因此就用 new Date().Format('yyyy-MM-dd hh:mm:ss')代替了。 这样部分引入react-time页面就少了200kb左右压缩前大小。 对于工具库的使用,个人理解是在引入对应库以前,要知道你要引入的是什么,以及引入了多少无用的代码。若是引入的代码比较少,你彻底能够用几行代码搞定,仍是不要引入了,这样会形成系统稳定性下降和 无用代码增长。 其实更推荐你们写一个工具库,而后把工具类都往里面塞。这样一方面大小可控(本身写的),一方面风险下降(出bug随时改)
虽然使用webpack code split 和 commonchunkPlugin以后代码比较平均而且小了许多。可是有的页面依旧很大(我这里的缘由是页面嵌套了不点击用户没法看到的Modal)。 因此最基本的优化思路是用户不点击的时候不加载js,这样会减小首次加载的js大小。 经过拆分首屏部分,大概抽出了300多k的内容,这取决于页面内容,并非说抽出非首屏内容必定会提升性能,视状况而定,这点须要注意。
优化后是这样的:
代码是基于webpack require.ensure()的 。 详情查看:https://webpack.github.io/docs/code-splitting.html
前一种是为了减小用户首次加载等待时间,这个是为了进一步减小这个时间。虽然两个名词截然相反。
这里的基本原理是分析用户行为,在用户将要发生这个行为以前,预先请求资源。 好比用户鼠标移到菜单上,那么颇有多是要点击,这时候就去加载js。即便用户不想切换也不会带来性能问题。由于用户不可能在页面未加载就把鼠标移上去吧?
这里我写了一个预加载的库。
github 地址 : https://github.com/azl397985856/react-prefetch
这个库目前实现了MPA鼠标移上去加载html。SPA鼠标移上去触发回调函数,回调函数会传url信息,你根据这个信息本身取请求对应资源便可。 我试了下,相比以前,如今页面基本平滑无闪动
代码优化,主要从一下两方面进行:
好比尽可能避免使用闭包。 使用定时器不要忘了清理等。 还有一个就是尽可能避免多层嵌套,若是你以为你必须这么作,极可能你选错了路。
关于代码优化,我以前有专门讲过,不赘述。
react是基于dom-diff 来渲染dom的全局刷新dom,但这创建在你使用良好的基础上。因此审查代码render次数,查找没必要要的渲染也是优化的一步。
比较容易有问题的一般是onchange scroll 这种比较频繁的事件监听。对于这种比较频繁的事件监听,须要单独优化,这一部分有机会再单独谈。
下面是我以前代码对的render状况:
我内心清楚这里面有一些没必要要的render,是能够优化的。
优化后:
经过这样分析并去除没必要要的渲染,能够进一步提高性能。