การดึงข้อมูลล่วงหน้าช่วยให้ Terra เพิ่มอัตราการคลิกผ่านโฆษณา 30% และทำให้ Largest Contentful Paint เร็วขึ้นได้อย่างไร

การดึงข้อมูลล่วงหน้าจะเพิ่มความเร็วในการโหลดหน้าเว็บและปรับปรุงเมตริกทางธุรกิจ

Guilherme Moser de Souza
Guilherme Moser de Souza

การโหลดล่วงหน้าเป็นเทคนิคที่ใช้ในการเพิ่มความเร็วในการโหลดหน้าเว็บโดยการดาวน์โหลดทรัพยากรหรือแม้แต่หน้าเว็บทั้งหน้าซึ่งอาจมีการใช้ในอนาคตอันใกล้ การวิจัยแสดงให้เห็นว่าเวลาในการโหลดที่เร็วขึ้นทําให้อัตรา Conversion สูงขึ้นและผู้ใช้ได้รับประสบการณ์การใช้งานที่ดีขึ้น

Terra เป็นพอร์ทัลเนื้อหาที่ใหญ่ที่สุดแห่งหนึ่งจากบราซิล ซึ่งให้บริการความบันเทิง ข่าวสาร และกีฬา โดยมีผู้เข้าชมที่ไม่ซ้ำกันมากกว่า 63 ล้านคนต่อเดือน เราได้ทำงานร่วมกับทีมวิศวกรของ Terra เพื่อปรับปรุงเวลาในการโหลดบทความโดยใช้เทคนิคการโหลดล่วงหน้าในบางส่วนในเว็บไซต์

กรณีศึกษานี้อธิบายการใช้งานเส้นทางของ Terra ซึ่งส่งผลให้อัตราการคลิกผ่าน (CTR) ของโฆษณาในอุปกรณ์เคลื่อนที่เพิ่มขึ้น 11%, CTR ของโฆษณาในเดสก์ท็อปเพิ่มขึ้น 30% และเวลา Largest Contentful Paint (LCP) ลดลง 50%

กลยุทธ์การเรียกข้อมูลล่วงหน้า

การดึงข้อมูลล่วงหน้ามีมานานแล้ว แต่คุณต้องใช้อย่างระมัดระวังเนื่องจากจะกินแบนด์วิดท์เพิ่มสำหรับทรัพยากรที่ไม่จำเป็นในทันที คุณควรใช้เทคนิคนี้อย่างรอบคอบเพื่อหลีกเลี่ยงการใช้อินเทอร์เน็ตโดยไม่จำเป็น ในกรณีของ Terra ระบบจะดึงข้อมูลบทความล่วงหน้าหากเป็นไปตามเงื่อนไขต่อไปนี้

  • ระดับการมองเห็นของลิงก์ไปยังบทความที่ระบบโหลดล่วงหน้า: Terra ใช้ Intersection Observer API เพื่อตรวจหาระดับการมองเห็นของส่วนที่มีบทความที่ต้องการโหลดล่วงหน้า
  • เงื่อนไขที่เหมาะสําหรับการใช้อินเทอร์เน็ตเพิ่มขึ้น: ตามที่กล่าวไว้ก่อนหน้านี้ การจําล่วงหน้าเป็นการปรับปรุงประสิทธิภาพโดยประมาณซึ่งจะใช้อินเทอร์เน็ตเพิ่ม และอาจไม่ใช่ผลลัพธ์ที่ต้องการในทุกสถานการณ์ Terra ใช้ Network Information API ร่วมกับ Device Memory API เพื่อพิจารณาว่าจะดึงข้อมูลบทความถัดไปหรือไม่ เพื่อลดโอกาสที่จะเกิดการสิ้นเปลืองแบนด์วิดท์ Terra จะดึงข้อมูลบทความถัดไปเฉพาะในกรณีต่อไปนี้
    • ความเร็วการเชื่อมต่ออย่างน้อย 3G และอุปกรณ์มีหน่วยความจำอย่างน้อย 4 GB
    • หรือหากอุปกรณ์ใช้ iOS
  • CPU ไม่ได้ใช้งาน: สุดท้าย Terra จะตรวจสอบว่า CPU ไม่ได้ใช้งานและสามารถทํางานเพิ่มเติมได้หรือไม่โดยใช้ requestIdleCallback ซึ่งจะใช้การเรียกกลับเพื่อประมวลผลเมื่อเธรดหลักไม่ได้ใช้งาน หรือตามกำหนดเวลา (ไม่บังคับ) ที่เจาะจง แล้วแต่ว่าอะไรจะเกิดขึ้นก่อน

การปฏิบัติตามเงื่อนไขเหล่านี้จะช่วยให้มั่นใจได้ว่า Terra จะดึงข้อมูลเฉพาะเมื่อจำเป็นเท่านั้น ซึ่งจะช่วยประหยัดแบนด์วิดท์และอายุการใช้งานแบตเตอรี่ รวมถึงลดผลกระทบของการเรียกข้อมูลล่วงหน้าที่ไม่ได้ใช้งาน

เมื่อเป็นไปตามเงื่อนไขเหล่านี้ Terra จะโหลดบทความล่วงหน้าในส่วน "เนื้อหาที่เกี่ยวข้อง" และ "แนะนำสำหรับคุณ" ที่ไฮไลต์ด้วยสีน้ำเงินด้านล่าง

ภาพหน้าจอของ 2 ส่วนในเว็บไซต์ Terra ที่ระบบได้ทำการดึงข้อมูลลิงก์ไว้ล่วงหน้า ทางด้านซ้าย มีการไฮไลต์ส่วน "เนื้อหาที่เกี่ยวข้อง" ส่วนทางด้านขวามีการไฮไลต์ส่วน "แนะนำสำหรับคุณ"

ผลกระทบทางธุรกิจ

Terra ได้เปิดตัวฟีเจอร์นี้ในส่วน "เนื้อหาที่เกี่ยวข้อง" ของหน้าบทความก่อน เพื่อวัดผลลัพธ์ของเทคนิคนี้ โค้ด UTM ช่วยให้บริษัทแยกความแตกต่างระหว่างบทความที่ดึงข้อมูลล่วงหน้าและบทความที่ไม่ได้ดึงข้อมูลล่วงหน้าเพื่อวัตถุประสงค์ในการเปรียบเทียบได้ หลังจากการทดสอบ A/B ที่ประสบความสําเร็จเป็นเวลา 2 สัปดาห์ Terra จึงตัดสินใจเพิ่มฟังก์ชันการโหลดล่วงหน้าลงในส่วน "แนะนําให้คุณ"

ผลการโหลดบทความล่วงหน้าคือเมตริกโฆษณาโดยรวมเพิ่มขึ้นและ LCP และเวลาในการตอบสนองครั้งแรก (TTFB) ลดลง

เมตริก อุปกรณ์เคลื่อนที่ เดสก์ท็อป
CTR ของโฆษณา +11% +30%
การมองเห็นโฆษณา +10.5% +6%
LCP -51% -73%
TTFB -83% -84%

การใช้การดึงข้อมูลล่วงหน้าอย่างระมัดระวังจะช่วยปรับปรุงเวลาในการโหลดหน้าเว็บ เพิ่มเมตริกโฆษณา และลดเวลา LCP ได้มาก

รายละเอียดทางเทคนิค

การเรียกข้อมูลล่วงหน้าทำได้โดยใช้คำแนะนำทรัพยากร เช่น rel=prefetch หรือ rel=preload ผ่านไลบรารี เช่น quicklink หรือ Guess.js หรือใช้ Speculation Rules API เวอร์ชันใหม่ Terra เลือกใช้วิธีนี้โดยใช้ fetch API ที่มีลําดับความสําคัญต่ำร่วมกับอินสแตนซ์ Intersection Observer Terra เลือกวิธีนี้เนื่องจากช่วยให้รองรับ Safari ซึ่งยังไม่รองรับวิธีการโหลดล่วงหน้าอื่นๆ เช่น rel=prefetch หรือ Speculation Rules API และไลบรารี JavaScript แบบเต็มรูปแบบไม่จำเป็นสำหรับความต้องการของ Terra

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 เพื่อตรวจสอบเมื่อองค์ประกอบปรากฏในวิวพอร์ต และเพิ่ม URL ลงในรายการสำหรับการโหลดล่วงหน้าในภายหลัง
  • ระบบจะกำหนดเวลากระบวนการเตรียมข้อมูลล่วงหน้าด้วย requestIdleCallback โดยมีเป้าหมายเพื่อเรียกใช้ฟังก์ชัน prefetch เมื่อเทรดหลักไม่มีการใช้งาน

บทสรุป

เมื่อใช้อย่างระมัดระวัง การป้อนข้อมูลล่วงหน้าจะช่วยลดเวลาในการโหลดคำขอไปยังส่วนต่างๆ ในอนาคตได้อย่างมาก จึงช่วยลดความยุ่งยากในเส้นทางของผู้ใช้และเพิ่มการมีส่วนร่วม การโหลดล่วงหน้าจะส่งผลให้มีการโหลดไบต์เพิ่มเติมที่อาจไม่ได้ใช้ Terra จึงดำเนินการเพิ่มเติมเพื่อโหลดล่วงหน้าเฉพาะในสภาพเครือข่ายที่ดีและในอุปกรณ์ที่พร้อมใช้งาน ซึ่งข้อมูลนี้พร้อมใช้งาน

ขอขอบคุณ Gilberto Cocchi, Harry Theodoulou, Miguel Carlos Martínez Díaz, Barry Pollard, Jeremy Wagner และ Leonardo Bellini และ Lucca Paradeda จากทีมวิศวกรของ Terra ที่ให้ความร่วมมือในงานนี้