เป็นเรื่องปกติที่หน้าเว็บจะต้องส่งข้อมูล (หรือ "บีคอน") กลับไปยังเซิร์ฟเวอร์ของตน เช่น ข้อมูลการวิเคราะห์สำหรับเซสชันปัจจุบันของผู้ใช้เป็นตัวอย่าง สำหรับนักพัฒนาซอฟต์แวร์ จะต้องมีการดำเนินการให้สมดุล กล่าวคือ การลดจำนวนคำขอคงที่ อาจซ้ำซ้อนกัน โดยไม่ต้องเสี่ยงพลาดข้อมูลหากแท็บปิดอยู่หรือเมื่อผู้ใช้ออกไปก่อนที่จะส่งบีคอน
เดิมทีนักพัฒนาซอฟต์แวร์ใช้เหตุการณ์ pagehide
และ visibilitychange
เพื่อตรวจจับหน้าเว็บเมื่อมีการยกเลิกการโหลด จากนั้นใช้ navigator.sendBeacon()
หรือ fetch()
ที่มี keepalive
เพื่อรับข้อมูลบีคอน อย่างไรก็ตาม ทั้ง 2 เหตุการณ์นี้มีปัญหามุมที่ยากลำบากซึ่งแตกต่างกันไปตามเบราว์เซอร์ของผู้ใช้ และบางครั้งก็ไม่มีเหตุการณ์ใดๆ เลย โดยเฉพาะบนอุปกรณ์เคลื่อนที่
fetchLater()
เป็นข้อเสนอเพื่อแทนที่ความซับซ้อนนี้ด้วยการเรียก API เดียว ซึ่งทำงานตรงตามชื่อ กล่าวคือ จะขอให้เบราว์เซอร์ตรวจสอบว่ามีการส่งคำขอเกิดขึ้นในอนาคต แม้ว่าหน้าเว็บจะปิดไปแล้วหรือผู้ใช้จะออกจากหน้าเว็บไป
fetchLater()
พร้อมใช้งานใน Chrome สำหรับการทดสอบกับผู้ใช้จริงหลังช่วงทดลองใช้จากต้นทาง โดยเริ่มตั้งแต่เวอร์ชัน 121 (เปิดตัวในเดือนมกราคม 2024) ซึ่งใช้ได้ถึง Chrome 126 (กรกฎาคม 2024)
fetchLater()
API
const fetchLaterResult = fetchLater(request, options);
fetchLater()
ใช้อาร์กิวเมนต์ 2 รายการ ซึ่งโดยทั่วไปจะเหมือนกับอาร์กิวเมนต์ของ fetch()
request
ซึ่งเป็น URL สตริงหรืออินสแตนซ์Request
- ออบเจ็กต์
options
ที่ไม่บังคับ ซึ่งขยายoptions
จากfetch()
โดยใช้ระยะหมดเวลาชื่อactivateAfter
fetchLater()
แสดงผล FetchLaterResult
ซึ่งปัจจุบันมีพร็อพเพอร์ตี้ activated
แบบอ่านอย่างเดียวเท่านั้น ซึ่งจะตั้งค่าเป็น true
เมื่อผ่านไปแล้ว "ภายหลัง" และมีการดึงข้อมูล ระบบยกเลิกการตอบกลับคำขอ fetchLater()
ทั้งหมด
request
การใช้งานที่ง่ายที่สุดคือ URL เพียงอย่างเดียว:
fetchLater('/endpoint/');
แต่เช่นเดียวกับ fetch()
ตัวเลือกจำนวนมากที่คุณจะกำหนดให้ส่งคำขอ fetchLater()
ได้ รวมถึงส่วนหัวที่กำหนดเอง ลักษณะการทำงานของข้อมูลเข้าสู่ระบบ เนื้อหาของ POST
และ AbortController
signal
ที่อาจยกเลิกได้
fetchLater('/endpoint/', {
method: 'GET',
cache: 'no-store',
mode: 'same-origin',
headers: {Authorization: 'SUPER_SECRET'},
});
options
ออบเจ็กต์ตัวเลือกจะขยายตัวเลือกของ fetch()
ด้วยการหมดเวลาคือ activateAfter
ในกรณีที่คุณต้องการให้คำขอเริ่มทํางานหลังจากหมดเวลาหรือเมื่อหน้ายกเลิกการโหลด ขึ้นอยู่กับว่ากรณีใดจะเกิดขึ้นก่อน
วิธีนี้ช่วยให้คุณตัดสินใจได้ว่าจะรับข้อมูลในช่วงเวลาสุดท้ายสัมบูรณ์หรือช่วงเวลาที่เหมาะสมมากกว่า
ตัวอย่างเช่น หากคุณมีแอปที่ผู้ใช้มักจะเปิดไว้ตลอดวันทำงาน คุณอาจต้องการระยะหมดเวลา 1 ชั่วโมงเพื่อให้มั่นใจถึงการวิเคราะห์ที่ละเอียดขึ้น ในขณะเดียวกันก็ยังรับประกันการบีคอนหากผู้ใช้ออกเมื่อใดก็ตามก่อนที่ชั่วโมงนั้นจะสิ้นสุดลง จากนั้นจะตั้งค่า fetchLater()
ใหม่เพื่อรับข้อมูลวิเคราะห์ 1 ชั่วโมงถัดไปได้
const hourInMilliseconds = 60 * 60 * 1000;
fetchLater('/endpoint/', {activateAfter: hourInMilliseconds});
ตัวอย่างการใช้
ปัญหาหนึ่งเมื่อวัด Core Web Vitals ในฟิลด์นี้คือเมตริกประสิทธิภาพใดๆ ก็ตามอาจเปลี่ยนแปลงได้จนกว่าผู้ใช้จะออกจากหน้าเว็บจริงๆ ตัวอย่างเช่น การเปลี่ยนเลย์เอาต์ที่ใหญ่ขึ้นอาจเกิดขึ้นได้ตลอดเวลา หรือหน้าเว็บอาจใช้เวลานานขึ้นในการตอบสนองต่อการโต้ตอบ
อย่างไรก็ตาม คุณไม่ควรเสี่ยงที่จะสูญเสียข้อมูลประสิทธิภาพทั้งหมดเนื่องจากมีข้อบกพร่องหรือบีคอนที่ไม่สมบูรณ์เมื่อยกเลิกการโหลดหน้า เหมาะอย่างยิ่งสำหรับ fetchLater()
ในตัวอย่างนี้ ไลบรารี web-vitals.js ใช้เพื่อตรวจสอบเมตริก และใช้ fetchLater()
เพื่อรายงานผลลัพธ์ไปยังปลายทางการวิเคราะห์
import {onCLS, onINP, onLCP} from 'web-vitals';
const queue = new Set();
let fetchLaterController;
let fetchLaterResult;
function updateQueue(metricUpdate) {
// If there was an already complete request for whatever
// reason, clear out the queue of already-sent updates.
if (fetchLaterResult?.activated) {
queue.clear();
}
queue.add(metricUpdate);
// JSON.stringify used here for simplicity and will likely include
// more data than you need. Replace with a preferred serialization.
const body = JSON.stringify([...queue]);
// Abort any existing `fetchLater()` and schedule a new one with
// the update included.
fetchLaterController?.abort();
fetchLaterController = new AbortController();
fetchLaterResult = fetchLater('/analytics', {
method: 'POST',
body,
signal: fetchLaterController.signal,
activateAfter: 60 * 60 * 1000, // Timeout to ensure timeliness.
});
}
onCLS(updateQueue);
onINP(updateQueue);
onLCP(updateQueue);
ทุกครั้งที่มีการอัปเดตเมตริก ระบบจะยกเลิก fetchLater()
ที่กำหนดเวลาไว้ที่มีอยู่ด้วย AbortController
และสร้าง fetchLater()
ใหม่พร้อมกับการอัปเดต
ลองใช้ fetchLater()
ตามที่ระบุไว้ fetchLater()
พร้อมใช้งานในช่วงทดลองใช้จากต้นทางจนถึง Chrome 126 ดูข้อมูลเบื้องต้นเกี่ยวกับช่วงทดลองใช้จากต้นทางได้ที่ "เริ่มต้นใช้งานช่วงทดลองใช้จากต้นทาง"
สำหรับการทดสอบในเครื่อง คุณเปิดใช้ fetchLater
ได้ด้วยแฟล็กฟีเจอร์แพลตฟอร์มเว็บแบบทดลองที่ chrome://flags/#enable-experimental-web-platform-features
นอกจากนี้ คุณยังเปิดใช้ Chrome จากบรรทัดคำสั่งด้วย --enable-experimental-web-platform-features
หรือแฟล็ก --enable-features=FetchLaterAPI
ที่ตรงเป้าหมายมากขึ้นได้ด้วย
หากใช้ในหน้าสาธารณะ โปรดตรวจสอบว่าได้ใช้ฟีเจอร์ Detect โดยตรวจสอบว่ามีการกำหนด fetchLater
ส่วนกลางหรือไม่ก่อนใช้งาน
if (globalThis.fetchLater) {
// Set up beaconing using fetchLater().
// ...
}
ความคิดเห็น
ความคิดเห็นของนักพัฒนาแอปเป็นสิ่งสำคัญในการทำให้ API เว็บใหม่ๆ ทำงานได้อย่างถูกต้อง โปรดแจ้งปัญหาและความคิดเห็นเกี่ยวกับ GitHub