Terra 如何運用預先擷取功能,將廣告點閱率提升 30%,並加速最大內容繪製速度。

預先擷取資源可加快網頁載入時間,並改善業務指標。

Guilherme Moser de Souza
Guilherme Moser de Souza

預先載入是一種技術,可下載近期可能需要的資源 (甚至是整個網頁),藉此加快網頁載入速度。研究顯示,載入時間越短,轉換率就越高,使用者體驗也越好。

Terra 是巴西最大的內容入口網站之一,提供娛樂、新聞和體育內容,每月不重複訪客人數超過 6,300 萬。我們與 Terra 的工程團隊合作,在網站的特定部分使用預先載入技術,改善文章的載入時間。

本案例研究說明 Terra 導入旅程後,行動裝置的廣告點閱率 (CTR) 提升 11%、電腦的廣告點閱率提升 30%,以及 最大內容繪製 (LCP) 時間縮短 50%。

預先擷取策略

預先擷取功能已推出一段時間,但請務必謹慎使用,因為這會消耗頻寬,用於非立即必要的資源。請謹慎使用這項技巧,以免浪費資料。在 Terra 的情況下,如果符合下列條件,系統就會預先擷取文章:

  • 預先擷取文章連結的可見度:Terra 使用 Intersection Observer API 偵測包含預先擷取文章的區塊的可視度。
  • 增加資料用量的有利條件:如前所述,預先載入是一種會消耗額外資料的效能提升方式,且在某些情況下可能不是理想的結果。為降低浪費頻寬的可能性,Terra 會使用 Network Information APIDevice Memory API,判斷是否要擷取下一篇文章。Terra 只會在下列情況下擷取下一篇文章:
    • 連線速度至少為 3G,且裝置至少有 4 GB 的記憶體。
    • 或裝置搭載 iOS 系統。
  • CPU 閒置:最後,Terra 會使用 requestIdleCallback 檢查 CPU 是否處於閒置狀態,並能執行額外工作。這項檢查會在主執行緒處於閒置狀態時,或在特定 (選用) 期限到期時,處理回呼。

遵守這些條件可確保 Terra 只在必要時才擷取資料,進而節省頻寬和電池續航力,並盡可能減少未使用的預先擷取作業所造成的影響。

在符合這些條件時,Terra 會預先擷取「相關內容」和「推薦給你」(下方以藍色標示) 部分中的文章。

Terra 網站上兩個預先擷取連結的部分的螢幕截圖。左側會標示「相關內容」部分,右側則會標示「為你推薦」部分。

業務影響

為了評估這項做法的成效,Terra 首先在文章頁面的「相關內容」部分推出這項功能。他們使用 UTM 代碼來區分預先擷取的文章和未預先擷取的文章,以便進行比較。經過兩週的 A/B 版本測試後,Terra 決定在「推薦給您」專區中加入預先載入功能。

預先載入文章後,我們發現廣告指標整體提升,且 LCP 和首次字節回應時間 (TTFB) 縮短:

指標 行動裝置 電腦
廣告點閱率 +11% +30%
廣告可視度 +10.5% +6%
LCP -51% -73%
TTFB -83% -84%

預先載入功能 (若使用得當) 可大幅縮短網頁載入時間、提高廣告指標,並縮短 LCP 時間。

技術詳細資料

您可以使用資源提示 (例如 rel=prefetchrel=preload)、quicklinkGuess.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 採取額外步驟,只在網路狀況良好且裝置支援的情況下,在可取得這類資訊的裝置上預先載入。

特別感謝 Terra 工程團隊的 Gilberto Cocchi、Harry Theodoulou、Miguel Carlos Martínez Díaz、Barry Pollard、Jeremy Wagner、Leonardo Bellini 和 Lucca Paradeda 對這項工作的貢獻。