แนวทางปฏิบัติแนะนำในการกำหนดเวลาลงทะเบียน Service Worker
โปรแกรมทำงานของบริการ สามารถเร่งการเข้าชมเว็บแอปซ้ำๆ ได้อย่างมาก แต่คุณควรทำตามขั้นตอนเพื่อให้มั่นใจว่าการติดตั้งเริ่มต้นของโปรแกรมทำงานของบริการจะไม่ทำให้ประสบการณ์การเข้าชมครั้งแรกของผู้ใช้แย่ลง
โดยทั่วไปแล้วการเลื่อน Service Worker การลงทะเบียนไปจนกว่าหน้าเริ่มต้นจะโหลดขึ้นมาจะทำให้ผู้ใช้ได้รับประสบการณ์ที่ดีที่สุด โดยเฉพาะอย่างยิ่งผู้ที่ใช้อุปกรณ์เคลื่อนที่ที่มีการเชื่อมต่อเครือข่ายช้ากว่า
ต้นแบบการจดทะเบียนทั่วไป
หากคุณเคยอ่านข้อมูลเกี่ยวกับ Service Worker มา คุณน่าจะได้พบต้นแบบที่คล้ายกับตัวอย่างต่อไปนี้
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js');
}
บางครั้งมาพร้อมกับคำสั่ง console.log()
2-3 รายการ หรือโค้ดที่ตรวจพบการอัปเดตการลงทะเบียน Service Worker ก่อนหน้าเพื่อแจ้งให้ผู้ใช้รีเฟรชหน้า แต่นั่นเป็นแค่รูปแบบเล็กๆ
ในโค้ดมาตรฐานเพียงไม่กี่บรรทัด
navigator.serviceWorker.register
มีความแตกต่างเล็กๆ น้อยๆ หรือไม่ มีแนวทางปฏิบัติแนะนำ
ที่ควรทำตามไหม ไม่น่าแปลกใจ (หากบทความนี้ไม่จบที่นี่) คำตอบของทั้งสองคำตอบคือ "ใช่"
การเข้าชมครั้งแรกของผู้ใช้
ลองพิจารณาการเข้าชมเว็บแอปครั้งแรกของผู้ใช้ ยังไม่มีโปรแกรมทำงานของบริการ และเบราว์เซอร์ไม่มีทางทราบล่วงหน้าว่าจะมีโปรแกรมทำงานของบริการที่ติดตั้งในที่สุดหรือไม่
ในฐานะนักพัฒนาซอฟต์แวร์ สิ่งที่คุณให้ความสำคัญสูงสุดคือตรวจสอบว่าเบราว์เซอร์ได้รับชุดทรัพยากรที่สำคัญน้อยที่สุดที่จำเป็นในการแสดงหน้าเว็บแบบอินเทอร์แอกทีฟได้อย่างรวดเร็ว สิ่งที่ทำให้คำตอบเหล่านั้นช้าลงคืออุปสรรคของประสบการณ์การโต้ตอบแบบรวดเร็ว
ทีนี้ลองนึกภาพว่าในขั้นตอนการดาวน์โหลด JavaScript หรือรูปภาพที่หน้าเว็บต้องแสดงผล เบราว์เซอร์จะตัดสินใจเริ่มเทรดหรือการประมวลผลในเบื้องหลัง (เพื่อความกระชับ เราจะสมมติว่าเป็นชุดข้อความ) ให้สมมติว่าคุณไม่ได้ใช้เครื่องเดสก์ท็อปที่หนักหน่วง แต่เป็นโทรศัพท์มือถือที่มีพลังงานน้อยในระดับที่คนทั่วโลกมักมองว่าเป็นอุปกรณ์หลัก การรวมเทรดเพิ่มเติมนี้จะเพิ่มการช่วงชิงเวลา CPU และหน่วยความจำที่เบราว์เซอร์อาจใช้ในการแสดงผลหน้าเว็บแบบอินเทอร์แอกทีฟ
ชุดข้อความในเบื้องหลังที่ไม่มีการใช้งานไม่น่าจะสร้างความแตกต่างได้มากนัก แต่จะเกิดอะไรขึ้นหากเทรดนั้นไม่ได้ใช้งานแต่ตัดสินใจว่าจะเริ่มดาวน์โหลดทรัพยากรจากเครือข่ายด้วย ความกังวลเกี่ยวกับการช่วงชิง CPU หรือหน่วยความจำ ควรมานั่งกังวลเรื่องแบนด์วิดท์ที่มีจำกัดซึ่งใช้ได้กับอุปกรณ์เคลื่อนที่จำนวนมาก แบนด์วิดท์มีค่ามาก ดังนั้นอย่าทำลายทรัพยากรที่สำคัญโดยการดาวน์โหลดทรัพยากรรองพร้อมกัน
ทั้งหมดนี้คือการสร้างเทรด Service Worker ใหม่เพื่อดาวน์โหลดและแคชทรัพยากรในเบื้องหลังจะได้ผลตามเป้าหมายในการมอบประสบการณ์การใช้งานแบบอินเทอร์แอกทีฟที่สั้นที่สุดเมื่อผู้ใช้เข้าชมเว็บไซต์ครั้งแรก
การปรับปรุงต้นแบบ
วิธีแก้ไขคือการควบคุมการเริ่มต้นของโปรแกรมทำงานของบริการโดยเลือกเวลาที่จะเรียกใช้ navigator.serviceWorker.register()
หลักการง่ายๆ คือให้เลื่อนการลงทะเบียนออกไปจนกว่า load
event
จะเริ่มทำงานในวันที่ window
ดังนี้
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/service-worker.js');
});
}
แต่เวลาที่เหมาะสมในการเริ่มต้นการลงทะเบียนโปรแกรมทำงานของบริการยังขึ้นอยู่กับสิ่งที่เว็บแอปทำหลังจากที่โหลดขึ้นมาแล้ว ตัวอย่างเช่น เว็บแอป Google I/O 2016 จะแสดงภาพเคลื่อนไหวสั้นๆ ก่อนที่จะเปลี่ยนไปเป็นหน้าจอหลัก ทีมของเราพบว่าการเริ่มต้นการลงทะเบียน Service Worker ระหว่างการสร้างภาพเคลื่อนไหวอาจทำให้เกิดความไม่ราบรื่นในอุปกรณ์เคลื่อนที่ระดับไฮเอนด์ แทนที่จะมอบประสบการณ์ที่ไม่ดีแก่ผู้ใช้ เราชะลอการลงทะเบียนโปรแกรมทำงานของบริการไว้จนกระทั่งหลังภาพเคลื่อนไหวเป็นช่วงที่เบราว์เซอร์มีแนวโน้มมากที่สุดที่ไม่มีการใช้งานเป็นเวลา 2-3 วินาที
ในทำนองเดียวกัน หากเว็บแอปใช้เฟรมเวิร์กที่ทำการตั้งค่าเพิ่มเติมหลังจากหน้าเว็บโหลดแล้ว ให้มองหาเหตุการณ์เฉพาะเฟรมเวิร์กที่ส่งสัญญาณว่าเสร็จแล้ว
การเข้าชมที่ตามมา
เรามุ่งเน้นที่ประสบการณ์การเข้าชมครั้งแรกมาโดยตลอด แต่จะมีผลอย่างไรต่อการลงทะเบียนผู้ปฏิบัติงานบริการที่ล่าช้าต่อการเข้าชมเว็บไซต์ของคุณซ้ำ แม้ว่าบางคนอาจตกใจ แต่ก็ไม่น่าจะสร้างผลกระทบใดๆ ได้เลย
เมื่อลงทะเบียน Service Worker แล้ว ระบบจะดำเนินการผ่านเหตุการณ์ในวงจร install
และ activate
เมื่อเปิดใช้งาน Service Worker แล้ว จะสามารถจัดการเหตุการณ์ fetch
สำหรับการเข้าชมเว็บแอปของคุณครั้งต่อๆ ไปได้ โดย Service Worker จะเริ่มต้นก่อนจะมีการส่งคำขอหน้าเว็บใดก็ตามที่อยู่ภายใต้ขอบเขตของโปรแกรม ซึ่งเหมาะสมเมื่อคุณคิดเกี่ยวกับเรื่องนี้ หาก Service Worker ที่มีอยู่ยังไม่ได้ทำงานก่อนเข้าชมหน้าเว็บ ก็จะไม่มีโอกาสดำเนินการตามเหตุการณ์ fetch
สำหรับคำขอการนำทาง
ดังนั้นเมื่อมี Service Worker ที่มีสถานะทำงานอยู่แล้ว คุณจะโทรหา navigator.serviceWorker.register()
หรือไม่ก็ได้ หรืออันที่จริงก็ไม่ว่าคุณจะโทรหา หรือไม่ก็ตาม
ในกรณีที่คุณเปลี่ยน URL ของสคริปต์ Service Worker จะทำให้ navigator.serviceWorker.register()
เป็นไม่มีการดำเนินการอย่างมีประสิทธิภาพในระหว่างการเข้าชมครั้งต่อๆ ไป การโทรไม่เกี่ยวข้อง
เหตุผลที่ควรลงทะเบียนล่วงหน้า
มีสถานการณ์ใดบ้างที่การลงทะเบียน Service Worker โดยเร็วที่สุดเท่าที่จะเป็นไปได้ สิ่งหนึ่งที่ควรคำนึงถึงคือเมื่อโปรแกรมทำงานของบริการใช้ clients.claim()
เพื่อควบคุมหน้าเว็บในระหว่างการเข้าชมครั้งแรก และ Service Worker ดำเนินการแคชรันไทม์อย่างจริงจังภายในตัวแฮนเดิล fetch
ในสถานการณ์เช่นนี้ มีข้อได้เปรียบคือการทำให้ Service Worker ทำงานโดยเร็วที่สุดโดยพยายามสร้างแคชรันไทม์ด้วยทรัพยากรที่อาจมีประโยชน์ในภายหลัง หากเว็บแอปอยู่ในหมวดหมู่นี้ คุณควรลองย้อนกลับไปดูเพื่อให้แน่ใจว่าเครื่องจัดการ install
ของ Service Worker ไม่ได้ขอทรัพยากรที่ต่อสู้เพื่อแบนด์วิดท์กับคำขอของหน้าเว็บหลัก
ทดสอบสิ่งต่างๆ
วิธีที่ดีในการจำลองการเข้าชมครั้งแรกคือการเปิดเว็บแอปในหน้าต่างที่ไม่ระบุตัวตนของ Chrome และดูการจราจรของข้อมูลในเครือข่ายในเครื่องมือสำหรับนักพัฒนาเว็บของ Chrome ในฐานะนักพัฒนาเว็บ คุณอาจโหลดอินสแตนซ์ในเครื่องของเว็บแอปซ้ำหลายสิบครั้งต่อวัน แต่การกลับมาที่เว็บไซต์ของคุณอีกครั้งเมื่อมี Service Worker และมีแคชที่สร้างข้อมูลครบถ้วนแล้ว คุณจะไม่ได้รับประสบการณ์การใช้งานเหมือนกับที่ผู้ใช้ใหม่จะได้รับ และคุณก็ไม่ต้องสนใจปัญหาที่อาจเกิดขึ้นได้ง่ายๆ
นี่เป็นตัวอย่างที่แสดงความแตกต่างของเวลาการจดทะเบียน ภาพหน้าจอทั้ง 2 ภาพจะถ่ายขณะไปที่ตัวอย่างแอปในโหมดไม่ระบุตัวตนโดยใช้การควบคุมเครือข่ายเพื่อจำลองการเชื่อมต่อที่ช้า
![การจราจรของข้อมูลในเครือข่ายด้วยการลงทะเบียนล่วงหน้า](https://web.developers.google.cn/static/articles/service-workers-registration/image/network-traffic-early-re-63d00e80875ce.png?authuser=5&hl=th)
ภาพหน้าจอด้านบนแสดงการจราจรของข้อมูลในเครือข่ายเมื่อมีการแก้ไขตัวอย่างเพื่อดำเนินการลงทะเบียน Service Worker โดยเร็วที่สุด คุณจะเห็นคำขอการแคชล่วงหน้า (รายการที่มีไอคอนรูปเฟืองอยู่ข้างๆ คำขอ ซึ่งมาจากตัวแฮนเดิล install
ของโปรแกรมทำงานของบริการ) แทรกกับคำขอทรัพยากรอื่นๆ ที่จำเป็นต่อการแสดงหน้าเว็บ
![การจราจรของข้อมูลในเครือข่ายที่มีการลงทะเบียนล่าช้า](https://web.developers.google.cn/static/articles/service-workers-registration/image/network-traffic-late-reg-17e31ea5d01ab.png?authuser=5&hl=th)
ในภาพหน้าจอด้านบน การลงทะเบียน Service Worker ล่าช้าจนกระทั่งโหลดหน้าเว็บขึ้นมา คุณจะเห็นว่าคำขอการแคชล่วงหน้าจะไม่เริ่มต้นจนกว่าจะมีการดึงทรัพยากรทั้งหมดจากเครือข่าย ซึ่งทำให้เกิดการช่วงชิงแบนด์วิดท์ได้ นอกจากนี้ เนื่องจากรายการบางส่วนที่เราแคชล่วงหน้าอยู่ในแคช HTTP ของเบราว์เซอร์แล้ว ซึ่งก็คือรายการที่มี (from disk cache)
ในคอลัมน์ขนาด เราจึงเติมแคชของโปรแกรมทำงานของบริการได้โดยไม่ต้องไปที่เครือข่ายอีกครั้ง
สิ่งที่จะได้รับโบนัสถ้าคุณทำการทดสอบประเภทนี้จากอุปกรณ์ระดับล่างสุดบน เครือข่ายมือถือจริง คุณสามารถใช้ประโยชน์จากความสามารถในการแก้ไขข้อบกพร่องระยะไกลของ Chrome เพื่อต่อเชื่อมโทรศัพท์ Android กับเครื่องเดสก์ท็อปผ่าน USB และดูแลให้การทดสอบที่คุณกำลังทำแสดงถึงประสบการณ์จริงของผู้ใช้จำนวนมาก
บทสรุป
กล่าวโดยสรุปคือ การตรวจสอบว่าผู้ใช้ได้รับประสบการณ์การเข้าชมครั้งแรกที่ดีที่สุดคือสิ่งที่สำคัญที่สุด การชะลอการลงทะเบียน Service Worker ไปจนกระทั่งหน้าโหลดเสร็จในระหว่างการเข้าชมครั้งแรกสามารถช่วยรับประกันได้ คุณจะยังคงได้ประโยชน์จากการมีโปรแกรมทำงานของบริการสำหรับการเข้าชมซ้ำ
วิธีง่ายๆ ในการชะลอการลงทะเบียนครั้งแรกของ Service Worker จนกว่าจะโหลดหน้าแรกขึ้นคือการใช้โค้ดต่อไปนี้
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/service-worker.js');
});
}