成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

記一次使用 vue-admin-template 的優(yōu)化歷程

xumenger / 2389人閱讀

摘要:同時(shí)也要引入對(duì)應(yīng)版本的先引入引入組件庫(kù)因?yàn)橐蕾?lài)是從外部引入的,所以需要告知在打包時(shí),依賴(lài)的來(lái)源。然后在中加入一條命令執(zhí)行或者即可完成打包。因此將此次優(yōu)化記錄下來(lái),并傳上了中。

本文原文

前言

公司有好幾個(gè)項(xiàng)目都有后臺(tái)管理系統(tǒng),為了方便開(kāi)發(fā),所以選擇了 vue 中比較火的 后臺(tái)模板 作為基礎(chǔ)模板進(jìn)行開(kāi)發(fā)。但是,開(kāi)始用的時(shí)候,作者并沒(méi)有對(duì)此進(jìn)行優(yōu)化,到項(xiàng)目上線(xiàn)的時(shí)候,才發(fā)現(xiàn),打包出來(lái)的文件都十分之大,就一個(gè) vendor 就有 770k 的體積(下圖是基礎(chǔ)模板,什么都沒(méi)加打包后的文件信息):

通過(guò) webpack-bundle-analyzer 進(jìn)行分析可得,體積主要來(lái)源于 餓了么UI(體積為 500k),因?yàn)闆](méi)對(duì)其進(jìn)行部分引入拆分組件,導(dǎo)致 webpack 把整個(gè)組件庫(kù)都打包進(jìn)去了。其次就是 vue 本身,體積也達(dá)到了 80k 之大。

所以,對(duì)其進(jìn)行打包優(yōu)化,是一件刻不容緩的事情。

優(yōu)化

優(yōu)化主要目的有:

加快資源加載速度,減少用戶(hù)等待的時(shí)間和首頁(yè)白屏?xí)r間,提高用戶(hù)體驗(yàn)。

加快打包速度,不要將時(shí)間浪費(fèi)在等待打包上。

解決第一個(gè)問(wèn)題,很多人都會(huì)想到資源文件放在 CDN 上就好了,沒(méi)錯(cuò),這次我們就是通過(guò) CDN 來(lái)解決加載問(wèn)題。

CDN - 提高加載速度

像 vue, element ui 這些比較成熟的框架/組件庫(kù),一般都有免費(fèi)、高速、公共的 cdn 供開(kāi)發(fā)者使用,鑒于大部分用戶(hù)均在國(guó)內(nèi),所以這次使用了 bootcdn 這個(gè)庫(kù)。該庫(kù)熱門(mén)資源比較齊全,各個(gè)版本都有,而且國(guó)內(nèi)訪(fǎng)問(wèn)速度很快,簡(jiǎn)直是開(kāi)發(fā)者的福音。

index.html 中引入 vue 和 餓了么組件。



  
    
    
    vue-admin-template
    
    
  
  
    

因?yàn)橐蕾?lài)是從外部引入的,所以需要告知 webpack 在打包時(shí),依賴(lài)的來(lái)源。

修改 webpack.base.conf.js

module.exports = {
  ...
  externals: {
    vue: "Vue",
    "element-ui":"ELEMENT"
  }
}

再一次打包,確實(shí)能極大的壓縮了打包的體積,從 700k 驟減至 130k:

但是隨之而來(lái)的就有問(wèn)題了:

明明我在本地開(kāi)發(fā),但是由于引入了線(xiàn)上的生產(chǎn)版本的 vue 文件,因此 vue-dev-tools 就不能進(jìn)行調(diào)試。

因此,我們需要再次調(diào)整一下 webpack 的配置,webpack.base.conf.js,而且 webpack 注入的 js 總是在最后面的,因此,我們需要 html-webpack-include-assets-plugin 幫忙在注入 app.js 后,再注入相對(duì)應(yīng)的組件庫(kù) :

const HtmlWebpackIncludeAssetsPlugin = require("html-webpack-include-assets-plugin")

const externals = {
  // 因?yàn)榇虬鼤r(shí),還沒(méi)注入,所以這里要去掉。
  // "element-ui":"ELEMENT"
}
// 生產(chǎn)環(huán)境中使用生產(chǎn)環(huán)境的 vue
// 開(kāi)發(fā)環(huán)境繼續(xù)使用本地 node_modules 中的 vue
if (process.env.NODE_ENV === "production") {
  externals["vue"] = "Vue"
  // 如發(fā)現(xiàn)打包時(shí)依舊將 element-ui 打包進(jìn)入 vendor,可以在打包時(shí)將其加入外部依賴(lài)。
  externals["element-ui"] = "ELEMENT"
}
// 生產(chǎn)環(huán)境默認(rèn)注入 vue 
// 開(kāi)發(fā)環(huán)境中不注入
const defaultJS = process.env.NODE_ENV === "production" ? [{ path: "https://cdn.bootcss.com/vue/2.4.2/vue.min.js", type: "js" }] : []
const plugins = [
  new HtmlWebpackIncludeAssetsPlugin({
      assets: defaultJS.concat([
        { path: "https://cdn.bootcss.com/element-ui/2.3.2/index.js", type: "js" },
        { path: "https://cdn.bootcss.com/element-ui/2.3.2/locale/zh-CN.min.js", type: "js" },
      ]),
      // 是否在 webpack 注入的 js 文件后新增?true 為 append, false 為 prepend。
      // 生產(chǎn)環(huán)境中,這些 js 應(yīng)該先加載。
      append: process.env.NODE_ENV !== "production",
      publicPath: "",
    })
]

module.exports = {
  ...
  externals,
  plugins,
  ...
}

OK,這時(shí)候,既能兼顧打包后的體積大小,也能在開(kāi)發(fā)模式中使用 vue-dev-tool 進(jìn)行調(diào)試。

DLL - 提高打包速度

經(jīng)常打包的前端會(huì)發(fā)現(xiàn),很多時(shí)候,我們?yōu)榱诵迯?fù)某些bug(如 promise 在 ie Safari 下的 bug),而新引入了一個(gè) polyfill,然而,打包完后發(fā)現(xiàn),vendor 的 hash 值變了,而整個(gè) vendor 只新加了一個(gè) es6-promise 的依賴(lài),但是付出的代價(jià)就是,需要拋棄之前打包好的 vendor,用戶(hù)重新訪(fǎng)問(wèn)時(shí),需要再一次拉取一個(gè)全新的 vendor,這個(gè)代價(jià)就有點(diǎn)大了。

這時(shí)候,使用 dllPlugin 打包就有優(yōu)勢(shì)了。它可以將一些基礎(chǔ)依賴(lài)模塊統(tǒng)一先打包起來(lái),當(dāng)正式打包時(shí),則可以略過(guò)這些模塊,不再重復(fù)打包進(jìn)去 vendor,提高打包速度的同時(shí)也能減少 vendor 的體積。

如,后臺(tái)管理系統(tǒng)基礎(chǔ)模塊基本有以下幾個(gè):

axios: ajax 請(qǐng)求。

vuex: 全局狀態(tài)管理。

js-cookie: 前端處理 cookie。

vue-router: 路由管理。

這四個(gè)基礎(chǔ)模塊幾乎是必須的,那么可以先提取出來(lái)。

step 1 打包基礎(chǔ)模塊

先在 build 文件夾下新建一個(gè)用于打包 dll 的配置文件 webpack.dll.conf.js

const webpack = require("webpack");
const path = require("path");
const vueLoaderConfig = require("./vue-loader.conf")
const utils = require("./utils")

function resolve(dir) {
    return path.join(__dirname, "..", dir)
}

const vendor = [
    // "vue/dist/vue.runtime.esm.js", // 由于 vue 在生產(chǎn)環(huán)境中使用的是 cdn 引入,所以也無(wú)需提前打包進(jìn) dll
    // "raven-js", // 前端監(jiān)控,若無(wú)此需求,可以忽略。
    "es6-promise", // 修復(fù) promise 中某些 bug。
    "vue-router",
    "js-cookie",
    "axios",
    "vuex",
];

const webpackConfig = {
    context: __dirname,
    output: {
        path: path.join(__dirname, "../static/js/"),
        filename: "[name].dll.js",
        library: "[name]_[hash]",
    },
    entry: {
        vendor
    },
    plugins: [
        new webpack.DllPlugin({
            context: __dirname,
            path: path.join(__dirname, ".", "[name]-manifest.json"),
            name: "[name]_[hash]",
        }),
        new webpack.optimize.UglifyJsPlugin({
            compress: {
              warnings: false
            },
            sourceMap: true,
            // parallel: true
        })
    ],
    module: {
        rules: [{
                test: /.vue$/,
                loader: "vue-loader",
                options: vueLoaderConfig
            },
            {
                test: /.js$/,
                loader: "babel-loader",
                include: [resolve("src"), resolve("test"), resolve("node_modules/webpack-dev-server/client")]
            },
            {
                test: /.(png|jpe?g|gif|svg)(?.*)?$/,
                loader: "url-loader",
                options: {
                    limit: 10000,
                    name: utils.assetsPath("img/[name].[hash:7].[ext]")
                }
            },
            {
                test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(?.*)?$/,
                loader: "url-loader",
                options: {
                    limit: 10000,
                    name: utils.assetsPath("media/[name].[hash:7].[ext]")
                }
            },
            {
                test: /.(woff2?|eot|ttf|otf)(?.*)?$/,
                loader: "url-loader",
                options: {
                    limit: 10000,
                    name: utils.assetsPath("fonts/[name].[hash:7].[ext]")
                }
            }
        ]
    }
};

module.exports = webpackConfig

然后在 package.json 中加入一條命令:

{
    "scripts": {
        ...
        "build:dll": "webpack --config build/webpack.dll.conf.js",
        ...
    }
}

執(zhí)行 yarn build:dll 或者 npm run build:dll 即可完成打包 dll。執(zhí)行完成后:

yarn build:dll
yarn run v1.5.1
$ webpack --config build/webpack.dll.conf.js
Hash: f6894dff019b2e0734af
Version: webpack 3.10.0
Time: 1295ms
         Asset     Size  Chunks             Chunk Names
vendor.dll.js  62.6 kB       0  [emitted]  vendor
   [8] dll vendor 12 bytes {0} [built]
    + 32 hidden modules
?  Done in 1.89s.

同時(shí),可以在 build 目錄下,找到各個(gè)模塊對(duì)應(yīng)關(guān)系文件 vendors-manifest.jsonstatic/js 下的 vendor.dll.js。

step 2 頁(yè)面中引入 vendor

打包后的 dll 文件需要手動(dòng)在 index.html 引入:

step 3 告訴 webpack 使用 dllPlugin 進(jìn)行打包

修改 build/webpack.prod.conf.js:

module.exports = {
    plugins: [
        ...
        new webpack.DllReferencePlugin({
            context: __dirname,
            manifest: require("./vendor-manifest.json")
        }),
        ...
    ]
}

再次打包:

$ yarn build:report
yarn run v1.5.1
$ npm_config_report=true node build/build.js
Hash: b4ff51852866ed865cfd
Version: webpack 3.10.0
Time: 6532ms
                                              Asset       Size  Chunks             Chunk Names
         static/js/manifest.42b9584a653aec2b9c5e.js     1.5 kB       5  [emitted]  manifest
                         static/img/404.a57b6f3.png    98.1 kB          [emitted]
                static/js/1.9e4133a25808e2101dd3.js       1 kB       1  [emitted]
                static/js/2.2a8a8e01c51473fab882.js    4.34 kB       2  [emitted]
           static/js/vendor.c7b076ef3341d4711402.js    39.4 kB       3  [emitted]  vendor
              static/js/app.6d52c7a5bf1bacb5cc85.js    21.4 kB       4  [emitted]  app
                static/js/0.cbc645864aab28ae8055.js    15.3 kB       0  [emitted]
static/css/app.1b30f8eba210e245a5f96d7bf0d6fb6c.css     7.6 kB       4  [emitted]  app
                                        favicon.ico    67.6 kB          [emitted]
                                         index.html  986 bytes          [emitted]
                            static/js/vendor.dll.js    62.6 kB          [emitted]

  Build complete.

  Tip: built files are meant to be served over an HTTP server.
  Opening index.html over file:// won"t work.

發(fā)現(xiàn) vendor 現(xiàn)在只有 40k 的體積,減少了一半的體積,而且打包速度也快了 2s,而相對(duì)于最開(kāi)始的基礎(chǔ)模板,打包速度快了 12s,這是很讓人欣慰。

后記

使用了 cdn 和 dll 打包后,無(wú)論是打包速度還是頁(yè)面加載的速度都有很大的提升。因此將此次優(yōu)化記錄下來(lái),并傳上了 GitHub 中。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95022.html

相關(guān)文章

  • Vue-cli3 簡(jiǎn)qian易yi教程

    摘要:原文地址對(duì)于沒(méi)有了解過(guò)的童鞋,建議先去看看官方的教程傳送門(mén)新版本的新特性插件使用的插件,可以很快的搭建一個(gè)項(xiàng)目的結(jié)構(gòu)。使用時(shí)直接引入即可。的界面讓管理項(xiàng)目變得更加簡(jiǎn)單。如遷移過(guò)程中有任何疑問(wèn),可以留言一起探討。 原文地址 對(duì)于沒(méi)有了解過(guò) vue-cli3 的童鞋,建議先去看看官方的教程: 傳送門(mén) 新版本的新特性 1. 插件 使用 cli 的插件,可以很快的搭建一個(gè)項(xiàng)目的結(jié)構(gòu)。如 ax...

    jemygraw 評(píng)論0 收藏0
  • 記一段SPASEO歷程:Html5 History Api 大顯神通!

    摘要:用戶(hù)體驗(yàn)的需求,完美地保留了瀑布流模態(tài)框的閱讀模式。不支持的話(huà),就不攔截瀑布流文塊的,也就是直接讓其跳轉(zhuǎn)。 背景 想當(dāng)年,我做了一個(gè)新媒體網(wǎng)站項(xiàng)目(AIISPO,已下線(xiàn))。跟普通資訊網(wǎng)站不一樣的是,老板要求PC端前臺(tái)的文章閱讀模式一定得是瀑布流+模態(tài)框。瀑布流指的是以瀑布流的形式將文章羅列出來(lái),而模態(tài)框則指的是點(diǎn)擊瀑布流中代表文章的某個(gè)文塊時(shí),直接在當(dāng)前頁(yè)面彈出模態(tài)框來(lái)顯示文章正文。 ...

    Lyux 評(píng)論0 收藏0
  • 記一段SPASEO歷程:Html5 History Api 大顯神通!

    摘要:用戶(hù)體驗(yàn)的需求,完美地保留了瀑布流模態(tài)框的閱讀模式。不支持的話(huà),就不攔截瀑布流文塊的,也就是直接讓其跳轉(zhuǎn)。 背景 想當(dāng)年,我做了一個(gè)新媒體網(wǎng)站項(xiàng)目(AIISPO,已下線(xiàn))。跟普通資訊網(wǎng)站不一樣的是,老板要求PC端前臺(tái)的文章閱讀模式一定得是瀑布流+模態(tài)框。瀑布流指的是以瀑布流的形式將文章羅列出來(lái),而模態(tài)框則指的是點(diǎn)擊瀑布流中代表文章的某個(gè)文塊時(shí),直接在當(dāng)前頁(yè)面彈出模態(tài)框來(lái)顯示文章正文。 ...

    reclay 評(píng)論0 收藏0
  • 一次前端項(xiàng)目重構(gòu)要點(diǎn)總結(jié)

    摘要:重構(gòu)總共耗時(shí)個(gè)工作日。第一個(gè)重構(gòu)原因就是沒(méi)有引入靜態(tài)類(lèi)型,導(dǎo)致查看一個(gè)對(duì)象結(jié)構(gòu)需要翻來(lái)覆去在多個(gè)文件中查找。第三是各個(gè)狀態(tài)模塊耦合度高,加大了代碼維護(hù)難度。但如果耦合度過(guò)高,往往是因?yàn)槟K沒(méi)有細(xì)分到位。這個(gè)項(xiàng)目也不列外。 showImg(https://segmentfault.com/img/remote/1460000019660483); 不知不覺(jué)已是2019年的7月,恍惚之間已...

    frolc 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<