發布日期:2025 年 10 月 14 日
與下一個顯示的內容互動 (INP) 是評估回應速度的重要 Core Web Vitals 指標。在 2024 年 INP 取代首次輸入延遲 (FID) 後,Google Search Console 顯示 Fotocasa 有大量網頁的 INP 評估結果變成「需要改善」和「不佳」。這份個案研究說明瞭我們用來診斷及解決這些問題的工具和策略,最終大幅提升了 INP。
Fotocasa 團隊的起點
在從 FID 改為 INP 之前,電腦和行動裝置上幾乎所有網頁都符合「良好」門檻,也就是當時所有網站體驗核心指標 (LCP、CLS 和 FID) 的成效都很好。不過,改用 INP 後,幾乎所有網頁都變成「需要改善」,有些甚至變成「不佳」,因為大多數使用者互動的 INP 值都超過 200 毫秒。
這項異動讓 Fotocasa 團隊意識到,他們忽略了使用者體驗的重要環節。FID 只會評估第一次互動的延遲時間,INP 則會評估所有互動的回應情形,並考量輸入處理和呈現延遲時間。這項更廣泛的評估指標是真正互動的絕佳替代指標 (如 Google所述),並突顯了錯失的商機。
雖然 Google Search Console 提供欄位成效資料,但不會提供即時洞察資料。這項資料是彙整 28 天內的資料,因此很難確切指出當時是哪些互動造成問題。
為了找出最慢且最常使用的互動,並在團隊的開發環境中可靠地重現這些互動,我們需要即時追蹤 INP。同樣重要的是瞭解所做變更的影響,不僅是哪些修正有幫助,還有哪些調整無意間讓情況變得更糟。
因此,我們使用了一組工具來診斷及解決問題。最重要的包括:
- Google Chrome 開發人員工具,特別是「效能」分頁。
- Fotocasa 團隊在 Datadog 中使用 web-vitals 程式庫建構的自訂 RUM (實際使用者監控) 系統。
- React 開發人員工具。
診斷問題的工具
如要診斷及偵錯 INP 效能問題,請使用下列工具。
Google Chrome 開發人員工具
如要偵測及重現與網頁應用程式中網站使用體驗核心指標相關的問題,最有效的方法是使用 Google Chrome 開發人員工具的「效能」分頁。「效能」分頁會自動評估網站體驗核心指標,即時提供載入、互動和版面配置轉移指標的回饋。這項指標的計算方式與其他 Google 工具的報表大致相同。
為找出並解決 INP 問題,Fotocasa 團隊通常會先節流 CPU,模擬低階和中階裝置的效能。Fotocasa 團隊因此得以觀察網頁在限制較多的情況下會如何運作。接著使用分析器記錄工作階段,並仔細分析追蹤記錄,著重於使用者互動,找出效能問題。
找出瓶頸時,特別有助於檢查 INP 子部分,以及瀏覽器在每個子部分中執行的工作。舉例來說,在下圖中,由於文件主體中的樣式變更導致兩次樣式重新計算,因此 INP 相當高。
Fotocasa 建立了一套系統,用來追蹤 INP 和其他核心網頁指標,確保能迅速找出並解決任何效能問題。當指標超過特定門檻 (根據 Google 定義的範圍),系統就會記錄歸因,以便分析及解決問題。
對於該系統,我們使用 web-vitals 程式庫,從實際使用者擷取這些指標,擷取方式與 Chrome 的測量方式完全一致,並將指標回報給其他 Google 工具 (例如 Chrome 使用者體驗報告、PageSpeed Insights 和 Search Console 的「速度」報告等)。
為了全面掌握情況並集中追蹤,Fotocasa 使用 Datadog 收集及顯示資料,讓團隊能夠根據資料做出明智的決策。自訂指標不僅有助於節省成本,還能更有效地追蹤 Fotocasa 網站上的幾乎所有使用者。
Fotocase 團隊可透過這套系統,迅速監控修改內容是否會影響指標,或是否發生可能導致指標失準的意外變更。接著,您可以將 INP 指標細分為輸入延遲、處理時間和呈現延遲等部分,準確找出導致互動時間過長的主要原因。
偵測到異常情況 (如圖 7 和 8 所示) 後,Fotocasa 立即採取行動,並使用 OpenSearch 找出可能發生變更的位置。Web Vitals 程式庫提供的資料有助於找出目標 (可能導致指標值偏高的 DOM 元素),並協助團隊更專注於修正問題。
此外,您還可以定義各種篩選器 (例如網頁類型、裝置或載入狀態),簡化情境並更準確地瞭解 INP 的影響。
React 開發人員工具
Fotocasa 運用 React 開發人員工具提升偵錯功能,這項強大功能可讓您醒目顯示重新算繪的元件。
如要啟用這項功能,請前往「分析器」分頁標籤。接著按一下頂端列右側的齒輪圖示,前往「一般」分頁,然後勾選「在元件算繪時醒目顯示更新內容」核取方塊。啟用這項功能後,元件會在重新算繪時醒目顯示,提供動態視覺化呈現方式。
找出重新算繪的原因
找出重新算繪的元件後,下一個問題是「為什麼會發生這種情況?」React 開發人員工具會在火焰圖檢視畫面中顯示實用工具提示,回答這個問題。
如要存取這項資訊,請錄製分析器工作階段。分析剖析器輸出內容,即可取得實用資訊:
- 右上角會顯示 React 提交次數。
- 火焰圖會以視覺化方式呈現元件樹狀結構,灰色表示未重新算繪的元件。每個長條代表 React 元件樹狀結構變更的時刻,以及對應變更提交至 DOM 的時刻。
- 將滑鼠游標懸停在火焰圖中的每個元件上,即可在「Why did this render?」(為何要重新算繪?)子標題下方,查看重新算繪的原因。
元件重新算繪的原因可能包括:
- 這是第一次算繪元件
- 內容已變更
- 已變更的掛鉤
- 屬性已變更
- 州別已變更
- 上層元件已算繪
找出轉譯時間
火焰圖中的顏色會傳達有意義的資訊。藍色等顏色代表相較於其他元件,元件所需的算繪時間較短。相反地,橘色和紅色等顏色表示元件的轉譯時間較長。
Fotocasa 團隊如何修正問題
移除不必要的重新算繪
每當 React 需要使用新資料更新 UI 時,就會重新算繪。這通常來自使用者動作、API 回應或其他需要更新使用者介面的重要事件。由於每次重新轉譯都會執行 JavaScript,因此一次重新轉譯太多內容 (尤其是在大型元件樹狀結構中) 可能會封鎖主執行緒,導致效能問題。
重新算繪分為兩種:
- 必要重新算繪:當元件擁有或使用新資料,確實需要更新時。
- 不必要的重新算繪:當元件更新時沒有任何有意義的變更,通常是因為狀態管理效率不彰或屬性處理不當。
幾個不必要的重新算繪通常不會造成大問題,因為 React 速度夠快,使用者一般不會注意到。不過,如果發生頻率過高,或是在大型元件樹狀結構中發生,可能會影響使用者體驗,並對網頁的 INP 造成負面影響。
Fotocasa 團隊就是如此。他們發現網站有許多不必要的重新算繪。這兩種情況分別是:
- 網頁載入期間:增加主執行緒上的長時間工作數量,並延遲首次互動,對網頁的 INP 造成負面影響。
- 使用者互動期間:大多數互動的處理時間增加,連帶影響 INP。
Fotocasa 網站上許多不必要的重新算繪作業都經過最佳化。其中一項重大最佳化措施是在「搜尋」頁面進行。網頁載入時發生三次不必要的重新算繪。移除這些項目後,我們觀察到以下結果:
- 減少長時間執行的工作數量 (如下圖所示)
- 總封鎖時間較短 (比較圖 14 和 15)
狀態共置
如果 React 狀態放置位置不當,可能會導致應用程式速度變慢,使用者介面也會感覺沒有回應。元件的狀態變更時,子項元件預設會重新算繪,除非使用逸出機制 (例如 memo)。
如上一節所述,重新算繪本身並非壞事,但如果因為特定狀態更新而重新算繪整個網頁,可能會導致互動變慢,因為 DOM 更新會在算繪後發生。
舉例來說,在「搜尋」頁面中,點選按鈕時會顯示對話方塊,其中列出所有篩選器。
在本例中,控制對話方塊開啟狀態的狀態會放在「搜尋」頁面。當這個狀態變更時,整個網頁都會重新算繪,導致 INP 偏低,特別是在較慢的裝置上更是如此 (如在開發人員工具中使用 CPU 節流時所見):
盡可能在觸發變更的元件附近變更狀態,即可解決這個問題。在這個特定案例中,狀態可以放在篩選器的按鈕元件中,這樣一來,狀態變更時,系統只會重新算繪按鈕。
移除不必要的狀態
狀態不應包含多餘或重複的資訊。否則可能會導致不必要的重新算繪,並造成問題。
舉例來說,在 Fotocasa 篩選器列中,會顯示文字,代表特定搜尋套用的篩選器數量:
系統會根據應用程式的狀態計算套用的篩選器數量。不過,這不僅會導致整個元件不必要的重新算繪,在某些情況下,由於這個元件是伺服器端算繪,還會導致版面配置位移:
const [filtersCount, setFiltersCount] = useState(DEFAULT_COUNTER)
useEffect(() => {
const counter = filters
? Object.keys(filters)
?.reduce(reducerCounter, [])
?.filter((param) => searchParams?.[param]).length
: DEFAULT_COUNTER
setFiltersCount(counter)
}, [searchParams]);
如要解決這個問題,值是使用變數從篩選器物件衍生而來,而不是使用狀態:
const counter = filters
? Object.keys(filters)
?.reduce(reducerCounter, [])
?.filter((param) => searchParams?.[param]).length
: DEFAULT_COUNTER;
減少耗費資源的算繪作業
React 應用程式發生互動時,通常會觸發狀態變更。如先前所述,當元件的狀態變更時,元件及其所有子項都會重新算繪。
如果其中一個元件的算繪函式速度緩慢,可能會產生長時間工作,導致 DOM 更新時間變長,進而對網頁的 INP 造成負面影響。
Fotocasa 團隊盡可能減少元件的算繪函式中耗時的運算作業。Chrome 開發人員工具和 React 開發人員工具在偵測緩慢的算繪作業時相當實用。
延遲執行程式碼
除了最佳化元件的算繪函式,我們也盡可能減少長時間執行的工作,並針對其他函式進行最佳化。不過,部分工作依附於第三方程式碼,因此無法最佳化。
其中一個例子是數據分析。在本例中,我們決定延後執行 Analytics 程式碼,並在發生使用者互動時優先更新 DOM。為此,Fotocasa 團隊使用了名為 idlefy 的程式庫,確保即使瀏覽器隨後立即關閉,分析程式碼仍會繼續執行。
績效文化
效能工作並非一次性作業,而是每次發布至正式環境的功能都必須考量的因素。團隊成員必須達成共識,否則網站體驗核心指標幾乎難以避免衰退。
為掌握這項資訊,Fotocasa 團隊積極在團隊內分享知識,並根據 Fotocasa 的 Datadog RUM 資料,建立明確的架構來找出效能問題,包括如何重現問題。在 RUM 系統中設定網站使用體驗核心指標 (尤其是 INP) 的快訊,並設定為直接在 Slack 中通知 Fotocasa 團隊。這種做法可確保效能維持在最佳狀態,並在問題演變成回歸之前及時發現。
結果
Fotocasa 必須結合技術最佳化和文化變革,才能改善 INP。Fotocasa 團隊淘汰不必要的重新轉譯作業、改善狀態放置位置、減少耗費資源的轉譯作業,以及延遲處理非重要程式碼,成功將所有電腦版網頁從「需要改善」提升至「良好」,並將幾乎所有「不良」和「需要改善」的行動版網頁升級至「良好」,大幅提升網頁效能。
這些變更提升了 Fotocasa 的整體使用者體驗,並與其他措施共同促成聯絡和電話開發潛在客戶廣告的轉換量增加 27%,直接強化了該公司的重要業務指標。
Fotocasa 團隊透過 Datadog 進行即時監控,驗證 INP 改善成效、快速偵測異常狀況,並防止回歸。除了這些成就,Fotocasa 也成功將網頁效能融入開發文化,確保每次發布新版本時,都會優先考量 INP 和網站體驗核心指標。