vue前端項目優化


今天終於得空了,我要把kui 說明文檔這個項目優化下。打開太慢了,就是這個 http://k-ui.cn

10幾秒才能展示完全,真受不了。來張圖就明白了

看到這個就沒啥好意外了,為什么會這么慢。

因為說明文檔的webpack 配置沒用vue-cli 腳手架,自己手動配置的,所以問題估計會多些吧

1)webpack配置出錯,導致庫重復被編譯到一個文件里

逐步檢查了編譯后比較大的文件,發現index.js 也就是入口文件,其內容有vue庫被重復打包了。如下圖

一句句排查webpack配置,沒有發現問題,那么到底問題出在哪里呢,搜索了下vue 的引入,發現有3個文件有引入vue,但是這並不影響編譯重復啊,不應該的,最后終於發現了問題,由於是mac 環境大小寫敏感所致,手一抖 “import Vue from 'vue'” 寫成了 “import Vue from 'Vue'”。

看似沒有任何問題debug 調試也不會出錯。但是問題就出現在這里,把from 后面的 “Vue”改位 首字母 小寫的“vue” 問題解決了。重新編譯后文件小了130多kb。從945kb到800多kb,繼續優化吧。

2)第三方褲文件過大造成的

由於說明文檔有部分要代碼高亮展示,文中用到了highlight.js代碼高亮庫。自行寫了個組件,代碼如下:

//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 那里干掉。再次編譯:

編譯后的文件才130kb,找到問題的根源了。

之前用谷歌的代碼高亮,這次不用它了,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,尚在接受范圍。

3)js模塊沒有做按需加​​載

因為vue是單頁web,靠router來驅動view,隨着項目越來越龐大,所以按需加載這個是必須的,不然所有的頁面必然會打包在同一個js文件里。造成加載緩慢。

按需加載(也就是懶加載)有3種實現方式

1)vue自帶的異步方式

在router push的時候做修改即可

{
    path: '/test',
    name: 'test',
    component: resolve => require(['../components/test'], resolve)
}
2)es提案的import()

官方文檔

注意注視內的內容,名字一樣的會被打包進一個文件

const test = () => import(/* webpackChunkName: "test" */'../components/test')
{
   path: '/test',
   name: 'test',
   component: test
},
3)webpack提供的require.ensure()

注意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陪。

[完]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM