今天終於得空了,我要把kui 說明文檔這個項目優化下。打開太慢了,就是這個 http://k-ui.cnjavascript
10幾秒才能展現徹底,真受不了。來張圖就明白了
css
看到這個就沒啥好意外了,爲何會這麼慢。html
由於說明文檔的webpack 配置沒用vue-cli 腳手架,本身手動配置的,因此問題估計會多些吧vue
逐步檢查了編譯後比較大的文件,發現index.js 也就是入口文件,其內容有vue庫被重複打包了。以下圖
java
一句句排查webpack配置,沒有發現問題,那麼到底問題出在哪裏呢,搜索了下vue 的引入,發現有3個文件有引入vue,可是這並不影響編譯重複啊,不該該的,最後終於發現了問題,因爲是mac 環境大小寫敏感所致,手一抖 「import Vue from 'vue'」 寫成了 「import Vue from 'Vue'」。node
看似沒有任何問題debug 調試也不會出錯。可是問題就出如今這裏,把from 後面的 「Vue」改位 首字母 小寫的「vue」 問題解決了。從新編譯後文件小了130多kb。從945kb到800多kb,繼續優化吧。python
因爲說明文檔有部分要代碼高亮展現,文中用到了highlight.js代碼高亮庫。自行寫了個組件,代碼以下:react
//code.vue <template> <div v-high class="k-code"> <pre :style="styles" ref="rel"> <code :class="lang"><slot></slot></code> </pre> </div> </template> //code.js import Hljs from "highlight.js"; import "highlight.js/styles/atom-one-light.css"; const vueHljs = {}; vueHljs.install = (Vue) => { Vue.directive("high", function (el, binding) { let blocks = el.querySelectorAll("pre code"); Array.prototype.forEach.call(blocks, Hljs.highlightBlock); }); }; export default vueHljs //調用 <Code lang="xml html">{{code}}</Code>
事實上代碼這麼寫也不會有什麼問題,可是編譯後文件爲何會這麼大呢,800多kb,因而乎我把關鍵的代碼高亮代碼註釋,也就是引入highlight.js 那裏幹掉。再次編譯:webpack
編譯後的文件才130kb,找到問題的根源了。c++
以前用谷歌的代碼高亮,此次不用它了,markdown也不想折騰。
去node_modules 仔細的探究下,由於代碼高亮包含了太多的語言和語法,我每次編譯事後是全量包,python,sql,c++等50幾種高亮語言全在裏面,可是我只要js 和 html 語法高亮,因此就從庫裏提出了我想要的:
var Hljs = require('./highlight'); //只要這2個高亮語言庫,其餘幹掉 Hljs.registerLanguage('xml', require('./lang/xml')); Hljs.registerLanguage('javascript', require('./lang/javascript'));
再次編譯,編譯後180kb,尚在接受範圍。
由於vue是單頁web,靠router來驅動view,隨着項目愈來愈龐大,因此按需加載這個是必須的,否則全部的頁面必然會打包在同一個js文件裏。形成加載緩慢。
按需加載(也就是懶加載)有3種實現方式
在router push的時候作修改便可
{ path: '/test', name: 'test', component: resolve => require(['../components/test'], resolve) }
官方文檔
注意注視內的內容,名字同樣的會被打包進一個文件
const test = () => import(/* webpackChunkName: "test" */'../components/test') { path: '/test', name: 'test', component: test },
注意ensure 傳參,最後一個chunkname,不傳 output 配置 chunkFilename:將會是[id].build.js
{ path: '/test', name: 'test', component: resolve => require.ensure([], () => resolve(require('../components/test')), 'test') },
注:require.ensure() 是 webpack 特有的,已經被 import() 取代。
以上3種方式都能實現按需加載,最後在webpack config 裏面配置chunkFilename
output: { path: path.resolve(__dirname, '../dist'), filename: 'js/[name].js',//.[hash].js', publicPath: '/', chunkFilename: 'js/[name].[chunkhash:3].js', },
固然,我在項目裏是作了按需加載的,可是最終打包的文件仍是合併了。那麼看看問題出如今哪裏
個人路由是這麼幹的:
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) let routes = [] let r = ['','install', 'start', 'log', 'input', 'button', 'select', 'switch', 'form', 'colorpicker', 'loading', 'icon', 'timeline', 'theme', 'react-kui', 'angular-kui', 'alert', 'message', 'notice', 'upload', 'poptip', 'menu', 'tabs', 'badge', 'checkbox', 'radio', 'datepicker', 'table', 'layout', 'page', 'modal', 'kyui-loader', 'sponsor', 'about']; r.forEach((x) => { routes.push({ path: `/${x}`, component: resolve => require([x==''?'./ui/index':`./ui/${x}`], resolve), // component: r => require.ensure([], () => r(require(x==''?'/ui/index':`./ui/${x}`)), x) }) }) let routers = new Router({ routes: routes, mode: 'history' }) export default routers
按需加載看似沒有問題吧,可是最後打包出來的chunkFilename 有300kb,並且頁面所有都打進了一個js文件。
探究了一番,由於是異步加載,因此不能動態傳值的,map 遍歷的時候路徑組合 x 值是動態傳入,致使打包後沒法識別。最後修改成靜態的,問題解決了。從新編譯後多個頁面路由分割成單個js文件,每一個約10kb左右,路由改變時,動態加載對應的js文件
import xx from '/dev/test‘ //這裏的abc 是靜態的值 如 ‘/ui/abc.vue’ { path:'xx', component:xx }
至此,問題解決了,頁面加載正常狀況下延時1-2秒,時間縮短了將近10陪。
[完]