เป็นเรื่องปกติที่หน้าเว็บจะต้องส่งข้อมูล (หรือ "บีคอน") กลับไปยังเซิร์ฟเวอร์ของตน ลองนึกถึงข้อมูลวิเคราะห์สำหรับเซสชันปัจจุบันของผู้ใช้เป็นตัวอย่าง สําหรับนักพัฒนาแอป การดำเนินการนี้ต้องอาศัยความสมดุลระหว่างการลดคําขอที่ส่งอย่างต่อเนื่องและอาจซ้ำซ้อนโดยไม่เสี่ยงที่จะพลาดข้อมูลหากมีการปิดแท็บหรือผู้ใช้ไปยังส่วนอื่นก่อนที่ส่งบีคอนได้
เดิมทีนักพัฒนาซอฟต์แวร์ใช้เหตุการณ์ pagehide
และ visibilitychange
เพื่อจับหน้าเว็บขณะที่ระบบยกเลิกการโหลด จากนั้นใช้ navigator.sendBeacon()
หรือ fetch()
ที่มี keepalive
เพื่อส่งข้อมูลบีคอน อย่างไรก็ตาม เหตุการณ์ทั้ง 2 รายการนี้มีปัญหาเฉพาะที่ยากซึ่งแตกต่างกันไปตามเบราว์เซอร์ของผู้ใช้ และบางครั้งเหตุการณ์อาจไม่เกิดขึ้นเลย โดยเฉพาะบนอุปกรณ์เคลื่อนที่
fetchLater()
คือข้อเสนอที่จะแทนที่ความซับซ้อนนี้ด้วยการเรียก API ครั้งเดียว ซึ่งทํางานตามที่ชื่อบอกไว้ทุกประการ กล่าวคือจะขอให้เบราว์เซอร์ส่งคําขอในอนาคต ณ เวลาใดเวลาหนึ่ง แม้ว่าหน้าเว็บจะปิดอยู่หรือผู้ใช้จะไปยังหน้าอื่นแล้วก็ตาม
fetchLater()
พร้อมใช้งานใน Chrome สำหรับการทดสอบกับผู้ใช้จริงในช่วงทดลองใช้จากต้นทางตั้งแต่เวอร์ชัน 121 (เปิดตัวในเดือนมกราคม 2024) จนถึงวันที่ 3 กันยายน 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
body และ AbortController
signal
เพื่อยกเลิกคําขอได้
fetchLater('/endpoint/', {
method: 'GET',
cache: 'no-store',
mode: 'same-origin',
headers: {Authorization: 'SUPER_SECRET'},
});
options
ออบเจ็กต์ตัวเลือกจะขยายตัวเลือกของ fetch()
ด้วยระยะหมดเวลา activateAfter
ในกรณีที่คุณต้องการให้คำขอเริ่มทำงานหลังจากหมดเวลา หรือเมื่อหน้าเว็บยกเลิกการโหลด ขึ้นอยู่กับว่ากรณีใดจะเกิดขึ้นก่อน
ซึ่งจะช่วยให้คุณตัดสินใจได้ว่าต้องการรับข้อมูลในนาทีสุดท้ายที่เป็นไปได้หรือเมื่อข้อมูลนั้นมีความทันท่วงทีมากกว่า
ตัวอย่างเช่น หากมีแอปที่ผู้ใช้มักเปิดแอปไว้ตลอดวันทำงาน คุณอาจต้องการระยะหมดเวลา 1 ชั่วโมงเพื่อให้ระบบวิเคราะห์ได้ละเอียดยิ่งขึ้น ในขณะเดียวกันก็รับประกันบีคอนในกรณีที่ผู้ใช้ออกก่อนเวลานั้นจนถึงเวลานั้น จากนั้นตั้งค่า fetchLater()
ใหม่สําหรับการวิเคราะห์ชั่วโมงถัดไปได้
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
หรือ Flag --enable-features=FetchLaterAPI
ที่มุ่งเน้นมากขึ้น
หากคุณใช้ในหน้าสาธารณะ อย่าลืมใช้ฟีเจอร์โดยตรวจสอบว่ามีการกำหนด fetchLater
ส่วนกลางหรือไม่ก่อนใช้งาน
if (globalThis.fetchLater) {
// Set up beaconing using fetchLater().
// ...
}
ความคิดเห็น
ความคิดเห็นของนักพัฒนาซอฟต์แวร์มีความสำคัญต่อการสร้าง API ของเว็บใหม่ๆ อย่างถูกต้อง ดังนั้นโปรดยื่นปัญหาและความคิดเห็นเกี่ยวกับ GitHub