Vue前端優化術!三招讓你的網站更快更流暢

蘇靖軒 Jenson
企鵝也懂程式設計
7 min readApr 25, 2023

當前端系統的元素、功能越來越多後,就開始會遇到效能問題。
網站卡卡的總是讓心情不愉快,使用者不愉快客戶就不愉快,客戶不愉快工程師就準備遭殃了…。

有兩個方法可以來緩解這個感受:
1. UX 設計,透過載入動畫來緩解等待感受
2. 調教前端效能(本篇重點!)

事前準備

  • 一個寫好的 Vue SPA 網站
  • 一些 Webpack 知識
  • PageSpeed Insights

三個優化項目

  1. 啟用文字壓縮(Enable text compression
  2. 降低未使用 JavaScript 對網站效能的負擔(Reduce unused JavaScript)
  3. 緩存靜態文件(Serve static assets with an efficient cache policy)

1. 啟用文字壓縮(Enable text compression)

A compressed text-based resource is delivered to your browser faster (GTmetrix)

網站是由 html, text, javascript, css, json 等許多文字檔案所組成,如果這些檔案很大的時候,導致下載這些資源花費不少時間,也會大幅影響網頁載入時間。

方法 1:開啟 GZIP 壓縮

目前瀏覽器支援 Gzip, Brotli 及 Deflate 壓縮演算法,我們可以透過開啟壓縮這些文字資源,減小資源體積。

這裡我們用 NGINX 來開啟 GZIP 壓縮,不過有一些設定要注意:

  • 在 nginx 設定 gzip on; ,預設只壓縮 text/html,可以透過 gzip_types 增加壓縮格式,可參考 gzip_types
  • 對於 js、text、json、css 進行壓縮效果很好,不用改程式碼就可以提升網站響應速度
  • 壓縮過程要耗費 CPU,若對大文件 (圖片、音檔) 進行壓縮,不僅不能提升網頁速度,還會增加伺服器壓力

提供 NGINX 參數配置:

# 開啟 gzip
gzip on;

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

# gzip 壓縮等級,1-9,數字越大壓縮得越好,也越耗費 CPU,推薦6
gzip_comp_level 6;

# 設置壓縮所需的 buffer 大小 (可不設置)
gzip_buffers 16 8k;

# 設置 gzip 壓縮針對的 HTTP 版本
gzip_http_version 1.1;

# 選擇壓縮的文件類型
gzip_types text/plain text/css application/json application/javascript font/woff2 font/ttf image/svg+xml;

# 啟用 gzip 壓縮的最小文件大小,小於設置值不進行壓縮
gzip_min_length 1k;

# nginx 作為反向代理的時候啟用
gzip_proxied any;

查看一下啟用壓縮後的結果:

原本 chunk 是在 4.7 MB 左右。在 Size 行中,第一列 4.7 MB 為目前下載大小,第二列 4.7 MB 為原本資源大小,下圖的上下列數字都相同,代表都還沒有進行壓縮。

啟用壓縮後,JS 從 4.7 MB 壓縮為 1.3 MB,其他文件檔案也有不同程度的壓縮優化。

雖然 1.3 MB 還是很大,但依然可以看到明顯的優化。如果想要對 chunk 有更深度的優化,可以用 webpack 將 chunk split 成適合的大小,這部分以後專門寫一篇文章講解!

方法 2:uglifyjs-webpack-plugin

透過 webpack 引入 Uglifyjs,將程式碼做 Minimize & Uglify,這裡也提供相關配置,詳細的參數可以查看這裡

const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
optimization: {
minimizer: [new UglifyJsPlugin({
uglifyOptions: {
warnings: false,
compress: {
// 移除 debugger
drop_debugger: true,
// 移除console.*函数
drop_console: true,
// 移除console.log的引用
// 例如 log = console.log, 移除log,同時移除 console.log
pure_funcs: ['console.log']
}
},
// 多進程運行
parallel: true,
// 啟用緩存
cache: true,
// 抽取註釋
extractComments: true
})],
},
};

2. 降低未使用 JavaScript 對網站效能的負擔(Reduce unused JavaScript)

在 Vue 中,可以使用 tree shaking 技術來減少未使用的 JavaScript。
Tree shaking 是一種自動化的 JavaScript 優化技術,它可以刪除在項目中未使用的代碼。

可以注意一些引用的細節,例如 UI library 的按需引入、lodash tree shaking、Vue Lazy Loading Routes 等。

// replace
// import UserDetails from './views/UserDetails'
// with
const UserDetails = () => import('./views/UserDetails.vue')

const router = createRouter({
// ...
routes: [{ path: '/users/:id', component: UserDetails }],
})

3. 緩存靜態文件(Serve static assets with an efficient cache policy)

有許多資源,在資源尚未更新時,其實都是相同的,例如 chunk、css、圖片資源等。這些都可以透過緩存機制來優化反應速度,就不需要每次都請求最新的文件。

我們可以在 NGINX 加入協商緩存,作為優化的解決方案。這邊也談談兩個不同的緩存機制:強制緩存協商緩存。

強制緩存

  • 瀏覽器不與伺服器溝通,直接取瀏覽器的緩存(本地緩存)。除非資源過期,才會再去伺服器取資源
  • 強制緩存的相關標頭:Expires 和 Cache-Control,其中 Cache-Control 優先級比 Expires 高

協商緩存

  • 瀏覽器與伺服器溝通。第二次請求時,瀏覽器會首先將緩存標示發送給伺服器,服務器會判斷資源是否被更新,如果有更新會發送新資源
  • 新資源返回 200,緩存資源返回 304
  • 協商緩存的相關標頭:Last-Modified/IF-Modified-Since、Etag/IF-None-Match

協商緩存的開啟方式非常簡單,只要在 NGINX 做簡單設定就好

location / {
...
add_header Cache-Control no-cache;
}

開啟壓縮後,觀察 Network 下載資源的狀況。發現資源回覆 304 Not MOdified,且反應時間都非常的短!

Hi 我是 Jesnon,如果此篇教學對你有幫助,請留下 Clap 以及任何想法跟我分享!

--

--

蘇靖軒 Jenson
企鵝也懂程式設計

鵝肝前端佐後端風味醬汁,少許資料分析點綴,人生的擺盤,done