Nuxt 效能
Nuxt 內建了旨在提升應用效能並改善核心 Web 指標的功能。此外,還有多個 Nuxt 核心模組可協助在特定領域提升效能。本指南概述了最佳化 Nuxt 應用效能的最佳實踐。
內建功能
Nuxt 提供了多項內建功能,可幫助您最佳化網站效能。瞭解這些功能的工作原理對於實現極速效能至關重要。
連結
<NuxtLink>
是 Vue Router 的 <RouterLink>
元件和 HTML 的 <a>
標籤的直接替代品。它智慧地判斷連結是內部連結還是外部連結,並根據可用的最佳化(預載入、預設屬性等)進行渲染。
<template>
<NuxtLink to="/about">About page</NuxtLink>
</template>
<!-- Which will render to with Vue Router & Smart Prefetching -->
<a href="/about">About page</a>
Nuxt 自動包含智慧預載入功能。這意味著它會檢測到連結何時可見(預設情況下),無論是在視口中還是在滾動時,並預載入這些頁面的 JavaScript,以便使用者點選連結時即可使用。
您也可以選擇在互動時進行預載入
export default defineNuxtConfig({
experimental: {
defaults: {
nuxtLink: {
prefetchOn: 'interaction',
},
},
},
})
混合渲染
在更復雜的應用中,我們可能需要完全控制應用的渲染方式,以支援某些頁面可以在構建時生成,而另一些頁面應該在客戶端渲染的情況。
混合渲染允許透過路由規則為每個路由設定不同的快取規則,並決定伺服器應如何響應給定 URL 的新請求。
export default defineNuxtConfig({
routeRules: {
'/': {
prerender: true,
},
'/products/**': {
swr: 3600,
},
'/blog': {
isr: 3600,
},
'/admin/**': {
ssr: false,
},
},
})
Nuxt 伺服器將自動註冊相應的中介軟體,並使用 Nitro 快取層將路由與快取處理程式包裝起來。
元件懶載入
要動態匯入元件(也稱為懶載入元件),您只需在元件名稱前新增 Lazy 字首即可。如果元件並非總是需要,這會很有用。
<script setup lang="ts">
const show = ref(false)
</script>
<template>
<div>
<h1>Mountains</h1>
<LazyMountainsList v-if="show" />
<button v-if="!show" @click="show = true">Show List</button>
</div>
</template>
透過使用 Lazy 字首,您可以將元件程式碼的載入延遲到合適的時機,這有助於最佳化 JavaScript 包大小。
懶惰水合
在初始載入時,並非總是需要水合(或使互動)網站的所有元件。透過使用懶惰水合,您可以控制何時載入元件的程式碼,從而改善應用的互動時間指標。Nuxt 允許您透過懶惰水合(在 Nuxt v3.16 中新增)控制組件何時變得可互動。
<template>
<div>
<LazyMyComponent hydrate-on-visible />
</div>
</template>
為了最佳化您的應用,您可能希望延遲某些元件的水合,直到它們可見,或者直到瀏覽器完成更重要的任務。
資料獲取
為了避免重複獲取相同資料(一次在伺服器上,一次在客戶端上),Nuxt 提供了 useFetch
和 useAsyncData
。它們確保如果 API 呼叫在伺服器上進行,資料會轉發到客戶端的 payload 中,而不是再次獲取。
Nuxt 核心模組
除了 Nuxt 的內建功能,還有由 Nuxt 團隊維護的核心模組,它們有助於進一步提升效能。這些模組有助於處理影像、自定義字型或第三方指令碼等資產。
圖片
未最佳化的影像會對您的網站效能產生顯著的負面影響,特別是最大內容繪製 (LCP)得分。
在 Nuxt 中,我們可以使用Vercel 上使用 Nuxt Image模組,它是 Nuxt 應用的即插即用影像最佳化解決方案。它允許您使用內建最佳化器或您喜歡的影像 CDN 來調整和轉換影像。
<NuxtImg>
是原生 <img>
標籤的直接替代品,並具有以下增強功能
- 使用內建提供程式最佳化本地和遠端影像
- 將
src
轉換為使用現代格式(如 WebP 或 Avif)最佳化的提供程式 URL - 根據
width
和height
自動調整影像大小 - 提供 sizes 選項時生成響應式
sizes
- 支援原生
lazy loading
以及其他<img>
屬性
您網站中的圖片通常可以按重要性進行分類;那些需要在初始載入時首先交付的(即 Largest Contentful Paint
),以及那些可以稍後載入或在特定需要時載入的。為此,我們可以使用以下最佳化措施
<template>
<!-- 🚨 Needs to be loaded ASAP -->
<NuxtImg
src="/hero-banner.jpg"
format="webp"
preload
loading="eager"
fetch-priority="high"
width="200"
height="100"
/>
<!-- 🐌 Can be loaded later -->
<NuxtImg
src="/facebook-logo.jpg"
format="webp"
loading="lazy"
fetch-priority="low"
width="200"
height="100"
/>
</template>
字型
Nuxt Fonts將自動最佳化您的字型(包括自定義字型),並消除外部網路請求,以提高隱私和效能。
它包含任何字型檔案的內建自動自託管功能,這意味著您可以以減少佈局偏移的方式最佳化載入網路字型,這得益於底層軟體包fontaine.
Nuxt Fonts 會處理您的所有 CSS,並在遇到 font-family 宣告時自動執行以下操作。
- 解析字型 – 在 public/ 中查詢字型檔案,然後檢查 Google、Bunny 和 Fontshare 等網路提供商。
- 生成 @font-face 規則 – 注入 CSS 規則以從正確的源載入字型。
- 代理和快取字型 – 重寫 URL 為
/_fonts
,並在本地下載和快取字型。 - 建立回退指標 – 調整本地系統字型以匹配網路字型,減少佈局偏移(CLS).
- 將字型包含在構建中 – 將字型與您的專案打包,對檔名進行雜湊處理並設定長期快取標頭。
它支援多個提供商,這些提供商被設計為可插拔和可擴充套件的,因此無論您的設定如何,您都應該能夠使用現有提供商或編寫自己的提供商。
指令碼
第三方資源,如分析工具、影片嵌入、地圖和社交媒體整合,可以增強網站功能,但會顯著降低使用者體驗,並對下次繪製互動時間 (INP)和最大內容繪製 (LCP) 分數產生負面影響。
Nuxt Scripts讓您以更好的效能、隱私、安全性和開發體驗載入第三方指令碼。
Nuxt Scripts 在第三方指令碼之上提供了一個抽象層,提供 SSR 支援和型別安全,同時仍為您提供對指令碼載入方式的完全底層控制。
const { onLoaded, proxy } = useScriptGoogleAnalytics(
{
id: 'G-1234567',
scriptOptions: {
trigger: 'manual',
},
},
)
// queue events to be sent when ga loads
proxy.gtag('config', 'UA-123456789-1')
// or wait until ga is loaded
onLoaded((gtag) => {
// script loaded
})
分析工具
要提升效能,我們首先需要知道如何衡量它,從在本地開發環境中衡量效能開始,然後轉向審計部署到生產環境中的應用程式。
Nuxi Analyze
此 nuxi
命令允許分析 Nuxt 應用程式的生產包。它利用 vite-bundle-visualizer
(類似於 webpack-bundle-analyzer
)生成應用程式包的視覺化表示,從而更容易識別哪些元件佔用空間最大。
當您在視覺化圖中看到一個大塊時,這通常意味著存在最佳化機會——無論是將其拆分成更小的部分、實現懶載入,還是用更高效的替代品替換它,特別是對於第三方庫而言。
包含多個元素的大塊通常可以透過僅匯入必要的元件而不是整個模組來減少,而大的獨立塊可能更適合懶載入而不是包含在主包中。
Nuxt DevTools
用於格式化的Nuxt DevTools為您提供 Nuxt 應用的洞察和透明度,以識別效能差距並無縫管理您的應用配置。
它附帶了幾個可用於衡量 Nuxt 應用效能的功能
- 時間線 – 跟蹤元件渲染、更新和初始化所花費的時間,以識別效能瓶頸。
- 資產 – 顯示檔案大小(例如,影像)而不進行轉換。
- 渲染樹 – 顯示 Vue 元件、指令碼和樣式之間的連線,以最佳化動態載入。
- 檢查 – 列出 Vue 應用中使用的所有檔案及其大小和評估時間。
Chrome 開發者工具
Chrome 開發者工具提供了兩個用於衡量效能的實用選項卡:Performance
和 Lighthouse
。
當您開啟效能面板時,它會立即顯示您本地的最大內容繪製 (LCP) 和累計佈局偏移 (CLS) 分數(良好、需要改進或差)。
如果您與頁面互動,它還會捕獲下次繪製互動時間 (INP),為您提供基於您的裝置和網路的完整核心 Web 指標檢視。
燈塔審計效能、可訪問性、SEO、漸進式 Web 應用和最佳實踐。它對您的頁面執行測試並生成報告。使用不合格的審計結果作為改進您網站的指導。
每個審計都有一個參考文件,解釋了審計為何重要以及如何修復它。
PageSpeed Insights
PageSpeed Insights (PSI)報告頁面在移動和桌面裝置上的使用者體驗,並提供如何改進該頁面的建議。
它提供關於頁面的實驗室資料和現場資料。實驗室資料有助於除錯問題,因為它是在受控環境中收集的,而現場資料有助於捕捉真實的、真實世界的使用者體驗。
網頁測試
WebPageTest是一個網路效能工具,提供有關頁面在各種條件下如何執行的深入診斷資訊。
每個測試都可以在世界各地的不同位置、在真實瀏覽器上、透過任意數量可定製的網路條件執行。
常見問題
在構建更復雜的 Nuxt 應用程式時,您可能會遇到下面列出的一些問題。理解並解決這些問題將有助於您提升網站效能。
過度使用外掛
問題:大量外掛可能會導致效能問題,尤其是當它們需要昂貴的計算或初始化時間過長時。由於外掛在水合階段執行,效率低下的設定可能會阻塞渲染並降低使用者體驗。
解決方案:檢查您的外掛,看看其中一些是否可以作為可組合函式或實用函式來實現。
未使用的程式碼/依賴項
問題:隨著專案的發展,可能會出現一些未使用的程式碼或依賴項。這些額外的功能可能沒有被使用或需要,但它會增加我們專案的打包大小。
解決方案:檢查您的 package.json
中是否存在未使用的依賴項,並分析您的程式碼中是否存在未使用的工具/可組合函式/函式。
不使用 Vue 效能技巧
問題: Vue 文件列出了一些我們也可以在 Nuxt 專案中使用的效能改進,但由於它們是 Vue 文件的一部分,開發人員往往會忘記它們,只關注 Nuxt 特定的改進——儘管 Nuxt 應用程式仍然是一個 Vue 專案。
解決方案:使用 shallowRef
、v-memo
、v-once
等概念來提升效能。
不遵循模式
問題:專案上工作的人越多,維護穩定的程式碼庫就越困難。開發人員傾向於引入他們在其他專案中見過的新概念,這可能會導致衝突和效能問題。
解決方案:在專案中建立規則和模式,例如Vue Composables 的最佳實踐和設計模式
嘗試同時載入所有內容
問題:當頁面載入時,如果未能正確指示元素載入順序,將導致所有內容同時獲取——這可能導致速度緩慢並帶來糟糕的使用者體驗。
解決方案:使用漸進增強等概念,首先設定核心網頁內容,然後隨著瀏覽器/網際網路連線的允許,在頂部新增更細緻和技術上更嚴格的呈現和功能層。
有用資源
要了解更多關於提高效能的各種技術,請參閱以下資源