ขอแนะนำการดึงข้อมูลในเบื้องหลัง

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

ฟีเจอร์นี้มีประโยชน์ แต่ต้องใช้ Service Worker ที่ทำงานอยู่ตลอดระยะเวลาของ การดึงข้อมูล ซึ่งจะไม่เป็นปัญหาสำหรับงานสั้นๆ เช่น การส่งข้อความ แต่หากงานใช้เวลานานเกินไป เบราว์เซอร์จะปิด Service Worker มิฉะนั้นจะเป็นความเสี่ยงต่อความเป็นส่วนตัวและแบตเตอรี่ของผู้ใช้

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

Background Fetch พร้อมใช้งานโดยค่าเริ่มต้นตั้งแต่ Chrome 74

นี่คือการสาธิตสั้นๆ 2 นาทีที่แสดงสถานะแบบเดิมๆ เทียบกับการใช้การดึงข้อมูลในเบื้องหลัง

วิธีการทำงาน

การดึงข้อมูลในเบื้องหลังจะทำงานดังนี้

  1. คุณบอกเบราว์เซอร์ให้ทำการดึงข้อมูลกลุ่มหนึ่งในเบื้องหลัง
  2. เบราว์เซอร์จะดึงข้อมูลเหล่านั้นและแสดงความคืบหน้าต่อผู้ใช้
  3. เมื่อการดึงข้อมูลเสร็จสมบูรณ์หรือล้มเหลว เบราว์เซอร์จะเปิด Service Worker และทริกเกอร์เหตุการณ์ เพื่อแจ้งให้คุณทราบสิ่งที่เกิดขึ้น ในส่วนนี้ คุณจะตัดสินใจได้ว่าจะทำอย่างไรกับคำตอบ (หากมี)

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

ในบางแพลตฟอร์ม (เช่น Android) เบราว์เซอร์อาจปิดหลังจากขั้นตอนที่ 1 เนื่องจาก เบราว์เซอร์สามารถส่งต่อการดึงข้อมูลไปยังระบบปฏิบัติการได้

หากผู้ใช้เริ่มดาวน์โหลดขณะออฟไลน์หรือออฟไลน์ระหว่างการดาวน์โหลด ระบบจะหยุดการดึงข้อมูลในเบื้องหลังชั่วคราวและดำเนินการต่อในภายหลัง

API

ตรวจหาฟีเจอร์

เช่นเดียวกับฟีเจอร์ใหม่ๆ คุณต้องตรวจหาว่าเบราว์เซอร์รองรับฟีเจอร์นี้หรือไม่ สำหรับการดึงข้อมูลในเบื้องหลัง คุณทำได้ง่ายๆ ดังนี้

if ('BackgroundFetchManager' in self) {
  // This browser supports Background Fetch!
}

การเริ่มดึงข้อมูลในเบื้องหลัง

API หลักจะเชื่อมต่อกับการลงทะเบียน Service Worker ดังนั้นโปรดตรวจสอบว่าคุณได้ลงทะเบียน Service Worker แล้ว จากนั้นให้ทำดังนี้

navigator.serviceWorker.ready.then(async (swReg) => {
  const bgFetch = await swReg.backgroundFetch.fetch('my-fetch', ['/ep-5.mp3', 'ep-5-artwork.jpg'], {
    title: 'Episode 5: Interesting things.',
    icons: [{
      sizes: '300x300',
      src: '/ep-5-icon.png',
      type: 'image/png',
    }],
    downloadTotal: 60 * 1024 * 1024,
  });
});

backgroundFetch.fetch รับอาร์กิวเมนต์ 3 รายการ ได้แก่

พารามิเตอร์
id string
ระบุการดึงข้อมูลในเบื้องหลังนี้อย่างไม่ซ้ำกัน

backgroundFetch.fetch จะปฏิเสธหากรหัสตรงกับ Background fetch ที่มีอยู่

requests Array<Request|string>
สิ่งที่ต้องดึงข้อมูล ระบบจะถือว่าสตริงเป็น URL และเปลี่ยนเป็น Request ผ่าน new Request(theString)

คุณสามารถดึงข้อมูลจากต้นทางอื่นๆ ได้ตราบใดที่ทรัพยากรอนุญาตผ่าน CORS

หมายเหตุ: ขณะนี้ Chrome ยังไม่รองรับคำขอที่ต้องมีการตรวจสอบเบื้องต้นของ CORS

options ออบเจ็กต์ซึ่งอาจรวมถึงข้อมูลต่อไปนี้
options.title string
ชื่อสำหรับเบราว์เซอร์เพื่อแสดงพร้อมกับความคืบหน้า
options.icons Array<IconDefinition>
อาร์เรย์ของออบเจ็กต์ที่มี `src`, `size` และ `type`
options.downloadTotal number
ขนาดทั้งหมดของเนื้อหาการตอบกลับ (หลังจากยกเลิกการบีบอัดด้วย gzip)

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

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

backgroundFetch.fetch จะแสดงผล Promise ที่แก้ไขด้วย BackgroundFetchRegistration ฉันจะ อธิบายรายละเอียดในภายหลัง Promise จะปฏิเสธหากผู้ใช้เลือกไม่ใช้การดาวน์โหลด หรือพารามิเตอร์ที่ระบุอย่างน้อย 1 รายการไม่ถูกต้อง

การระบุคำขอจำนวนมากสำหรับการดึงข้อมูลในเบื้องหลังรายการเดียวช่วยให้คุณรวมรายการต่างๆ ที่เป็นรายการเดียวเชิงตรรกะสำหรับผู้ใช้ได้ เช่น ภาพยนตร์อาจแบ่งออกเป็นแหล่งข้อมูลหลายพันรายการ (โดยทั่วไปจะใช้ MPEG-DASH) และมาพร้อมกับแหล่งข้อมูลเพิ่มเติม เช่น รูปภาพ เลเวลของเกมอาจกระจายอยู่ตามทรัพยากร JavaScript, รูปภาพ และเสียงจำนวนมาก แต่สำหรับผู้ใช้แล้ว มันก็คือ "ภาพยนตร์" หรือ "เลเวล"

การรับการดึงข้อมูลในเบื้องหลังที่มีอยู่

คุณสามารถรับการดึงข้อมูลในเบื้องหลังที่มีอยู่ได้ดังนี้

navigator.serviceWorker.ready.then(async (swReg) => {
  const bgFetch = await swReg.backgroundFetch.get('my-fetch');
});

…โดยส่ง id ของการดึงข้อมูลในเบื้องหลังที่ต้องการ get จะแสดงผล undefined หากไม่มีการดึงข้อมูลในเบื้องหลังที่ใช้งานอยู่ซึ่งมีรหัสดังกล่าว

ระบบจะถือว่าการดึงข้อมูลในเบื้องหลัง "ทำงานอยู่" ตั้งแต่เวลาที่ลงทะเบียนจนกว่าจะสำเร็จ ล้มเหลว หรือถูกยกเลิก

คุณดูรายการการดึงข้อมูลในเบื้องหลังที่ใช้งานอยู่ทั้งหมดได้โดยใช้ getIds

navigator.serviceWorker.ready.then(async (swReg) => {
  const ids = await swReg.backgroundFetch.getIds();
});

การลงทะเบียนการดึงข้อมูลในเบื้องหลัง

BackgroundFetchRegistration (bgFetch ในตัวอย่างด้านบน) มีลักษณะดังนี้

พร็อพเพอร์ตี้
id string
รหัสของการดึงข้อมูลในเบื้องหลัง
uploadTotal number
จำนวนไบต์ที่จะส่งไปยังเซิร์ฟเวอร์
uploaded number
จำนวนไบต์ที่ส่งสำเร็จ
downloadTotal number
ค่าที่ระบุเมื่อลงทะเบียนการดึงข้อมูลในเบื้องหลัง หรือ 0
downloaded number
จำนวนไบต์ที่ได้รับสำเร็จ

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

result

ประเภทใดประเภทหนึ่งต่อไปนี้

  • "" - การดึงข้อมูลในเบื้องหลังทำงานอยู่ จึงยังไม่มีผลลัพธ์
  • "success" - การดึงข้อมูลในเบื้องหลังสำเร็จแล้ว
  • "failure" - การดึงข้อมูลในเบื้องหลังไม่สำเร็จ ค่านี้จะปรากฏก็ต่อเมื่อ การดึงข้อมูลในเบื้องหลังล้มเหลวโดยสิ้นเชิง เช่น เบราว์เซอร์ไม่สามารถลองอีกครั้ง/ดำเนินการต่อได้