預先擷取資源可加快網頁載入時間,並改善業務指標。
預先擷取是一種技術,可下載近期可能需要的資源 (甚至是整個網頁),藉此加快網頁載入速度。研究顯示,載入時間越短,轉換率就越高,使用者體驗也會更好。
Terra 是巴西最大的內容入口網站之一,提供娛樂、新聞和體育內容,每月不重複訪客人數超過 6,300 萬。我們與 Terra 的工程團隊合作,在網站的特定部分使用預先載入技術,改善文章的載入時間。
本案例研究說明 Terra 導入旅程後,行動裝置的廣告點閱率 (CTR) 提升 11%、電腦的廣告點閱率提升 30%,以及 最大內容繪製 (LCP) 時間縮短 50%。
預先擷取策略
預先擷取功能已推出一段時間,但請務必謹慎使用,因為這會消耗頻寬,用於非立即必要的資源。請謹慎採用這項做法,以免造成不必要的資料用量。在 Terra 的情況下,如果符合下列條件,系統就會預先擷取文章:
- 預先擷取文章連結的可視度:Terra 使用 Intersection Observer API 偵測包含預先擷取文章的區塊的可視度。
- 增加資料用量的有利條件:如前所述,預先載入是一種會消耗額外資料的效能提升方式,且在某些情況下可能不是理想的結果。為降低浪費頻寬的可能性,Terra 會使用 Network Information API 和 Device Memory API,判斷是否要擷取下一篇文章。Terra 只會在下列情況下擷取下一篇文章:
- 連線速度至少為 3G,且裝置至少有 4 GB 的記憶體。
- 或裝置搭載 iOS。
- CPU 閒置:最後,Terra 會使用
requestIdleCallback
檢查 CPU 是否處於閒置狀態,並能執行額外工作。這項檢查會在主執行緒處於閒置狀態時,或在特定 (選用) 期限到期時,處理回呼。
遵守這些條件可確保 Terra 只在必要時才擷取資料,進而節省頻寬和電池續航力,並盡可能減少未使用的預先擷取作業所造成的影響。
在符合這些條件時,Terra 會預先擷取「相關內容」和「推薦給你」(下方以藍色標示) 部分中的文章。
業務影響
為了評估這項做法的成效,Terra 首先在文章頁面的「相關內容」部分推出這項功能。他們使用 UTM 代碼來區分預先擷取的文章和未預先擷取的文章,以便進行比較。經過兩週的 A/B 版本測試後,Terra 決定在「推薦給您」專區中加入預先載入功能。
預先載入文章後,我們發現廣告指標整體提升,且 LCP 和首次字節回應時間 (TTFB) 縮短:
預先載入功能 (若使用得當) 可大幅縮短網頁載入時間、提高廣告指標,並縮短 LCP 時間。
技術詳細資料
您可以使用資源提示 (例如 rel=prefetch
或 rel=preload
)、quicklink 或 Guess.js 等程式庫,或是使用較新的 Speculation Rules API 來實現預先載入功能。Terra 選擇使用 fetch API 搭配低優先順序,並結合 Intersection Observer 例項,實作這項功能。Terra 做出這個選擇,是因為這樣可以支援 Safari,而 Safari 尚未支援其他預先載入方法,例如 rel=prefetch
或推測規則 API,而且 Terra 的需求並不需要完整功能的 JavaScript 程式庫。
下列 JavaScript 與 Terra 使用的程式碼大致相同:
function prefetch(nodeLists) {
// Exclude slow ECTs < 3g
if (navigator.connection &&
(navigator.connection.effectiveType === 'slow-2g'
|| navigator.connection.effectiveType === '2g')
) {
return;
}
// Exclude low end device which is device with memory <= 2GB
if (navigator.deviceMemory && navigator.deviceMemory <= 2) {
return;
}
const fetchLinkList = {};
const observer = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
if (!fetchLinkList[entry.target.href]) {
fetchLinkList[entry.target.href] = true;
fetch(entry.target, {
priority: 'low'
});
}
observer.unobserve(entry = entry.target);
}
});
});
}
const idleCallback = window.requestIdleCallback || function (cb) {
let start = Date.now();
return setTimeout(function () {
cb({
didTimeout: false,
timeRemaining: function () {
return Math.max(0, 50 - (Date.now() - start));
}
});
}, 1);
}
idleCallback(function () {
prefetch(nodeLists)
})
prefetch
函式會先檢查最低連線品質和裝置記憶體,再啟動預先擷取。- 接著,使用
IntersectionObserver
監控元素何時會在檢視區中顯示,並在之後將網址新增至預先載入清單。 - 預先載入程序會使用
requestIdleCallback
排程,目的是在主執行緒閒置時執行prefetch
函式。
結論
只要謹慎使用,預先載入功能就能大幅縮短日後導覽要求的載入時間,進而減少使用者歷程中的阻礙,並提高參與度。預先載入會載入可能不會使用的額外位元組,因此 Terra 採取額外步驟,只在網路狀況良好且裝置支援的情況下,在可取得這類資訊的裝置上預先載入。
特別感謝 Gilberto Cocchi、Harry Theodoulou、Miguel Carlos Martínez Díaz、Barry Pollard、Jeremy Wagner,以及 Terra 工程團隊的 Leonardo Bellini 和 Lucca Paradeda 對這項工作的貢獻。