EP52 - 效能

閱讀時間約 14 分鐘
Performance 效能這個東西真的是每個領域的目標
調教效能真的蠻重要~但也是很多知識點的地方
感覺這篇文章一定蠻多內容 Orz...

概述​ - Overview

Vue 被設計為在大多數常見使用情境中表現良好,無需過多手動優化。然而,在一些具有挑戰性的場景中,仍需進行額外的微調。本文將探討在 Vue 應用程式中應注意的性能問題。

首先,我們來討論網頁性能的兩個主要方面:

  • 頁面加載性能:應用程式在首次訪問時顯示內容並變得可交互的速度。通常使用網頁核心指標如最大內容繪製時間 (Largest Contentful Paint, LCP) 和首次輸入延遲 (First Input Delay, FID) 來衡量。
  • 更新性能:應用程式對用戶輸入的響應速度。例如,當用戶在搜索框中輸入時列表更新的速度,或用戶在單頁應用程式 (SPA) 中點擊導航鏈接時頁面切換的速度。

儘管理想情況下應同時最大化這兩方面的性能,但不同的前端架構會影響達成所需性能的難易度。此外,您正在構建的應用程式類型也會極大影響性能優化的優先順序。因此,確保最佳性能的第一步是為您構建的應用程式類型選擇合適的架構:

請參考《使用 Vue 的方法》,了解如何以不同方式利用 Vue。

Jason Miller 在《應用程式類型》一文中討論了各類網頁應用程式及其各自的理想實現/交付方式。

性能分析選項​ - Profiling Options​

要提升性能,首先需要了解如何測量性能。有許多優秀的工具可以幫助完成這項工作:

用於測量生產部署的加載性能:

用於本地開發期間的性能測試:

頁面加載優化​ - Page Load Optimizations​

優化頁面加載性能有許多與框架無關的方法,請查看這篇 web.dev 指南 以獲取全面的總結。在這裡,我們主要關注 Vue 特有的技術。

選擇合適的架構​ - Choosing the Right Architecture

如果您的用例對頁面加載性能敏感,避免將其作為純客戶端 SPA 發布。您希望服務器直接發送包含用戶想要看到的內容的 HTML。純客戶端渲染的缺點是內容顯示速度慢。這可以通過服務端渲染 (SSR)靜態網站生成 (SSG) 來緩解。請參閱 SSR 指南 了解如何使用 Vue 執行 SSR。如果您的應用程序不需要豐富的交互性,也可以使用傳統的後端服務器來渲染 HTML,並在客戶端使用 Vue 增強它。

如果您的主要應用程序必須是 SPA,但有一些營銷頁面(登陸頁面、關於頁面、博客),請將它們單獨發布!您的營銷頁面應該理想地作為靜態 HTML 部署,並使用最少的 JS,通過 SSG 來實現。

打包尺寸和瘦身技術​ - Bundle Size and Tree-shaking

提升頁面加載性能的最有效方法之一是減少 JavaScript 包的大小。以下是使用 Vue 時減少包大小的一些方法:

  • 如果可能,使用構建步驟。
  1. Vue 的許多 API 如果通過現代構建工具打包是 "tree-shakable" 的。例如,如果您不使用內置的 <Transition> 組件,它將不會包含在最終的生產包中。Tree-shaking 還可以移除源代碼中其他未使用的模塊。
  2. 使用構建步驟時,模板是預編譯的,因此我們不需要將 Vue 編譯器傳送到瀏覽器。這樣可以節省 14kb 壓縮後的 JavaScript 並避免運行時編譯成本。
  • 引入新依賴項時要謹慎!在真實世界的應用中,膨脹的包通常是引入了沉重的依賴項而未意識到它。
  1. 如果使用構建步驟,首選提供 ES 模塊格式並支持 tree-shaking 的依賴項。例如,首選 lodash-es 而非 lodash
  2. 檢查依賴項的大小並評估其提供的功能是否值得。注意如果依賴項支持 tree-shaking,實際的大小增加將取決於您實際導入的 API。可以使用 bundlejs.com 進行快速檢查,但使用實際構建設置進行測量始終是最準確的。
  • 如果您主要使用 Vue 進行漸進增強並希望避免構建步驟,請考慮使用 petite-vue(僅 6kb)。

代碼分割​ - Code Splitting

代碼分割是指構建工具將應用程序包分割成多個較小的塊,然後按需或並行加載。通過適當的代碼分割,可以立即下載頁面加載所需的功能,而其他塊僅在需要時延遲加載,從而提升性能。

例如,Rollup(Vite 基於此)或 webpack 可以通過檢測 ESM 動態導入語法自動創建分割塊:

// lazy.js 及其依賴項將被分割成一個單獨的塊
// 並且僅在調用 `loadLazy()` 時加載。
function loadLazy() {
return import('./lazy.js')
}

延遲加載最好用於初始頁面加載後不立即需要的功能。在 Vue 應用程序中,可以結合 Vue 的異步組件功能來為組件樹創建分割塊:

import { defineAsyncComponent } from 'vue'

// Foo.vue 及其依賴項將被創建成一個單獨的塊。
// 當異步組件在頁面上渲染時,它才會按需加載。
const Foo = defineAsyncComponent(() => import('./Foo.vue'))

對於使用 Vue Router 的應用程序,強烈建議對路由組件使用延遲加載。Vue Router 有專門支持延遲加載(lazy loading)的功能,從defineAsyncComponent分離出來,詳情請參閱 延遲加載路由

更新優化 - Update Optimizations​

Props 穩定性 - Props Stability

在 Vue 中,只有當接收到的 props 至少有一個發生改變時,子組件才會更新。考慮以下示例:

<ListItem
v-for="item in list"
:id="item.id"
:active-id="activeId" />`

<ListItem> 組件內部,它使用 idactiveId props 來判斷是否是當前活動的項目。雖然這種方法有效,但問題在於每次 activeId 改變時,列表中的每個 <ListItem> 都必須更新!

理想情況下,只有那些活動狀態改變的項目應該更新。我們可以通過將活動狀態的計算移到父組件中,並使 <ListItem> 直接接受一個 active prop 來實現:

<ListItem
v-for="item in list"
:id="item.id"
:active="item.id === activeId" />

現在,對於大多數組件來說,當 activeId 改變時,active prop 將保持不變,因此它們不再需要更新。總的來說,保持傳遞給子組件的 props 盡可能穩定是關鍵。

v-once

v-once 是一個內置指令,可用於渲染依賴運行時數據但不需要更新的內容。使用 v-once 的整個子樹將在所有未來的更新中被跳過。詳細信息請參閱其 API 參考

v-memo

v-memo 是一個內置指令,可用於有條件地跳過大型子樹或 v-for 列表的更新。詳細信息請參閱其 API 參考

計算屬性穩定性 - Computed Stability

在 Vue 3.4 及更高版本中,計算屬性僅在其計算值與前一個值發生變化時才會觸發效果。例如,以下 isEven 計算屬性僅在返回值從 true 變為 false 或反之時才會觸發效果:

const count = ref(0)
const isEven = computed(() => count.value % 2 === 0)

watchEffect(() => console.log(isEven.value)) // true

// 不會觸發新的日志,因為計算值保持為 `true`
count.value = 2
count.value = 4

這減少了不必要的效果觸發,但如果計算屬性每次計算都會創建一個新對象,則無法生效:

const computedObj = computed(() => {
return {
isEven: count.value % 2 === 0
}
})

由於每次都創建了一個新對象,技術上新值總是與舊值不同。即使 isEven 屬性保持不變,Vue 也無法知道,除非進行深度比較,而這種比較可能代價高昂且不值得。

相反,我們可以通過手動比較新值與舊值,並在確定沒有變化時有條件地返回舊值來進行優化:

const computedObj = computed((oldValue) => {
const newValue = {
isEven: count.value % 2 === 0
}
if (oldValue && oldValue.isEven === newValue.isEven) {
return oldValue
}
return newValue
})

Try it in the playground

注意,你應該始終在比較並返回舊值之前完成完整的計算,以便在每次運行時都能收集相同的依賴項。

一般優化 - General Optimizations​

以下技巧影響頁面加載和更新性能。

虛擬化大型列表

在所有前端應用中,渲染大型列表是最常見的性能問題之一。無論框架有多高效,由於瀏覽器需要處理的大量 DOM 節點,渲染包含數千項的列表都會變得緩慢。

然而,我們並不一定需要預先渲染所有這些節點。在大多數情況下,用戶的屏幕尺寸只能顯示我們大型列表中的一小部分。我們可以通過列表虛擬化技術來大幅提高性能,這種技術僅渲染當前在視口或接近視口的項目。

實現列表虛擬化並不容易,但幸運的是,有現成的社區庫可以直接使用:

減少大型不可變結構的響應性開銷 - Reduce Reactivity Overhead for Large Immutable Structures

Vue 的響應性系統默認是深度的。雖然這使狀態管理直觀,但當數據量很大時,會產生一定程度的開銷,因為每次訪問屬性都會觸發代理陷阱來進行依賴追蹤。這通常在處理大型深層嵌套對象數組時變得顯著,其中單次渲染需要訪問 100,000 多個屬性,因此僅會影響特定用例。

Vue 提供了一個逃生口來選擇退出深度響應性,使用 shallowRef()shallowReactive()。淺層 API 創建的狀態僅在根級別是響應的,並且暴露所有未修改的嵌套對象。這使嵌套屬性訪問速度更快,代價是我們現在必須將所有嵌套對象視為不可變的,並且只能通過替換根狀態來觸發更新:

const shallowArray = shallowRef([
/* 大量深層對象列表 */
])

// 這不會觸發更新...
shallowArray.value.push(newObject)
// 這會觸發:
shallowArray.value = [...shallowArray.value, newObject]

// 這不會觸發更新...
shallowArray.value[0].foo = 1
// 這會觸發:
shallowArray.value = [
{
...shallowArray.value[0],
foo: 1
},
...shallowArray.value.slice(1)
]

避免不必要的組件抽象 - Avoid Unnecessary Component Abstractions

有時我們可能會為了更好的抽象或代碼組織,創建無渲染組件或高階組件(即使用額外 props 渲染其他組件的組件)。雖然這本身並沒有問題,但請記住,組件實例比純 DOM 節點昂貴得多,由於抽象模式創建過多組件實例將會產生性能成本。

請注意,減少少量實例不會有顯著效果,因此如果組件在應用中只渲染幾次,不要過於擔心。最佳情況是再次考慮在大型列表中進行此優化。想象一個包含 100 個項目的列表,其中每個項目組件包含許多子組件。在這裡移除一個不必要的組件抽象可能會導致數百個組件實例的減少。

看完這些還是不太清楚,效能差異多少?
要來實際操作看看那些效能工具吧!!!
先記住有這些方法跟工具吧~www


avatar-img
2會員
71內容數
分享生活趣事~
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
卡關的人生 的其他內容
在生產部署中,Vue 提供開發環境及生產環境的最佳實踐。開發階段有錯誤警告、驗證等功能,但生產環境須去除開發代碼以提升效能。未使用建構工具時,建議使用 .prod.js 生產版;使用工具如 Vite 或 Vue CLI 時,已預設生產配置,適合進行部署。
Server-Side Rendering (SSR) 是將 Vue.js 組件在伺服器上渲染為 HTML 字串,並直接發送到瀏覽器的一種技術。這樣可以提升頁面顯示速度,尤其在網速慢或設備性能差的情況下。SSR 應用的代碼可在伺服器和客戶端上共享,提高開發效率。
測試對於構建複雜的 Vue 應用至關重要,因為它能防止回歸並鼓勵將應用拆分為可測試的模組。我們介紹了測試的基本術語和推薦的工具,包括單元測試、組件測試和端對端測試。建議越早開始測試,避免隨著時間推移而增加的相依性。單元測試專注於函數和邏輯的正確性,而組件測試則驗證 UI 元素的行為與交互。
狀態管理在 Vue 應用中非常重要,尤其是當多個組件需要共享狀態時。每個 Vue 組件管理自己的響應式狀態,但隨著組件數量增加,簡單的管理方式可能變得複雜。這時,可以使用如 Pinia 的狀態管理庫來簡化這一過程。Pinia 提供了一個更簡單的 API 和更強的類型推斷,並由 Vue 核心團隊維護。
前後端路由的協作是現代應用開發的重要部分。後端路由根據用戶的 URL 發送相應的回應,而前端路由則使得單頁應用(SPA)能在不重新加載整個頁面的情況下更新內容。前端路由會攔截用戶的導航,並動態加載所需的組件。
Vite 作為輕量快速的建置工具,原生支持 Vue SFC,並且提供簡化的配置與優越的開發體驗。文章還介紹了 IDE 支援、測試工具(如 Cypress 和 Vitest)、Linting 和格式化工具的使用,幫助開發者提高開發效率與代碼質量。
在生產部署中,Vue 提供開發環境及生產環境的最佳實踐。開發階段有錯誤警告、驗證等功能,但生產環境須去除開發代碼以提升效能。未使用建構工具時,建議使用 .prod.js 生產版;使用工具如 Vite 或 Vue CLI 時,已預設生產配置,適合進行部署。
Server-Side Rendering (SSR) 是將 Vue.js 組件在伺服器上渲染為 HTML 字串,並直接發送到瀏覽器的一種技術。這樣可以提升頁面顯示速度,尤其在網速慢或設備性能差的情況下。SSR 應用的代碼可在伺服器和客戶端上共享,提高開發效率。
測試對於構建複雜的 Vue 應用至關重要,因為它能防止回歸並鼓勵將應用拆分為可測試的模組。我們介紹了測試的基本術語和推薦的工具,包括單元測試、組件測試和端對端測試。建議越早開始測試,避免隨著時間推移而增加的相依性。單元測試專注於函數和邏輯的正確性,而組件測試則驗證 UI 元素的行為與交互。
狀態管理在 Vue 應用中非常重要,尤其是當多個組件需要共享狀態時。每個 Vue 組件管理自己的響應式狀態,但隨著組件數量增加,簡單的管理方式可能變得複雜。這時,可以使用如 Pinia 的狀態管理庫來簡化這一過程。Pinia 提供了一個更簡單的 API 和更強的類型推斷,並由 Vue 核心團隊維護。
前後端路由的協作是現代應用開發的重要部分。後端路由根據用戶的 URL 發送相應的回應,而前端路由則使得單頁應用(SPA)能在不重新加載整個頁面的情況下更新內容。前端路由會攔截用戶的導航,並動態加載所需的組件。
Vite 作為輕量快速的建置工具,原生支持 Vue SFC,並且提供簡化的配置與優越的開發體驗。文章還介紹了 IDE 支援、測試工具(如 Cypress 和 Vitest)、Linting 和格式化工具的使用,幫助開發者提高開發效率與代碼質量。
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
在數位時代,SEO(搜尋引擎優化)已成為創業者提升網站排名、吸引流量的關鍵工具。網站結構的優化對於SEO的影響不可小覷,它能直接決定網站在搜尋引擎結果中的位置。本文將探討如何利用網站結構優化來提升排名,並介紹如何借助專業的SEO公司服務,進一步增強數位行銷的效果。 一、網站結構優化的重要性
Thumbnail
本篇文章是根據知名 SEO 軟體開發商 Ahrefs 在分析一百多萬個網址後,所整理出來的技術性 SEO 問題以及對應的解決方案。
假設用戶在 Google 搜尋關鍵字「SEO」,而您的網站在搜尋結果頁面中出現了335次,這樣就表示您的網站獲得了335次的曝光。|SEO工具 網頁速度是什麼? 網頁速度英文名稱 Page speed,是衡量頁面內容載入速度的指標,網頁速度越快,表示使用者在打開網頁的時候,可以更快看到內容,而不
Thumbnail
Windows Clarity 是一種網站分析產品,讓網站設計師、開發人員可藉由它,更容易觀察用戶在網站的操作行為,協助更快速的優化網站,加強網頁的轉換效果與商業目標的達成。本文將介紹 Windows Clarity 應該如何使用,強化分析能力與優化網站效益。
Thumbnail
在當今的IG時代,多媒體內容已成為網頁設計不可或缺的一部分,它不僅豐富了用戶的互動體驗,還能顯著提升網站的吸引力和溝通效率。本文將探討多媒體內容對用戶體驗(UX)的影響、SEO最佳實踐與多媒體的整合方法,並提供成功整合多媒體的網站案例。
Thumbnail
交互式元素在現代網頁設計中扮演著越來越重要的角色,不僅因為它們能夠提升用戶體驗,還因為它們對搜索引擎最佳化(SEO)帶來的潛在好處。本文將探討交互式設計對SEO的好處、實施交互式元素的方法,並通過一個成功案例分析,展示這些元素如何有效地提升網站性能和搜索排名。
圖片大小 漂亮的圖片讓人賞心悅目,對網站美化也是一大加分項,但若是為了呈現自家商品或吸引人的圖片搭配文字,而塞進過量的圖片,導致網站本身太重跑得太慢,容易使客人失去耐性。|SEO工具 隨著時代的進步網路速度也與時俱進,但若網站本身太重,就算網路狀況再良好也無法馬上將網站載好,根據統計,大多數人的
透過Responsive網頁設計技術,能夠讓您的網站在不同裝置上顯示良好。此外,我們的服務還包括多種語言介面支援、內容管理系統、無限頁數網站、無限網上影片、無限網上表格以及專業的Banner設計。
Thumbnail
在現代數位時代,架設網站已成為企業和個人展示品牌、提供資訊、吸引客戶的不可或缺之一。然而,要建立一個成功的網站不僅僅是擁有吸引人的設計,還需要考慮多方面的因素,以確保網站的效能和使用者體驗達到最佳化。
Thumbnail
※ 效能 What tools would you use to monitor or analyze your performance ? 中文意思:在監控或分析系統性能方面可能會使用哪些工具? ※ 解答: 常見的監控和分析工具,可分成以下6大類: 系統監控工具: 例如,Promethe
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
在數位時代,SEO(搜尋引擎優化)已成為創業者提升網站排名、吸引流量的關鍵工具。網站結構的優化對於SEO的影響不可小覷,它能直接決定網站在搜尋引擎結果中的位置。本文將探討如何利用網站結構優化來提升排名,並介紹如何借助專業的SEO公司服務,進一步增強數位行銷的效果。 一、網站結構優化的重要性
Thumbnail
本篇文章是根據知名 SEO 軟體開發商 Ahrefs 在分析一百多萬個網址後,所整理出來的技術性 SEO 問題以及對應的解決方案。
假設用戶在 Google 搜尋關鍵字「SEO」,而您的網站在搜尋結果頁面中出現了335次,這樣就表示您的網站獲得了335次的曝光。|SEO工具 網頁速度是什麼? 網頁速度英文名稱 Page speed,是衡量頁面內容載入速度的指標,網頁速度越快,表示使用者在打開網頁的時候,可以更快看到內容,而不
Thumbnail
Windows Clarity 是一種網站分析產品,讓網站設計師、開發人員可藉由它,更容易觀察用戶在網站的操作行為,協助更快速的優化網站,加強網頁的轉換效果與商業目標的達成。本文將介紹 Windows Clarity 應該如何使用,強化分析能力與優化網站效益。
Thumbnail
在當今的IG時代,多媒體內容已成為網頁設計不可或缺的一部分,它不僅豐富了用戶的互動體驗,還能顯著提升網站的吸引力和溝通效率。本文將探討多媒體內容對用戶體驗(UX)的影響、SEO最佳實踐與多媒體的整合方法,並提供成功整合多媒體的網站案例。
Thumbnail
交互式元素在現代網頁設計中扮演著越來越重要的角色,不僅因為它們能夠提升用戶體驗,還因為它們對搜索引擎最佳化(SEO)帶來的潛在好處。本文將探討交互式設計對SEO的好處、實施交互式元素的方法,並通過一個成功案例分析,展示這些元素如何有效地提升網站性能和搜索排名。
圖片大小 漂亮的圖片讓人賞心悅目,對網站美化也是一大加分項,但若是為了呈現自家商品或吸引人的圖片搭配文字,而塞進過量的圖片,導致網站本身太重跑得太慢,容易使客人失去耐性。|SEO工具 隨著時代的進步網路速度也與時俱進,但若網站本身太重,就算網路狀況再良好也無法馬上將網站載好,根據統計,大多數人的
透過Responsive網頁設計技術,能夠讓您的網站在不同裝置上顯示良好。此外,我們的服務還包括多種語言介面支援、內容管理系統、無限頁數網站、無限網上影片、無限網上表格以及專業的Banner設計。
Thumbnail
在現代數位時代,架設網站已成為企業和個人展示品牌、提供資訊、吸引客戶的不可或缺之一。然而,要建立一個成功的網站不僅僅是擁有吸引人的設計,還需要考慮多方面的因素,以確保網站的效能和使用者體驗達到最佳化。
Thumbnail
※ 效能 What tools would you use to monitor or analyze your performance ? 中文意思:在監控或分析系統性能方面可能會使用哪些工具? ※ 解答: 常見的監控和分析工具,可分成以下6大類: 系統監控工具: 例如,Promethe