項目技術棧: 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,是能夠優化的。
優化後:
經過這樣分析並去除沒必要要的渲染,能夠進一步提高性能。