博客 / 詳情

返回

甲方嫌棄,項目首頁加載太慢

🧑‍💻 寫在開頭

點贊 + 收藏 === 學會🤣🤣🤣

有一天,甲方打開一個後台管理的項目,説有點卡,不太滿意,項目經理叫我優化,重新打包一下。

從輸入地址 到 展示 首屏,最佳時間在 3秒內,否則,甲方掛臉,咱就有可能有被裁的風險,understand?

廢話不多説,先來看一下怎麼個優化法吧。

優化

✅ cdn

分析

用Webpack Bundle Analyzer分析依賴,安裝webpack-bundle-analyzer打包分析插件:


# NPM
npm install --save-dev webpack-bundle-analyzer

# Yarn
yarn add -D webpack-bundle-analyzer

反正都是裝,看着來。

配一下:

// vue.config.js 文件裏。(沒有就要新建一下)

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
 
module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}

打包

執行打包命令並查看分析

npm run build --report

打包結束後,會在項目根目錄下生成dist文件。自動跳到127.0.0.1:8888(沒有跳的話,手動打開dist文件夾下的report.html),這個網址就是打包分析報告

ScreenShot_2026-01-28_144100_449

佔得比較大的塊,就是Element UI組件庫和echarts庫佔的空間比相對較大。

這就要考慮,第一,要按需,要啥再用啥,不要一股腦啥都裝。按需安裝,按需加載。

第二,考慮單獨引入這些組件庫的cdn,這樣速度也會咔咔提升。

詳細講一下怎麼搞cdn

按需大家都知道,要啥再引入啥,再裝啥。

比如element-ui,我要uninstall掉,然後呢,去引入cdn,不要裝庫了,用cdn。

package.json裏面看element-ui裝了啥版本,然後看完之後,就npm uninstall element-ui卸載掉。

去cdn庫裏面去找https://www.staticfile.org/,(首先先説一下,要找免費的開放的那種,因為一般有的公司沒有自家的cdn,沒有自家的桶,有的話,直接把js文件地址拖上去,然後得到一個地址,這樣也安全,也方便,但沒有的話另説)。

ScreenShot_2026-01-28_144408_738

 

樣式庫: https://cdn.staticfile.org/element-ui/2.15.12/theme-chalk/index.min.css
組件庫:https://cdn.staticfile.org/element-ui/2.15.12/index.min.js

然後去public/index.html入口文件中,去加入這個東西,像咱以前寫原生一樣引入就好,body裏面引入js,head裏面引入css。:
<head>
<link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.15.12/theme-chalk/index.min.css">
</head>

<body>
<script src="https://cdn.staticfile.org/element-ui/2.15.12/index.min.js"></script>
</body>

所以這樣子,就引入好了。接着在main.js裏面,把之前import的所有element的樣式刪掉。

接着,vue.config.jsconfigureWebpack加個externals字段:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
 
module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ],
  externals: {
    'element-ui': 'ELEMENT' // key 是之前install下下來的包名,element-ui。value是全局變量名(ELEMENT)
  }
}

externals: Webpack 的 externals 配置用於聲明某些依賴應該從外部獲取,而不是打包到最終的 bundle 中。這樣可以減小打包體積,前提是這些依賴已經在運行環境中存在。

'element-ui': 'ELEMENT' 的含義

  • 當你的代碼中 import 'element-ui' 時,Webpack 不會打包 element-ui,而是會從全局變量 ELEMENT 中獲取它。
  • ELEMENTelement-ui 庫通過 <script> 標籤引入時,在全局(window)中暴露的變量名。
    例如,如果你在 HTML 中這樣引入:

<script src="https://unpkg.com/element-ui/lib/index.js"></script>

  • 那麼 element-ui 會掛載到 window.ELEMENT 上。

為什麼這樣配置?

  • 通常是為了通過 CDN 引入 element-ui(而不是打包它),從而優化構建速度和體積。
  • 你需要確保在 HTML 中通過 <script> 提前加載了 element-ui,否則運行時 ELEMENT 會是 undefined
<!-- HTML 中通過 CDN 引入 element-ui -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
// webpack.config.js
module.exports = {
  externals: {
    'element-ui': 'ELEMENT' // 告訴 Webpack:import 'element-ui' 時,返回全局的 ELEMENT
  }
};
// 你的代碼中依然可以正常 import(但實際用的是全局變量)
import ElementUI from 'element-ui';
// 相當於:const ElementUI = window.ELEMENT;

注意事項:

  • 確保全局變量名(ELEMENT)和 element-ui 的 CDN 版本一致。不同版本的庫可能有不同的全局變量名。
  • 如果使用模塊化打包(如 npm + Webpack 全量打包),則不需要配置 externals

這裏有的夥伴就説,我咋知道是ELEMENT,而不是element呢。

這裏是這麼找的:

直接在瀏覽器控制枱檢查 在 HTML 中通過 CDN 引入該庫:

<script src="https://cdn.staticfile.org/element-ui/2.15.12/index.min.js"></script>
打開瀏覽器開發者工具(F12),在 Console 中輸入:
console.log(window);

然後查找可能的全局變量名(如 ELEMENT、ElementUI 等)。

cdn配置之後,重新分析

npm run build --report

重新用cdn的去分析,

那麼就很舒服了,也因此,這個就是cdn優化的方法。

✅ nginx gzip壓縮

server {
        listen       8103;
        server_name  ************;
		# 開啓gzip
	    gzip on;
	    # 進行壓縮的文件類型。
	   	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;
	    # 是否在http header中添加Vary: Accept-Encoding,建議開啓
	    gzip_vary on;
}

✅vue gzip壓

安包:npm i compression-webpack-plugin@1.1.12 --save-dev

注意版本匹配問題。

vue配置,這段配置是 Webpack 構建中關於 Gzip 壓縮 的設置,位於 config/index.js 文件中。:

//文件路徑  config --> index.js
build: {
  productionGzip: true, // 啓用生產環境的 Gzip 壓縮
  productionGzipExtensions: ['js', 'css'], // 需要壓縮的文件類型
}

productionGzip: true

  • 作用:開啓 Gzip 壓縮,減少靜態資源(JS、CSS)的體積,提升頁面加載速度。
  • 要求:需要安裝 compression-webpack-plugin(如註釋所述)。

npm install --save-dev compression-webpack-plugin

  1. productionGzipExtensions: ['js', 'css']

    • 指定需要壓縮的文件擴展名(默認壓縮 JS 和 CSS 文件)。

為什麼需要 Gzip?

  • 優化性能:Gzip 壓縮後的資源體積可減少 60%~70%,顯著降低網絡傳輸時間。
  • 服務器支持:大多數現代服務器(如 Nginx、Netlify)會自動對靜態資源進行 Gzip 壓縮,但本地構建時提前生成 .gz 文件可以避免服務器實時壓縮的開銷。

✅ 按需加載路由

路由級代碼分割(動態導入)

// 原寫法
import About from './views/About.vue'

// 優化後寫法
const About = () => import(/* webpackChunkName: "about" */ './views/About.vue')
  • 首頁只加載核心代碼(home路由)
  • about模塊會在用户點擊about路由時才加載
  • 顯著減少首屏加載資源體積

✅ 合理配置 prefetch策略

// vue.config.js
module.exports = {
  chainWebpack: config => {
    // 移除prefetch插件
    config.plugins.delete('prefetch')
    
    // 或者更精細控制
    config.plugin('prefetch').tap(options => {
      options[0].fileBlacklist = options[0].fileBlacklist || []
      options[0].fileBlacklist.push(/myasyncRoute(.)+?\.js$/)
      return options
    })
  }
}
  • 禁用prefetch:減少不必要的帶寬消耗,但可能增加後續路由切換等待時間
  • 啓用prefetch:利用瀏覽器空閒時間預加載,提升用户體驗但可能浪費帶寬
  • 折中方案:只對關鍵路由或高概率訪問的路由啓用prefetch

✅ splitChunks 將node_modules中的依賴單獨打包

拆分vendor:將node_modules中的依賴單獨打包

config.optimization.splitChunks({
 chunks: 'all',
 cacheGroups: {
   vendors: {
     name: 'chunk-vendors',
     test: /[\\/]node_modules[\\/]/,
     priority: -10,
     chunks: 'initial'
   }
 }
})

✅ 按需引入 lodash

import debounce from 'lodash/debounce'

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文檔,大家一起討論學習,一起進步。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.