Vue CLI 首屏優化技巧

https://www.cnblogs.com/royal6/p/12988252.html
要首屏優化,首先你要知道有哪些東西可以優化,你可以生成打包報告進行查看。
在package.json中,npm run build命令中添加如下命令,生成一份報告
在這裏插入圖片描述
根據這份報告,你就知道有哪些文件需要優化了。
在這裏插入圖片描述
一般的優化我們可以在vue.config.js裏面優化
configureWebpackchainWebpack
在 vue.config.js 導出的配置對象中,新增 configureWebpack 或 chainWebpack 節點,來自定義 webpack 的打包配置。

在這裏, configureWebpack 和 chainWebpack 的作用相同,唯一的區別就是它們修改 webpack 配置的方 式不同:

1.chainWebpack 通過鏈式編程的形式,來修改默認的 webpack 配置
2.configureWebpack 通過操作對象的形式,來修改默認的 webpack 配置
兩者具體的使用差異,可參考如下網址: https://cli.vuejs.org/zh/guide/webpack.html#webpack-相關

接下來就是一些優化的技巧
1.路由懶加載

  {
    // 首頁
    path: '/',
    name: 'Home',
    components: {
      default: () => import('@/views/home/index.vue'),
    },
    meta: { title: '111' }
  },

2.關閉預加載模塊prefetch(預先加載模塊)

因爲 vuecli 3默認開啓 prefetch(預先加載模塊),提前獲取用戶未來可能會訪問的內容
在首屏會把這十幾個路由文件,都一口氣下載了
所以我們要關閉這個功能,在 vue.config.js中設置

 chainWebpack: config => {
    config.plugins.delete('preload') 
    config.plugins.delete('prefetch') 
  },

3.拆包和組件重複使用打包,當文件的包越來越大的時候,我們需要進行相對應的分包處理,使用異步請求的辦法來提升請求的速度。具體的方法如下,還是在webpack配置中

 chainWebpack: config => {
    config
      .when(process.env.NODE_ENV !== 'development',
        config => {
          config
            .optimization.splitChunks({
              chunks: 'all',
              cacheGroups: {
                libs: {
                  name: 'chunk-libs',
                  test: /[\\/]node_modules[\\/]/,
                  priority: 10,
                  chunks: 'initial' // only package third parties that are initially dependent
                },
                vantUI: {
                  name: 'chunk-vantUI',
                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                  test: /vant/ // in order to adapt to cnpm
                },
                commons: {
                  name: 'chunk-commons',
                  test: resolve('src/components'), // can customize your rules
                  minChunks: 3, //  minimum common number
                  priority: 5,
                  reuseExistingChunk: true
                }
              }
            })
          config.optimization.runtimeChunk('single')
        }
      )
  },

我這裏拆分的是vant的包和component的包,你也可以按照我的方式拆分其他的包

4.gzip
拆完包之後,我們再用 gzip做一下壓縮

在vue.config.js中

  configureWebpack: config => {
    if (process.env.NODE_ENV === 'production') {
      return {
        plugins: [
          new CompressionPlugin({
            test: /\.js$|\.html$|\.css$/,
            // 超過10k才壓縮
            threshold: 10240,
            // 是否刪除源文件
            deleteOriginalAssets: false
          })
          // new BundleAnalyzerPlugin()
        ]
      }
    }
  },

在nginx上的配置如下:

http {
# 開啓gzip
    gzip on;

    # 啓用gzip壓縮的最小文件,小於設置值的文件將不會壓縮
    gzip_min_length 1k;

    # gzip 壓縮級別,1-9,數字越大壓縮的越好,也越佔用CPU時間,後面會有詳細說明
    gzip_comp_level 6;

    # 進行壓縮的文件類型。javascript有多種形式。其中的值可以在 mime.types 文件中找到。
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;

    # 是否在http header中添加Vary: Accept-Encoding,建議開啓
    gzip_vary on;

    # 禁用IE 6 gzip
    gzip_disable "MSIE [1-6]\.";

    # 設置壓縮所需要的緩衝區大小     
    gzip_buffers 32 4k;

    # 設置gzip壓縮針對的HTTP協議版本
    gzip_http_version 1.0;

}

OK,接下來優化的事情就做好了,以下是優化後的結果
在這裏插入圖片描述

完整的vue.config.js配置如下:

const path = require('path')
const CompressionPlugin = require('compression-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin') // 引入刪除console插件
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

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

module.exports = {
  publicPath: process.env.VUE_APP_BUILD_PATH, // 打包後的文件地址
  outputDir: process.env.VUE_APP_FILE_Name, // 打包的文件夾名字
  assetsDir: 'static',
  configureWebpack: config => {
    if (process.env.NODE_ENV === 'production') {
      return {
        optimization: {
          minimizer: [
            new TerserPlugin({
              terserOptions: {
                ecma: undefined,
                warnings: false, // 傳遞true以在中返回壓縮機警告result.warnings。使用該值可"verbose"獲取更詳細的警告。
                parse: {},
                compress: {
                  drop_console: true, // 移除console
                  drop_debugger: true, // 移除debugger
                  pure_funcs: ['console.log'] // 移除console
                }
              }
            })
          ]
        },
        plugins: [
          new CompressionPlugin({
            test: /\.js$|\.html$|\.css$/,
            // 超過10k才壓縮
            threshold: 10240,
            // 是否刪除源文件
            deleteOriginalAssets: false
          })
          // new BundleAnalyzerPlugin()
        ]
      }
    }
  },

  filenameHashing: true,
  // eslint-loader 是否在保存的時候檢查
  lintOnSave: true,
  // 是否使用包含運行時編譯器的Vue核心的構建
  runtimeCompiler: false,
  // 默認情況下 babel-loader 忽略其中的所有文件 node_modules
  transpileDependencies: [],
  // 生產環境 sourceMap,打包時不生成.map文件 避免看到源碼
  productionSourceMap: false,
  chainWebpack: config => {
    config.plugins.delete('preload') // TODO: need test
    config.plugins.delete('prefetch') // TODO: need test
    const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
    types.forEach(type =>
      addStyleResource(config.module.rule('less').oneOf(type))
    )
    config
      .when(process.env.NODE_ENV !== 'development',
        config => {
          config
            .optimization.splitChunks({
              chunks: 'all',
              cacheGroups: {
                libs: {
                  name: 'chunk-libs',
                  test: /[\\/]node_modules[\\/]/,
                  priority: 10,
                  chunks: 'initial' // only package third parties that are initially dependent
                },
                vantUI: {
                  name: 'chunk-vantUI',
                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                  test: /vant/ // in order to adapt to cnpm
                },
                commons: {
                  name: 'chunk-commons',
                  test: resolve('src/components'), // can customize your rules
                  minChunks: 3, //  minimum common number
                  priority: 5,
                  reuseExistingChunk: true
                }
              }
            })
          config.optimization.runtimeChunk('single')
        }
      )
    config.resolve.alias
      .set('@', resolve('src'))
      .set('imgs', resolve('src/assets/imgs'))
      .set('components', resolve('src/components'))
      .set('pageComponents', resolve('src/pageComponents'))
      .set('http', resolve('src/http'))
      .set('utils', resolve('src/utils'))
      .set('views', resolve('src/views'))
  },
  // 配置高於chainWebpack中關於 css loader 的配置
  css: {
    // 默認情況下,只有 *.module.[ext] 結尾的文件纔會被視作 CSS Modules 模塊。設置爲 false 後你就可以去掉文件名中的 .module 並將所有的 *.(css|scss|sass|less|styl(us)?) 文件視爲 CSS Modules 模塊。
    requireModuleExtension: true,
    // 是否使用 css 分離插件 ExtractTextPlugin,採用獨立樣式文件載入,不採用 <style> 方式內聯至 html 文件中 設置爲true的話修改樣式不會立即生效
    extract: false,
    // 是否構建樣式地圖,false 將提高構建速度
    sourceMap: false,
    loaderOptions: {
      less: {
        javascriptEnabled: true
      }
    }
  },
  devServer: {
    open: false, // 運行項目時自動啓動瀏覽器,
    port: 777, // 端口號
    https: false,
    hot: true, // 模塊熱替換(HMR - hot module replacement)功能會在應用程序運行過程中,替換、添加或刪除 模塊,而無需重新加載整個頁面。主要是通過以下幾種方式,來顯著加快開發速度
    hotOnly: false, // hot 和 hotOnly 的區別是在某些模塊不支持熱更新的情況下,前者會自動刷新頁面,後者不會刷新頁面,而是在控制檯輸出熱更新失敗
    overlay: {
      warnings: false, // 當出現編譯器錯誤或警告時,在瀏覽器中顯示全屏覆蓋層,如果想要顯示警告和錯誤
      errors: true
    },
    // 設置代理
    proxy: {
      '/api': {
        target: '', 
        changeOrigin: true,
        secure: false, // 如果是https接口,需要配置這個參數
        ws: true,
        pathRewrite: { // 表示的意思是把/api 替換爲空,用在如果你的實際請求地址沒有api的情況)
          '^/api': ''
        }
      },
   
      '/foo': {
        target: '<other_url>'
      }
    },
    before: app => { }
  },
  // 構建時開啓多進程處理 babel 編譯
  parallel: require('os').cpus().length > 1,
  pwa: {},
  // 第三方插件配置
  pluginOptions: {}
}

function addStyleResource(rule) {
  rule
    .use('style-resource')
    .loader('style-resources-loader')
    .options({
      patterns: [
        path.resolve(__dirname, 'src/assets/css/styles/global.less') // 需要全局導入的less
      ]
    })
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章