webpack打包首頁如何優化及路由懶加載?本文詳解


 

前言

最近做了一個小型的vue的h5項目,發現在手機上運行的時候,第一次進去的首頁比較慢,然后同事提了下可以在生產環境用cdn,於是我嘗試了下

生產環境開啟cdn

1、 在vue.congfig.js里面加入

const isProduction = process.env.NODE_ENV == "production"; configureWebpack: (config) => { if (isProduction) { config.externals = { vue: "Vue", "vue-router": "VueRouter", vant: "vant", _: "lodash", }; 另外注意:光理論是不夠的。在此贈送2020最新企業級 Vue3.0/Js/ES6/TS/React/node等實戰視頻教程,想學的可進裙 519293536 免費獲取,小白勿進哦!

externals是讓里面的庫不被webapck打包,也不影響通過import(或者其他AMD、CMD等)方式引入

2、 在index.html引入cdn資源

  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.8/lib/index.css" /> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <script src="https://cdn.jsdelivr.net/npm/vant@2.8/lib/vant.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.core.min.js"></script> 復制代碼

3、 優化下寫法

// vue.config.js

const cdn = {
  css: ["https://cdn.jsdelivr.net/npm/vant@2.8/lib/index.css"], js: [ "https://cdn.jsdelivr.net/npm/vue@2.6.11", "https://unpkg.com/vue-router/dist/vue-router.js", "https://cdn.jsdelivr.net/npm/vant@2.8/lib/vant.min.js", "https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.core.min.js", ], }; chainWebpack: (config) => { if (isProduction) { config.plugin("html").tap((args) => { args[0].cdn = cdn; return args; }); } } // index.html <% for(var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css){%> <link src="<%= htmlWebpackPlugin.options.cdn.css[i] %>"></link> <%}%> <% for(var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js){%> <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script> <%}%> 復制代碼

優化前

優化后

 

 

 

開啟gzip壓縮


cnpm install compression-webpack-plugin --save-dev 

// vue.config.js
const CompressionPlugin = require("compression-webpack-plugin"); configureWebpack: (config) => { if (isProduction) { config.externals = { vue: "Vue", "vue-router": "VueRouter", vant: "vant", _: "lodash", }; config.plugins.push( new CompressionPlugin({ algorithm: "gzip", }) ); } }, 復制代碼

路由懶加載

  {
    path: "/index", name: "index", component: () => import("../views/index.vue"), meta: { keepAlive: false, }, }, 復制代碼

平常當中經常這么寫,只不過你可能不知道這就是路由懶加載。官網,官網上提到這是由於異步組件和weback的代碼分割code-splitting功能,每個異步路由會打包成不同的塊,實現按需加載。除了上面的ES2015模塊的寫法,它還有

 {
    path: "/index", name: "index", component: (resolve) => require(["../views/index.vue"], resolve), meta: { keepAlive: false, }, }, 復制代碼

根據官網提到的,首先創建一個返回Promise的工廠函數

const Index = () => Promise.resolve({ /* 組件定義對象 */ })
復制代碼

然后用動態 import語法定義代碼分塊的分割點

import ('./Index') 復制代碼

兩者結合,就可以自動分割代碼

const Index = () => import('../views/index.vue') 復制代碼

先看了下這個code-split

 

 

然后去看了下vue-cli的具體配置,路由已經是Dynamic Import,如上圖第二點提到. 下面說說針對於chunk-vendors的分割,正如上圖第三點提到,配置splitChunks是了重復數據刪除和分割chunks

optimization(開發和生產都是一樣的)

optimization:{
      splitChunks: {
        cacheGroups: {  // 緩存組,可以定義多個
          vendors: {     //創建一個 自定義的vendor的chunk
            name: "chunk-vendors", test: /[\\\/]node_modules[\\\/]/, // 匹配node_modules priority: -10, // 理解為緩存的級別 chunks: "initial", }, common: { name: "chunk-common", minChunks: 2, // 分割之前必須共享模塊的最小chunk數 priority: -20, chunks: "initial", reuseExistingChunk: true, // 是否復用存在的塊 }, }, } } 復制代碼
  • cacheGroups 緩存組,可以定義多個
 cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/, priority: -10 }, default: { minChunks: 2, priority: -20, reuseExistingChunk: true } } 復制代碼
  • priority 緩存組的級別

A module can belong to multiple cache groups. The optimization will prefer the cache group with a higher priority. The default groups have a negative priority to allow custom groups to take higher priority (default value is 0 for custom groups)

翻譯過來大概就是一個模塊可以有多個cash groups,optimization將會選擇優先級更高的cash group, default group 的優先級為負數,可以允許custom group有更高的優先級(默認值是0)。 簡而言之,custom group可以通過priority比default group

  • reuseExistingChunk 是否復用存在的塊

output配置有些不同

// 生產
  output: {
    path:"/dist", filename: "static/js/[name].[contenthash:8].js", publicPath: "/", chunkFilename: "static/js/[name].[contenthash:8].js", // 生成一個8位的hash值 } // 開發 output: { path:"/dist", filename: "static/js/[name].js", publicPath: "/", chunkFilename: "static/js/[name].js", } 復制代碼

運行打包

 

 

生產輸出了css,而開發環境沒有,估計是生產配置了這句

  // 生產
    new MiniCssExtractPlugin({
      filename: "static/css/[name].[contenthash:8].css", chunkFilename: "static/css/[name].[contenthash:8].css", }) 復制代碼

那么問題來了

  • 開發模式打包出來文件的css到底怎么引入的
  • 打包出來的dist的index.html的link和script標簽引入的文件為何不同
  • preload 和 prefetch的區別
// development
<!DOCTYPE html>
<html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="/favicon.ico"> <title>南藍</title> <link href="/static/js/0.js" rel="prefetch"><link href="/static/js/1.js" rel="prefetch"><link href="/static/js/2.js" rel="prefetch"> <link href="/static/js/3.js" rel="prefetch"> <link href="/static/js/app.js" rel="preload" as="script"> <link href="/static/js/chunk-vendors.js" rel="preload" as="script"> </head> <body> <noscript> <strong>We're sorry but f2e-client doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <script type="text/javascript" src="/static/js/chunk-vendors.js"></script><script type="text/javascript" src="/static/js/app.js"></script></body> </html> 復制代碼

再來看看生產打包出來的index.html(production)

// production
<!DOCTYPE html>
<html lang=en>
<head>
   <meta charset=utf-8>
   <meta http-equiv=X-UA-Compatible content="IE=edge"> <meta name=viewport content="width=device-width,initial-scale=1"> <link rel=icon href=/favicon.ico> <title>鴨嘴獸</title> <script src=https://cdn.jsdelivr.net/npm/vant@2.8/lib/index.css></script> <script src=https://cdn.jsdelivr.net/npm/vue@2.6.11></script> <script src=https://unpkg.com/vue-router/dist/vue-router.js></script> <script src=https://cdn.jsdelivr.net/npm/vant@2.8/lib/vant.min.js></script> <script src=https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.15/lodash.core.min.js></script> <link href=/static/css/chunk-0c3564fc.b3594289.css rel=prefetch> <link href=/static/css/chunk-56255d30.c1e34d24.css rel=prefetch> <link href=/static/css/chunk-5ba5813d.a56f098f.css rel=prefetch> <link href=/static/css/chunk-9945b478.66fcd057.css rel=prefetch> <link href=/static/js/chunk-0c3564fc.9d02dfcc.js rel=prefetch> <link href=/static/js/chunk-56255d30.d0115acd.js rel=prefetch> <link href=/static/js/chunk-5ba5813d.10f75234.js rel=prefetch> <link href=/static/js/chunk-9945b478.dc8a4502.js rel=prefetch> <link href=/static/css/app.faa29057.css rel=preload as=style> <link href=/static/css/chunk-vendors.97c56160.css rel=preload as=style> <link href=/static/js/app.5deb2d45.js rel=preload as=script> <link href=/static/js/chunk-vendors.158e0179.js rel=preload as=script> <link href=/static/css/chunk-vendors.97c56160.css rel=stylesheet> <link href=/static/css/app.faa29057.css rel=stylesheet> </head> <body> <noscript><strong>We're sorry but f2e-client doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript> <div id=app></div> <script src=/static/js/chunk-vendors.158e0179.js></script> <script src=/static/js/app.5deb2d45.js></script> </body> </html> 復制代碼
  • 為啥有些js用link標簽引入,有些用scipt標簽引入
  • link的as屬性為啥有時有時無

 

 

彈出vue-cli配置webpack設置

開發換環境 npx vue-cli-service inspect --mode development  webpack.config.development.js
生產環境:npx vue-cli-service inspect --mode production  webpack.config.production.js
復制代碼

不管前端輪子怎么變化,萬變不離其宗,這個宗指的就是htmlcssjs,所有要回歸本質上去,我提出的那些問題,希望下次出篇文章弄懂它,有錯誤或者有建議可以提出來
最后注意:光理論是不夠的。在此贈送2020最新企業級 Vue3.0/Js/ES6/TS/React/node等實戰視頻教程,想學的可進裙 519293536 免費獲取,小白勿進哦!

本文的文字及圖片來源於網絡加上自己的想法,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯系我們以作處理


免責聲明!

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



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