本個案研究將逐步說明 Trendyol 運用 PageSpeed Insights (PSI)、Chrome DevTools 和 scheduler.yield
API 等 Google 工具,對 Trendyol 使用的 INP 偵錯及改善 INP 工作流程。
任何電子商務網站的兩個關鍵元件都是產品資訊頁面 (PLP) 和產品詳細資料頁面 (PDP)。電子商務流量通常來自產品資訊頁面,包括電子郵件廣告活動、社群媒體或廣告。因此,務必要確保 PLP 服務經過精心設計,可以縮短購買時間。為了邁向成功,優先考量使用者體驗品質是非常重要的。Milliseconds Make Millions 等研究出版品已發現網站效能帶來重大影響,可讓使用者願意付費並在線上與品牌互動。
Trendyol 是一個電子商務平台,擁有約 3,000 萬名客戶和 24 萬個賣家,這促使我們成為土耳其的第一間企業,價值超過 $100 億美元,以及全球頂尖的電子商務平台之一。
為了達成大規模盡可能提供最佳使用者體驗的目標,同時維持內容的彈性並使用舊版 React,Trendyol 將重點放在「與下一個繪製內容互動」(INP) 做為改善的關鍵指標。本個案研究說明 Trendyol 如何改善 PLP 的 INP 體驗,結果不僅減少了 50% 的 INP,搜尋結果業務指標也提升 1% 。
Trendyol 的 INP 調查流程
INP 會評估網站回應使用者輸入內容的情形。良好的 INP 表示瀏覽器能夠快速且穩定地回應所有使用者輸入內容並重新繪製頁面,這是提供良好使用者體驗的關鍵要素。
Trendyol 希望先對 PLP 改善 INP,在做出任何改善前,先對使用者體驗進行全面分析。根據 PSI 報告,PLP 實際使用者體驗的 INP 為行動裝置 963 毫秒,如下圖所示。
為確保良好的回應速度,網站擁有者應將 INP 設定為低於或低於 200 毫秒,也就是說,Trendyol 的 INP 落在「不良」範圍內。
幸好,PSI 同時提供 Chrome 使用者體驗報告 (CrUX) 內網頁的欄位資料和詳細的研究室診斷資料。查看研究室資料後,Lighthouse 的 JavaScript 執行時間稽核顯示,search-result-v2
指令碼佔用主執行緒的時間比網頁上的其他指令碼更長。
為了找出實際遇到的瓶頸,我們使用 Chrome 開發人員工具中的效能面板排解 PLP 體驗問題,並找出問題的來源。在 Chrome 開發人員工具中,透過 4 倍 CPU 減速模擬行動裝置效能,展現了在主執行緒上耗時 700-900 毫秒的工作。如果主要執行緒與其他工作佔用的時間超過 50 毫秒,可能就無法及時回應使用者輸入內容,進而導致使用者體驗不佳。
最長的工作是由 React 元件內搜尋結果指令碼的 Intersection Observer API 回呼所造成。此時,我們開始將長時間的工作分為小區塊,讓瀏覽器有更多機會回應高優先順序的工作 (包括使用者互動)。
這證明瞭在 Intersection Observer 回呼中使用 setState
作業觸發 React 重新轉譯的成本高昂,這對於低階裝置而言,可能會長時間佔用主執行緒,進而造成問題。
開發人員曾使用一種方法,將工作分割成較小的工作,涉及 setTimeout
。我們曾使用這項技術,將 setState
呼叫的執行作業延後至另一項工作。雖然 setTimeout
允許延遲 JavaScript 執行,但無法控制優先順序。我們因此加入 scheduler.yield
來源試用,以確保指令碼在收到主執行緒後會繼續執行:
/*
* Yielding method using scheduler.yield, falling back to setTimeout:
*/
async function yieldToMain() {
if('scheduler' in window && 'yield' in scheduler) {
return await scheduler.yield();
}
return new Promise(resolve => {
setTimeout(resolve, 0);
});
}
/*
* Yielding to the main thread before changing the state of the component:
*/
const observer = new IntersectionObserver((entries) => {
entries.forEach(handleIntersection);
const maxNumberOfEntries = Math.max(...this.intersectingEntries);
if (Number.isFinite(maxNumberOfEntries)) {
await this.yieldToMain();
this.setState({ count: maxNumberOfEntries });
}
}, { threshold: 0.5 });
在 PLP 程式碼中加入這個產生方法可改善 INP,因為主要執行時間較長的工作已分割成一系列較小的工作,可加快優先順序較高的工作 (例如使用者互動和後續轉譯工作)。
請注意,Trendyol 使用 PuzzleJs 架構,以 React 16.9.0 版實作微前端架構。使用 React 18 可以達到相同的效能,但有許多原因,Trendyol 目前無法升級。
出色業務成果
為評估導入的 INP 改善措施帶來的影響,我們執行了 A/B 測試,以瞭解業務指標受到的影響。整體而言,我們對 PLP 的調整推動了大幅改善,包括減少 INP 的 INP,以及從產品資訊頁面到使用者工作階段中,從產品資訊頁面到產品詳細資料頁面的點閱率提升 1%。下圖顯示 INP 對 PLP 的長期改善情形:
結語
最佳化 INP 的程序相當複雜且反覆發生,但只要有明確的工作流程就能簡化。對網站 INP 進行偵錯和改善的簡單方法,取決於您是否收集自己的欄位資料。如果還沒,PSI 和 Lighthouse 會是很好的起點。找出有問題的網頁後,您可以使用開發人員工具進一步調查,嘗試重現問題。
不時讓主要執行緒產生收益,讓瀏覽器有更多執行緊急工作的機會,可以讓您的網站變得更加回應,確保客戶享有更優質的體驗。較新的排程 API (例如 scheduler.yield()
) 能簡化這項工作。
特別感謝 Google 的 Jeremy Wagner、Barry Pollard 和 Houssein Djirdeh,以及 Trendyol 的工程團隊對這項計畫的貢獻。