การซิงค์ในเบื้องหลังเป็น Web API ใหม่ที่ให้คุณเลื่อนการดำเนินการจนกว่าผู้ใช้จะมีการเชื่อมต่อที่เสถียร วิธีนี้ช่วยให้มั่นใจได้ว่าผู้ใช้จะส่งสิ่งที่ต้องการได้
ปัญหา
อินเทอร์เน็ตเป็นพื้นที่ที่เหมาะแก่การเสียเวลา หากไม่เสียเวลาไปกับการท่องอินเทอร์เน็ต เราคงไม่รู้เลยว่าแมวไม่ชอบดอกไม้ กิ้งก่าชอบฟองสบู่ หรือว่า Eric Bidelman ของเราเองเป็นฮีโร่กอล์ฟพัตต์พัตต์แห่งยุค 90
แต่บางครั้ง เราไม่อยากเสียเวลา ประสบการณ์ของผู้ใช้ที่ต้องการควรมีลักษณะดังนี้
- โทรศัพท์ไม่ได้อยู่ในกระเป๋า
- บรรลุเป้าหมายรอง
- โทรศัพท์กลับเข้าไปในกระเป๋า
- กลับมาใช้ชีวิตต่อ
แต่การเชื่อมต่อที่ไม่ดีมักทำให้ประสบการณ์นี้ขาดตอน เราต่างก็เคยเจอประสบการณ์แบบเดียวกัน คุณกลอกตามองหน้าจอสีขาวหรือภาพสปินเนอร์อยู่ และรู้ว่าควรเลิกแล้วไปทำงานอย่างอื่นต่อ แต่ก็ยังรออีก 10 วินาทีเผื่อไว้ หลังจากนั้น 10 วินาทีใช่ไหม ไม่มี
แต่ทำไมต้องยอมแพ้ตอนนี้ คุณลงทุนเวลาไปแล้ว การเลิกล้มเลิกไปโดยไม่ได้รับอะไรเลยจึงเป็นเรื่องที่เสียเปล่า คุณจึงรอต่อไป เมื่อถึงจุดนี้ คุณอยากเลิก แต่คุณก็รู้ว่าวินาทีที่คุณเลิกรอคือวินาทีก่อนที่ทุกอย่างจะโหลดเสร็จแล้ว หากเพียงแต่คุณรอ
Service Worker ช่วยแก้ปัญหาการโหลดหน้าเว็บด้วยการให้คุณแสดงเนื้อหาจากแคช แต่จะเกิดอะไรขึ้นเมื่อหน้าเว็บจำเป็นต้องส่งอะไรบางอย่างไปยังเซิร์ฟเวอร์
ปัจจุบัน หากผู้ใช้กด "ส่ง" ในข้อความ ผู้ใช้จะต้องจ้องมองภาพสปินเนอร์จนกว่าภาพจะหยุด หากผู้ใช้พยายามออกจากหน้าเว็บหรือปิดแท็บ เราจะใช้ onbeforeunload
เพื่อแสดงข้อความ เช่น "ไม่ ฉันต้องการให้คุณมองที่ภาพสปินเนอร์นี้อีกสักพัก ขออภัย" หากผู้ใช้ไม่มีการเชื่อมต่อ เราจะแจ้งให้ผู้ใช้ทราบว่า "ขออภัย คุณต้องกลับมาลองใหม่ในภายหลัง"
ข้อมูลนี้ไม่ถูกต้อง การซิงค์ในเบื้องหลังช่วยให้คุณทำงานได้ดีขึ้น
การแก้ปัญหา
วิดีโอต่อไปนี้แสดง Emojoy ซึ่งเป็นการสาธิตแชทที่ใช้อีโมจิเท่านั้น เพราะเป็น Progressive Web App และทำงานแบบออฟไลน์เป็นหลัก แอปใช้ข้อความ Push และการแจ้งเตือน และใช้การซิงค์ในเบื้องหลัง
หากผู้ใช้พยายามส่งข้อความเมื่อไม่มีการเชื่อมต่อ ข้อความจะส่งในเบื้องหลังเมื่อผู้ใช้มีการเชื่อมต่อ
ตั้งแต่เดือนมีนาคม 2016 เป็นต้นไป การซิงค์ในเบื้องหลังพร้อมใช้งานใน Chrome เวอร์ชัน 49 ขึ้นไป คุณดูการดำเนินการได้โดยทำตามขั้นตอนด้านล่าง
- เปิด EmoJo
- ออฟไลน์ (โดยใช้โหมดบนเครื่องบินหรือไปที่กรง Faraday ในพื้นที่)
- พิมพ์ข้อความ
- กลับไปที่หน้าจอหลัก (เลือกปิดแท็บหรือเบราว์เซอร์ก็ได้)
- เชื่อมต่ออินเทอร์เน็ต
- ส่งข้อความในพื้นหลัง
ความสามารถในการส่งในเบื้องหลังเช่นนี้ยังช่วยให้ประสิทธิภาพดีขึ้นด้วย แอปไม่จำเป็นต้องทำเรื่องส่งข้อความให้เป็นเรื่องใหญ่ จึงเพิ่มข้อความไปยังเอาต์พุตได้ทันที
วิธีขอการซิงค์ในเบื้องหลัง
ฟีเจอร์นี้เป็นฟีเจอร์ระดับล่างที่ให้อิสระแก่คุณในการทำสิ่งที่จำเป็นตามสไตล์เว็บที่ขยายได้อย่างแท้จริง คุณขอให้เหตุการณ์เริ่มทำงานเมื่อผู้ใช้มีการเชื่อมต่อ ซึ่งจะมีผลทันทีหากผู้ใช้เชื่อมต่อแล้ว จากนั้นคุณก็คอยฟังเหตุการณ์นั้นและทําสิ่งที่ต้องทำ
เช่นเดียวกับการรับส่งข้อความ Push ฟีเจอร์นี้ใช้ Service Worker เป็นเป้าหมายเหตุการณ์ ซึ่งช่วยให้ทำงานได้เมื่อหน้าเว็บไม่ได้เปิดอยู่ วิธีเริ่มต้นคือลงทะเบียนเพื่อซิงค์จากหน้าเว็บ โดยทำดังนี้
// Register your service worker:
navigator.serviceWorker.register('/sw.js');
// Then later, request a one-off sync:
navigator.serviceWorker.ready.then(function(swRegistration) {
return swRegistration.sync.register('myFirstSync');
});
```
Then listen for the event in `/sw.js`:
```js
self.addEventListener('sync', function(event) {
if (event.tag == 'myFirstSync') {
event.waitUntil(doSomeStuff());
}
});
เพียงเท่านี้ก็เรียบร้อยแล้ว ด้านบน doSomeStuff()
ควรแสดงผลลัพธ์เป็นสัญญาที่บ่งบอกถึงความสำเร็จ/ความล้มเหลวของสิ่งที่พยายามทำ หากดำเนินการเสร็จสิ้น การซิงค์ก็จะเสร็จสมบูรณ์ หากไม่สำเร็จ ระบบจะกำหนดเวลาการซิงค์อีกครั้ง การซิงค์อีกครั้งจะรอการเชื่อมต่อและใช้ Exponential Backoff ด้วย
ชื่อแท็กของการซิงค์ ('myFirstSync' ในตัวอย่างด้านบน) ควรไม่ซ้ำกันสำหรับการซิงค์หนึ่งๆ หากคุณลงทะเบียนการซิงค์โดยใช้แท็กเดียวกับการซิงค์ที่รอดำเนินการ การซิงค์ดังกล่าวจะรวมเข้ากับการซิงค์ที่มีอยู่ ซึ่งหมายความว่าคุณสามารถลงทะเบียนการซิงค์ "ล้างกล่องจดหมาย" ทุกครั้งที่ผู้ใช้ส่งข้อความ แต่หากผู้ใช้ส่งข้อความ 5 รายการขณะออฟไลน์ คุณจะได้รับเฉพาะการซิงค์ครั้งเดียวเมื่อผู้ใช้กลับมาออนไลน์ หากคุณต้องการเหตุการณ์การซิงค์ 5 รายการแยกกัน ให้ใช้แท็กที่ไม่ซ้ำกัน
นี่คือการสาธิตง่ายๆ ที่ไม่ซับซ้อนเลย ซึ่งใช้เหตุการณ์การซิงค์เพื่อแสดงการแจ้งเตือน
ฉันจะใช้การซิงค์ในเบื้องหลังทำอะไรได้บ้าง
คุณควรใช้เพื่อกำหนดเวลาการส่งข้อมูลที่คุณสนใจหลังจากหน้าเว็บหยุดทำงาน ข้อความแชท อีเมล การอัปเดตเอกสาร การเปลี่ยนแปลงการตั้งค่า การอัปโหลดรูปภาพ... ทุกอย่างที่คุณต้องการเข้าถึงเซิร์ฟเวอร์ แม้ว่าผู้ใช้จะไปยังส่วนอื่นหรือปิดแท็บไปแล้วก็ตาม หน้าเว็บอาจจัดเก็บข้อมูลเหล่านี้ไว้ในที่เก็บ "กล่องขาออก" ใน IndexedDB และ Service Worker จะดึงข้อมูลดังกล่าวออกมาและส่ง
แต่คุณก็ใช้เพื่อดึงข้อมูลเล็กๆ น้อยๆ ได้ด้วย...
มาดูตัวอย่างอื่นกัน
นี่คือการสาธิต wikipedia ออฟไลน์ ที่เราสร้างไว้สําหรับการเพิ่มประสิทธิภาพการโหลดหน้าเว็บ เราได้เพิ่มการซิงค์เบื้องหลังเข้าไปแล้ว
ลองใช้ดู ตรวจสอบว่าคุณใช้ Chrome 49 ขึ้นไป จากนั้น
- ไปที่บทความใดก็ได้ เช่น Chrome
- ออฟไลน์ (ใช้โหมดบนเครื่องบินหรือใช้บริการของผู้ให้บริการเครือข่ายมือถือที่แย่อย่างฉัน)
- คลิกลิงก์ไปยังบทความอื่น
- คุณควรได้รับแจ้งว่าโหลดหน้าไม่สำเร็จ (ข้อความนี้จะปรากฏขึ้นหากหน้าเว็บใช้เวลาโหลดสักครู่)
- ยอมรับการแจ้งเตือน
- ปิดเบราว์เซอร์
- ใช้งานแบบออนไลน์
- คุณจะได้รับการแจ้งเตือนเมื่อบทความได้รับการดาวน์โหลด แคช และพร้อมดูแล้ว
เมื่อใช้รูปแบบนี้ ผู้ใช้สามารถเก็บโทรศัพท์ไว้ในกระเป๋าและใช้ชีวิตต่อไปได้ โดยที่รู้ว่าโทรศัพท์จะแจ้งเตือนเมื่อดึงข้อมูลที่ต้องการแล้ว
สิทธิ์
เดโมที่เราแสดงใช้การแจ้งเตือนทางเว็บ ซึ่งจำเป็นต้องมีสิทธิ์ แต่การซิงค์ในเบื้องหลังไม่จําเป็น
เหตุการณ์การซิงค์มักจะเสร็จสมบูรณ์ในขณะที่ผู้ใช้เปิดหน้าเว็บไปยังเว็บไซต์อยู่ ดังนั้นการขอสิทธิ์จากผู้ใช้จะเป็นประสบการณ์ที่ไม่ดี แต่เราจะจำกัดเวลาในการลงทะเบียนและทริกเกอร์การซิงค์เพื่อป้องกันการละเมิด เช่น
- คุณจะลงทะเบียนเหตุการณ์การซิงค์ได้ก็ต่อเมื่อผู้ใช้เปิดหน้าต่างเว็บไซต์อยู่เท่านั้น
- มีการจำกัดเวลาในการดำเนินกิจกรรม คุณจึงไม่สามารถใช้คำสั่ง ping กับเซิร์ฟเวอร์ทุก x วินาที ขุดบิตคอยน์ หรืออะไรก็ตาม
แน่นอนว่าข้อจำกัดเหล่านี้อาจผ่อนปรนหรือเข้มงวดขึ้นตามการใช้งานจริง
การเพิ่มประสิทธิภาพแบบต่อเนื่อง
เบราว์เซอร์ทุกรุ่นอาจใช้เวลาสักพักจึงจะรองรับการซิงค์ในเบื้องหลัง โดยเฉพาะเมื่อ Safari และ Edge ยังไม่รองรับ Service Worker แต่การเพิ่มประสิทธิภาพแบบเป็นขั้นเป็นตอนจะช่วยในเรื่องต่อไปนี้
if ('serviceWorker' in navigator && 'SyncManager' in window) {
navigator.serviceWorker.ready.then(function(reg) {
return reg.sync.register('tag-name');
}).catch(function() {
// system was unable to register for a sync,
// this could be an OS-level restriction
postDataFromThePage();
});
} else {
// serviceworker/sync not supported
postDataFromThePage();
}
หากโปรแกรมทำงานของบริการหรือการซิงค์ในพื้นหลังไม่พร้อมใช้งาน ให้โพสต์เนื้อหาจากหน้าเว็บตามที่คุณทำในวันนี้
คุณควรใช้การซิงค์ในเบื้องหลังแม้ว่าผู้ใช้จะดูเหมือนมีการเชื่อมต่อที่ดีก็ตาม เนื่องจากจะช่วยป้องกันไม่ให้เกิดการไปยังส่วนต่างๆ และการปิดแท็บระหว่างการส่งข้อมูล
อนาคต
เรามุ่งมั่นที่จะจัดส่งการซิงค์ในเบื้องหลังไปยัง Chrome เวอร์ชันเสถียรในช่วงครึ่งแรกของปี 2016 ในขณะที่กำลังพัฒนา "การซิงค์ในเบื้องหลังเป็นระยะๆ" เมื่อใช้การซิงค์ในเบื้องหลังเป็นระยะ คุณจะสามารถขอเหตุการณ์ที่ถูกจำกัดตามช่วงเวลา สถานะแบตเตอรี่ และสถานะเครือข่าย ซึ่งจะต้องได้รับสิทธิ์จากผู้ใช้ และขึ้นอยู่กับเบราว์เซอร์ว่าจะเรียกเหตุการณ์เหล่านี้ให้แสดงเมื่อใดและบ่อยแค่ไหน กล่าวคือ เว็บไซต์ข่าวอาจขอซิงค์ทุกชั่วโมง แต่เบราว์เซอร์อาจทราบว่าคุณอ่านเว็บไซต์นั้นเฉพาะเวลา 07:00 น. ดังนั้นการซิงค์จึงจะเกิดขึ้นทุกวันเวลา 06:50 น. แนวคิดนี้ไม่ใช่แค่การซิงค์เพียงครั้งเดียว แต่ก็กำลังพัฒนาอยู่
เรากำลังนํารูปแบบที่ประสบความสําเร็จจาก Android และ iOS มาสู่เว็บทีละน้อย ในขณะเดียวกันก็ยังคงรักษาสิ่งที่ทําให้เว็บยอดเยี่ยมไว้