การบันทึกกิจกรรมด้วย Web Beacon API
เผยแพร่แล้ว: 2022-03-10 Beacon API คือ Web API ที่ใช้ JavaScript สำหรับการส่งข้อมูลจำนวนเล็กน้อยจากเบราว์เซอร์ไปยังเว็บเซิร์ฟเวอร์โดยไม่ต้องรอการตอบกลับ ในบทความนี้ เราจะมาดูว่าสิ่งใดมีประโยชน์บ้าง สิ่งที่ทำให้แตกต่างจากเทคนิคที่คุ้นเคย เช่น XMLHTTPRequest
('Ajax') และวิธีเริ่มต้นใช้งาน
หากคุณรู้ว่าเหตุใดคุณจึงต้องการใช้ Beacon อยู่แล้ว ให้ข้ามไปที่ส่วนเริ่มต้นใช้งานโดยตรงได้เลย
Beacon API มีไว้เพื่ออะไร?
Beacon API ใช้สำหรับส่งข้อมูลจำนวนเล็กน้อยไปยังเซิร์ฟเวอร์ โดยไม่ต้องรอการตอบกลับ ส่วนสุดท้ายนั้นสำคัญมากและเป็นกุญแจสำคัญว่าทำไม Beacon จึงมีประโยชน์มาก — โค้ดของเราไม่เคยเห็นการตอบกลับเลย แม้ว่าเซิร์ฟเวอร์จะส่งมาก็ตาม บีคอนใช้สำหรับส่งข้อมูลโดยเฉพาะแล้วลืมไป เราไม่คาดหวังการตอบสนองและเราไม่ได้รับการตอบกลับ
คิดว่ามันเหมือนกับโปสการ์ดที่ส่งถึงบ้านเมื่อไปเที่ยวพักผ่อน คุณใส่ข้อมูลจำนวนเล็กน้อยลงไป (เช่น "หวังว่าคุณจะอยู่ที่นี่" และ "อากาศดีมาก") วางไว้ในกล่องจดหมาย และคุณจะไม่คาดหวังว่าจะได้รับคำตอบ ไม่มีใครส่งไปรษณียบัตรคืนว่า “ใช่ ฉันหวังว่าจะได้ไปที่นั่นจริงๆ ขอบคุณมาก!”
สำหรับเว็บไซต์และแอปพลิเคชันสมัยใหม่ มีกรณีการใช้งานจำนวนหนึ่งที่จัดอยู่ในรูปแบบการส่งและลืมนี้อย่างละเอียดถี่ถ้วน
สถิติการติดตามและข้อมูลการวิเคราะห์
กรณีการใช้งานครั้งแรกที่คนส่วนใหญ่นึกถึงคือการวิเคราะห์ โซลูชันขนาดใหญ่อย่าง Google Analytics อาจให้ภาพรวมที่ดีของสิ่งต่างๆ เช่น การเข้าชมหน้าเว็บ แต่ถ้าเราต้องการปรับแต่งอะไรมากกว่านี้ล่ะ เราสามารถเขียน JavaScript เพื่อติดตามสิ่งที่เกิดขึ้นในหน้า (อาจเป็นวิธีที่ผู้ใช้โต้ตอบกับส่วนประกอบ เลื่อนดูไปไกลแค่ไหน หรือบทความใดแสดงก่อนที่จะทำตาม CTA) แต่เราจำเป็นต้องส่งข้อมูลนั้น ไปยังเซิร์ฟเวอร์เมื่อผู้ใช้ออกจากเพจ บีคอนเหมาะอย่างยิ่งสำหรับสิ่งนี้ เนื่องจากเราเพียงแค่บันทึกข้อมูลและไม่ต้องการคำตอบ
ไม่มีเหตุผลใดที่เราไม่สามารถครอบคลุมงานทั่วไปที่ Google Analytics จัดการได้ รายงานเกี่ยวกับตัวผู้ใช้เองและความสามารถของอุปกรณ์และเบราว์เซอร์ของพวกเขา หากผู้ใช้มีเซสชันที่เข้าสู่ระบบ คุณยังสามารถผูกสถิติเหล่านั้นกับบุคคลที่รู้จักได้ ไม่ว่าคุณจะรวบรวมข้อมูลใด คุณสามารถส่งข้อมูลนั้นกลับไปยังเซิร์ฟเวอร์ด้วย Beacon
การดีบักและการบันทึก
แอปพลิเคชั่นที่มีประโยชน์อีกตัวหนึ่งสำหรับพฤติกรรมนี้คือการบันทึกข้อมูลจากโค้ด JavaScript ของคุณ ลองนึกภาพว่าคุณมีองค์ประกอบเชิงโต้ตอบที่ซับซ้อนบนหน้าเว็บซึ่งทำงานได้ดีกับการทดสอบทั้งหมดของคุณ แต่บางครั้งก็ล้มเหลวในการผลิต คุณรู้ว่ามันล้มเหลว แต่คุณไม่เห็นข้อผิดพลาดเพื่อเริ่มการดีบัก หากคุณตรวจพบความล้มเหลวในโค้ดเอง คุณสามารถรวบรวมการวินิจฉัยและใช้ Beacon เพื่อส่งกลับทั้งหมดสำหรับการบันทึก
อันที่จริง งานบันทึกใดๆ ก็ตามที่สามารถดำเนินการได้อย่างมีประโยชน์โดยใช้ Beacon ไม่ว่าจะเป็นการสร้างจุดบันทึกในเกม การรวบรวมข้อมูลเกี่ยวกับการใช้คุณสมบัติ หรือการบันทึกผลลัพธ์จากการทดสอบหลายตัวแปร หากเป็นสิ่งที่เกิดขึ้นในเบราว์เซอร์ที่คุณต้องการให้เซิร์ฟเวอร์รู้ Beacon น่าจะเป็นคู่แข่ง
เราทำสิ่งนี้ไม่ได้แล้วหรือ
ฉันรู้ว่าคุณกำลังคิดอะไรอยู่ สิ่งนี้ไม่ใหม่ใช่ไหม เราสามารถสื่อสารจากเบราว์เซอร์ไปยังเซิร์ฟเวอร์โดยใช้ XMLHTTPRequest
มานานกว่าทศวรรษ เมื่อไม่นานมานี้ เรายังมี Fetch API ซึ่งทำสิ่งเดียวกันกับอินเทอร์เฟซตามสัญญาที่ทันสมัยกว่า เหตุใดเราจึงต้องการ Beacon API เลย
สิ่งสำคัญในที่นี้คือ เนื่องจากเราไม่ได้รับการตอบกลับ เบราว์เซอร์จึงสามารถจัดคิวคำขอและส่งได้ โดยไม่ต้องบล็อกการเรียก ใช้โค้ดอื่นๆ เท่าที่เบราว์เซอร์มีความกังวล ไม่สำคัญว่าโค้ดของเราจะยังทำงานอยู่หรือไม่ หรือต้องเรียกใช้สคริปต์ที่ใด เนื่องจากไม่มีอะไรจะส่งคืน มันทำได้แค่เบื้องหลังการส่งคำขอ HTTP จนกว่าจะสะดวก ส่ง.
นั่นอาจหมายถึงการรอจนกว่าโหลด CPU จะลดลงหรือจนกว่าเครือข่ายจะว่าง หรือแม้แต่ส่งทันทีหากทำได้ สิ่งสำคัญคือเบราว์เซอร์จะจัดคิวบีคอนและส่งคืนการควบคุมทันที มันไม่ถือสิ่งต่าง ๆ ในขณะที่สัญญาณส่ง
เพื่อให้เข้าใจว่าเหตุใดจึงเป็นเรื่องใหญ่ เราต้องดูว่าคำขอประเภทนี้จะออกมาจากโค้ดของเราอย่างไรและเมื่อใด นำตัวอย่างสคริปต์การบันทึกการวิเคราะห์ของเรา รหัสของเราอาจกำหนดระยะเวลาที่ผู้ใช้ใช้บนหน้าเว็บ ดังนั้นจึงเป็นเรื่องสำคัญที่ข้อมูลจะถูกส่งกลับไปยังเซิร์ฟเวอร์ในช่วงเวลาสุดท้ายที่เป็นไปได้ เมื่อผู้ใช้ออกจากหน้า เราต้องการหยุดเวลาและส่งข้อมูลกลับบ้าน
โดยทั่วไป คุณจะใช้เหตุการณ์ unload
หรือ beforeunload
เพื่อดำเนินการบันทึก สิ่งเหล่านี้จะถูกไล่ออกเมื่อผู้ใช้ดำเนินการบางอย่าง เช่น การติดตามลิงก์บนหน้าเพื่อนำทางออกไป ปัญหาคือโค้ดที่ทำงานอยู่ในเหตุการณ์ unload
การโหลดรายการใดรายการหนึ่งสามารถบล็อกการดำเนินการและทำให้การโหลดหน้าเว็บล่าช้า หากการยกเลิกการโหลดหน้าล่าช้า การโหลดหน้าถัดไปก็ล่าช้าเช่นกัน ดังนั้นประสบการณ์การใช้งานจึงเป็นไปอย่างเชื่องช้า
โปรดทราบว่าคำขอ HTTP นั้นช้าเพียงใด หากคุณกำลังคิดเกี่ยวกับประสิทธิภาพ โดยทั่วไปแล้วหนึ่งในปัจจัยหลักที่คุณพยายามลดคือคำขอ HTTP เพิ่มเติม เนื่องจากการออกไปยังเครือข่ายและรับการตอบสนองอาจช้ามาก สิ่งสุดท้ายที่คุณต้องการทำคือทำให้ความช้าระหว่างการเปิดใช้งานลิงก์และการเริ่มต้นคำขอสำหรับหน้าถัดไป
Beacon แก้ไขปัญหานี้โดยจัดคิวคำขอโดยไม่บล็อก ส่งคืนการควบคุมกลับไปที่สคริปต์ของคุณทันที เบราว์เซอร์จะดูแลส่งคำขอนั้นในพื้นหลังโดยไม่ปิดกั้น สิ่งนี้ทำให้ทุกอย่างเร็วขึ้นมาก ซึ่งทำให้ผู้ใช้มีความสุขมากขึ้นและช่วยให้เราทุกคนรักษางานของเราไว้ได้
เริ่มต้น
ดังนั้น เราจึงเข้าใจว่า Beacon คืออะไร และเหตุใดเราจึงอาจใช้ Beacon ดังนั้นมาเริ่มใช้โค้ดกันก่อน พื้นฐานไม่สามารถง่ายกว่านี้:
let result = navigator.sendBeacon(url, data);
ผลลัพธ์คือบูลีน true
หากเบราว์เซอร์ยอมรับและจัดคิวคำขอ และ false
หากมีปัญหาในการทำเช่นนั้น
ใช้ navigator.sendBeacon()
navigator.sendBeacon
รับพารามิเตอร์สองตัว อันดับแรกคือ URL ที่จะทำการร้องขอ คำขอจะดำเนินการเป็น HTTP POST โดยส่งข้อมูลใดๆ ที่ระบุในพารามิเตอร์ที่สอง
พารามิเตอร์ข้อมูลสามารถอยู่ในรูปแบบใดรูปแบบหนึ่งจากหลายรูปแบบ ทั้งหมดหากนำมาจาก Fetch API โดยตรง ซึ่งอาจเป็น Blob
, a BufferSource
, FormData
หรือ URLSearchParams
— โดยทั่วไปแล้วจะเป็นประเภทเนื้อหาใดๆ ที่ใช้เมื่อทำการร้องขอด้วย Fetch
ฉันชอบใช้ FormData
สำหรับข้อมูลคีย์-ค่าพื้นฐาน เนื่องจากไม่ซับซ้อนและอ่านง่าย
// URL to send the data to let url = '/api/my-endpoint'; // Create a new FormData and add a key/value pair let data = new FormData(); data.append('hello', 'world'); let result = navigator.sendBeacon(url, data); if (result) { console.log('Successfully queued!'); } else { console.log('Failure.'); }
รองรับเบราว์เซอร์
การสนับสนุนในเบราว์เซอร์สำหรับ Beacon นั้นดีมาก โดยมีข้อยกเว้นที่โดดเด่นเพียงอย่างเดียวคือ Internet Explorer (ใช้งานได้ใน Edge) และ Opera Mini สำหรับการใช้งานส่วนใหญ่ ก็น่าจะใช้ได้ แต่ควรทดสอบการสนับสนุนก่อนที่จะลองใช้ navigator.sendBeacon
ทำได้ง่าย:
if (navigator.sendBeacon) { // Beacon code } else { // No Beacon. Maybe fall back to XHR? }
หากไม่มี Beacon และคำขอของคุณมีความสำคัญ คุณสามารถย้อนกลับไปใช้วิธีการบล็อก เช่น XHR คุณอาจเลือกที่จะไม่รบกวนทั้งนี้ขึ้นอยู่กับผู้ชมและวัตถุประสงค์ของคุณ
ตัวอย่าง: การบันทึกเวลาบนเพจ
ในการดูสิ่งนี้ในทางปฏิบัติ เรามาสร้างระบบพื้นฐานเพื่อจับเวลาว่าผู้ใช้อยู่บนเพจนานแค่ไหน เมื่อหน้าโหลด เราจะบันทึกเวลา และเมื่อผู้ใช้ออกจากหน้า เราจะส่งเวลาเริ่มต้นและเวลาปัจจุบันไปยังเซิร์ฟเวอร์
เนื่องจากเราสนใจเฉพาะเวลาที่ใช้ไป (ไม่ใช่เวลาจริงของวัน) เราจึงสามารถใช้ performance.now()
เพื่อรับการประทับเวลาพื้นฐานเมื่อหน้าเว็บโหลด:
let startTime = performance.now();
หากเราสรุปการเข้าสู่ระบบฟังก์ชั่น เราสามารถเรียกมันว่าเมื่อหน้ายกเลิกการโหลด
let logVisit = function() { // Test that we have support if (!navigator.sendBeacon) return true; // URL to send the data to, eg let url = '/api/log-visit'; // Data to send let data = new FormData(); data.append('start', startTime); data.append('end', performance.now()); data.append('url', document.URL); // Let's go! navigator.sendBeacon(url, data); };
สุดท้ายนี้ เราต้องเรียกใช้ฟังก์ชันนี้เมื่อผู้ใช้ออกจากเพจ สัญชาตญาณแรกของฉันคือใช้เหตุการณ์ unload
การโหลด แต่ Safari บน Mac ดูเหมือนจะบล็อกคำขอด้วยคำเตือนด้านความปลอดภัย ดังนั้น beforeunload
จึงทำงานได้ดีสำหรับเราที่นี่
window.addEventListener('beforeunload', logVisit);
เมื่อหน้ายกเลิกการโหลด (หรือก่อนหน้านั้น) logVisit()
ของเราจะถูกเรียกใช้และให้เบราว์เซอร์สนับสนุน Beacon API บีคอนของเราจะถูกส่งไป
(โปรดทราบว่าหากไม่มีการสนับสนุน Beacon เราจะคืนค่า true
และแสร้งทำเป็นว่ามันทำงานได้ดี การคืนค่า false
จะเป็นการยกเลิกกิจกรรมและหยุดการยกเลิกการโหลดหน้า ซึ่งน่าเสียดาย)
ข้อควรพิจารณาในการติดตาม
เนื่องจากการใช้งาน Beacon ที่เป็นไปได้มากมายนั้นเกี่ยวข้องกับการติดตามกิจกรรม ฉันคิดว่าไม่ควรพูดถึงความรับผิดชอบทางสังคมและทางกฎหมายที่เรามีในฐานะนักพัฒนาในการบันทึกและติดตามกิจกรรมที่อาจเชื่อมโยงกับผู้ใช้
GDPR
เราอาจนึกถึงกฎหมาย GDPR ของยุโรปล่าสุดที่เกี่ยวข้องกับอีเมล แต่แน่นอนว่ากฎหมายเกี่ยวข้องกับการจัดเก็บข้อมูลส่วนบุคคลทุกประเภท หากคุณรู้ว่าผู้ใช้ของคุณเป็นใครและสามารถระบุเซสชันของพวกเขาได้ คุณควรตรวจสอบกิจกรรมที่คุณกำลังบันทึกและความเกี่ยวข้องกับนโยบายที่ระบุไว้ของคุณอย่างไร
บ่อยครั้งเราไม่จำเป็นต้องติดตามข้อมูลมากเท่าที่สัญชาตญาณของเราตามที่นักพัฒนาบอกเราว่าควรทำ จะดีกว่าถ้าจงใจ ไม่ เก็บข้อมูลที่ระบุตัวผู้ใช้ และจากนั้นคุณลดโอกาสที่คุณจะทำผิด
DNT: ห้ามติดตาม
นอกเหนือจากข้อกำหนดทางกฎหมาย เบราว์เซอร์ส่วนใหญ่มีการตั้งค่าเพื่อให้ผู้ใช้สามารถแสดงความปรารถนาที่จะไม่ถูกติดตาม Do Not Track ส่งส่วนหัว HTTP พร้อมคำขอที่มีลักษณะดังนี้:
DNT: 1
หากคุณกำลังบันทึกข้อมูลที่สามารถติดตามผู้ใช้รายใดรายหนึ่งและผู้ใช้ส่งส่วนหัว DNT
ที่เป็นบวก จะเป็นการดีที่สุดที่จะปฏิบัติตามความต้องการของผู้ใช้และทำให้ข้อมูลนั้นไม่เปิดเผยตัวตนหรือไม่ติดตามเลย
ตัวอย่างเช่น ใน PHP คุณสามารถทดสอบส่วนหัวนี้ได้ง่ายมาก เช่น:
if (!empty($_SERVER['HTTP_DNT'])) { // User does not wish to be tracked ... }
สรุปแล้ว
Beacon API เป็นวิธีที่มีประโยชน์มากในการส่งข้อมูลจากเพจกลับไปยังเซิร์ฟเวอร์ โดยเฉพาะอย่างยิ่งในบริบทการบันทึก การสนับสนุนเบราว์เซอร์นั้นกว้างมากและช่วยให้คุณบันทึกข้อมูลได้อย่างราบรื่นโดยไม่ส่งผลกระทบในทางลบต่อประสบการณ์การท่องเว็บของผู้ใช้และประสิทธิภาพของเว็บไซต์ของคุณ ลักษณะการไม่บล็อกของคำขอหมายความว่าประสิทธิภาพเร็วกว่าทางเลือกอื่น เช่น XHR และ Fetch
หากคุณต้องการอ่านเพิ่มเติมเกี่ยวกับ Beacon API ไซต์ต่อไปนี้ควรค่าแก่การดู
- “ข้อกำหนด W3C Beacon” คำแนะนำสำหรับผู้สมัคร W3C
- “เอกสาร MDN Beacon,” เอกสารเว็บ MDN, Mozilla
- “ข้อมูลสนับสนุนเบราว์เซอร์” caniuse.com