• 使用 vue-cli4 配置打包优化

    • 2020-01-10 18:05
    • 字数 3,013
    • 阅读 1,665

    在vue-cli4项目中,通过 highlight.js,实现了页面中代码高亮显示。但页面打开速度变慢了很多,chunk-vendors.30c0fb60.js有1.2M,页面加载需要耗时5.6s,需要进行打包优化处理。通过使用 cdn 加载、打包压缩等方式,终于把该文件减少到 275KB,首页加载时间减少到不足3s。(新版本参考:再说 ant-design-vue 1.7.8 打包优化


    1、配置路由懒加载,示例代码如下:

    
    import Vue from "vue";
    import VueRouter from "vue-router";
    import Home from "../views/Home.vue";
    
    Vue.use(VueRouter);
    
    const routes = [
      {
        path: "/",
        name: "home",
        component: Home
      },
      {
        path: "/post/:id",
        name: "post",
        component: () => import("../views/Post.vue")
      }
    ];
    
    

    2、配置代码压缩,示例代码如下:

    
    const CompressionWebpackPlugin = require("compression-webpack-plugin");
    const productionGzipExtensions = ["js", "css"];
    
    new CompressionWebpackPlugin({
      filename: "[path].gz[query]",
      algorithm: "gzip",
      test: new RegExp("\\.(" + productionGzipExtensions.join("|") + ")$"),
      threshold: 10240,
      minRatio: 0.8
    })
    
    

    3、公用代码提取,使用 CDN 加载

    对于vue, vuex, vue-router,axios等我们可以利用wenpack的externals参数来配置,这里我们设定只需要在生产环境中才需要使用:

    
    configureWebpack: config => {
        if (process.env.NODE_ENV !== "production") return;
    
        return {
          externals: {
            vue: "Vue",
            "vue-router": "VueRouter",
            axios: "axios",
            "highlight.js": "hljs"
          },
        },
      },
    
    

    index.html文件引入相关 cdn 组件:

    
    <script src="//cdn.bootcss.com/axios/0.19.0/axios.min.js"></script>
    <script src="//cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
    <script src="//cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
    <script src="//cdn.bootcss.com/highlight.js/9.15.10/highlight.min.js"></script>
    
    

    4、优化请求数,配置信息如下:

    
    chainWebpack: config => {
        // 移除 prefetch 插件
        config.plugins.delete('prefetch')
        // 移除 preload 插件
        config.plugins.delete('preload');
      },
    
    

    5、通过yarn build重新打包,部署后发现效果明显。附完整的vue.config.js文件:

    
    const PrerenderSPAPlugin = require("prerender-spa-plugin");
    const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
    const path = require("path");
    
    const CompressionWebpackPlugin = require("compression-webpack-plugin");
    const productionGzipExtensions = ["js", "css"];
    
    module.exports = {
      productionSourceMap: false, // 生产环境的 source map
      // CSS 相关选项
      css: {
        // 将组件内的 CSS 提取到一个单独的 CSS 文件 (只用在生产环境中)
        // 也可以是一个传递给 `extract-text-webpack-plugin` 的选项对象
        extract: true,
    
        // 是否开启 CSS source map?
        sourceMap: false,
    
        // 为预处理器的 loader 传递自定义选项。比如传递给
        // sass-loader 时,使用 `{ sass: { ... } }`。
        loaderOptions: {}
      },
    
      configureWebpack: config => {
        if (process.env.NODE_ENV !== "production") return;
    
        return {
          externals: {
            vue: "Vue",
            "vue-router": "VueRouter",
            axios: "axios",
            "highlight.js": "hljs"
          },
          plugins: [
            new PrerenderSPAPlugin({
              // 生成文件的路径,也可以与webpakc打包的一致。
              // 下面这句话非常重要!!!
              // 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
              staticDir: path.join(__dirname, "dist"),
              // 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。
              routes: ["/", "/post/id", "/about"],
              // 这个很重要,如果没有配置这段,也不会进行预编译
              renderer: new Renderer({
                inject: {
                  foo: "bar"
                },
                headless: false,
                // 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
                renderAfterDocumentEvent: "render-event"
              })
            }),
    
            new CompressionWebpackPlugin({
              filename: "[path].gz[query]",
              algorithm: "gzip",
              test: new RegExp("\\.(" + productionGzipExtensions.join("|") + ")$"),
              threshold: 10240,
              minRatio: 0.8
            })
          ]
        };
      },
    
      chainWebpack: config => {
        // 移除 prefetch 插件
        config.plugins.delete('prefetch')
        // 移除 preload 插件
        config.plugins.delete('preload');
      },
    
      devServer: {
        publicPath: process.env.NODE_ENV === "development" ? "/" : "./",
        proxy: {
          "/api": {
            target: "http://localhost:9090",
            pathRewrite: {
              "^/api": ""
            }
          }
        }
      }
    };
    
    
back_to_top