การปรับปรุงการปิดหน้าเว็บใน XMLHttpRequest() พร้อมกัน

การลดการนําทางที่ล่าช้า

Joe Medley
Joe Medley

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

แนวทางปฏิบัตินี้ต้องเปลี่ยนแปลง และเบราว์เซอร์ก็ตอบสนองต่อการเปลี่ยนแปลงนี้ ข้อกําหนดของ XMLHttpRequest()กําลังอยู่ในกำหนดการเลิกใช้งานและนําออกแล้ว Chrome 80 จะเป็นก้าวแรกด้วยการไม่อนุญาตให้มีการเรียกแบบซิงค์ภายในตัวแฮนเดิลเหตุการณ์หลายรายการ โดยเฉพาะ beforeunload, unload, pagehide และ visibilitychange เมื่อมีการเรียกให้แสดง นอกจากนี้ WebKit ยังมีการคอมมิตที่ติดตั้งใช้งานการเปลี่ยนแปลงลักษณะการทำงานเดียวกันด้วย

บทความนี้จะอธิบายตัวเลือกสำหรับผู้ที่ต้องการเวลาอัปเดตเว็บไซต์และระบุทางเลือกอื่นๆ แทน XMLHttpRequest() โดยสังเขป

เลือกไม่รับชั่วคราว

Chrome ไม่ได้ต้องการปิดใช้ XMLHttpRequest() เพียงอย่างเดียว ด้วยเหตุนี้จึงมีตัวเลือกในการเลือกไม่ใช้ชั่วคราวอยู่ 2-3 รายการ สําหรับเว็บไซต์บนอินเทอร์เน็ต ช่วงทดลองใช้ต้นทางจะพร้อมใช้งาน วิธีนี้ทำให้คุณเพิ่มโทเค็นเฉพาะต้นทางลงในส่วนหัวของหน้าเว็บได้ ซึ่งจะเปิดใช้การเรียก XMLHttpRequest() แบบพร้อมกัน ตัวเลือกนี้จะสิ้นสุดลงก่อนการเปิดตัว Chrome 89 ในช่วงเดือนมีนาคม 2021 ลูกค้า Chrome Enterprise ยังใช้ Flag นโยบาย AllowSyncXHRInPageDismissal ซึ่งสิ้นสุดพร้อมกันได้

ตัวเลือกอื่นๆ

ไม่ว่าคุณจะส่งข้อมูลกลับไปยังเซิร์ฟเวอร์ด้วยวิธีใดก็ตาม คุณควรหลีกเลี่ยงการรอให้หน้าเว็บยกเลิกการโหลดเพื่อส่งข้อมูลทั้งหมดพร้อมกัน นอกจากจะทำให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ไม่ดีแล้ว การยกเลิกการโหลดยังไม่น่าเชื่อถือในเบราว์เซอร์สมัยใหม่และเสี่ยงต่อการสูญเสียข้อมูลหากเกิดข้อผิดพลาด กล่าวโดยละเอียดคือ เหตุการณ์ยกเลิกการโหลดมักไม่ทํางานในเบราว์เซอร์บนอุปกรณ์เคลื่อนที่เนื่องจากมีวิธีปิดแท็บหรือเบราว์เซอร์ในระบบปฏิบัติการบนอุปกรณ์เคลื่อนที่หลายวิธีโดยที่เหตุการณ์ unload จะไม่ทํางาน XMLHttpRequest() ให้คุณเลือกใช้เพย์โหลดขนาดเล็กได้ ตอนนี้เราเป็น ความต้องการ ทางเลือกทั้ง 2 รายการมีขีดจำกัดการอัปโหลด 64 KB ต่อบริบท ตามที่ข้อกำหนดระบุ

ดึงข้อมูล Keepalive

Fetch API มีวิธีการที่มีประสิทธิภาพในการจัดการกับการโต้ตอบกับเซิร์ฟเวอร์และอินเทอร์เฟซที่สอดคล้องกันสําหรับใช้ใน API แพลตฟอร์มต่างๆ ตัวเลือกของ keepalive จะช่วยให้คําขอดําเนินการต่อไปได้ไม่ว่าหน้าเว็บที่ส่งคําขอจะยังคงเปิดอยู่หรือไม่ก็ตาม

window.addEventListener('unload', {
  fetch('/siteAnalytics', {
    method: 'POST',
    body: getStatistics(),
    keepalive: true
  });
}

วิธีการ fetch() มีข้อดีคือควบคุมสิ่งที่ส่งไปยังเซิร์ฟเวอร์ได้มากขึ้น สิ่งที่ไม่ได้แสดงในตัวอย่างคือ fetch() จะแสดงผลเป็น Promise ที่แก้ไขด้วยออบเจ็กต์ Response ด้วย เนื่องจากผมพยายามที่จะหลีกเลี่ยงการยกเลิกการโหลดหน้าเว็บ ผมจึงเลือกที่จะไม่ทำอะไร

SendBeacon()

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

window.addEventListener('unload', {
  navigator.sendBeacon('/siteAnalytics', getStatistics());
}

บทสรุป

เมื่อfetch() พร้อมให้บริการในเบราว์เซอร์ต่างๆ มากขึ้น เราหวังว่าจะนํา XMLHttpRequest() ออกจากแพลตฟอร์มเว็บในเร็วๆ นี้ ผู้ให้บริการเบราว์เซอร์ยอมรับว่าควรนำฟีเจอร์นี้ออก แต่การดำเนินการนี้ต้องใช้เวลา การเลิกใช้งาน Use Case ที่แย่ที่สุดอย่างหนึ่งเป็นขั้นตอนแรกในการปรับปรุงประสบการณ์ของผู้ใช้สำหรับทุกคน

รูปภาพโดย Matthew Hamilton ใน Unsplash