การลงทะเบียน Service Worker

แนวทางปฏิบัติแนะนำในการกำหนดเวลาการลงทะเบียน Service Worker

Service Worker ช่วยเร่งความเร็วในการเข้าชมเว็บแอปซ้ำได้ แต่คุณควรดำเนินการเพื่อให้การติดตั้ง 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 มีความหมายที่ละเอียดอ่อนไหม มีแนวทางปฏิบัติแนะนำที่ควรทำตามไหม ไม่แปลกใจเลย (เนื่องจากบทความนี้ไม่ได้จบลงตรงนี้) คำตอบสำหรับทั้ง 2 ข้อคือ "ใช่"

การเข้าชมครั้งแรกของผู้ใช้

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

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

ลองจินตนาการว่าในระหว่างการดาวน์โหลด 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');
    });
}

แต่เวลาที่เหมาะสมในการเริ่มการลงทะเบียน Service Worker ยังขึ้นอยู่กับสิ่งที่เว็บแอปของคุณทําทันทีหลังจากโหลด ตัวอย่างเช่น เว็บแอป Google I/O ของปี 2016 มีภาพเคลื่อนไหวสั้นๆ ก่อนเปลี่ยนเป็นหน้าจอหลัก ทีมของเราพบว่าการเริ่มลงทะเบียน Service Worker ระหว่างภาพเคลื่อนไหวอาจทําให้อุปกรณ์เคลื่อนที่ระดับล่างทำงานขัดข้อง เราจึงเลื่อนการลงทะเบียน Service Worker ไว้จนกว่าจะแสดงภาพเคลื่อนไหวเสร็จสิ้น เมื่อเบราว์เซอร์มีแนวโน้มที่จะไม่มีการใช้งานเป็นเวลา 2-3 วินาที

ในทํานองเดียวกัน หากเว็บแอปใช้เฟรมเวิร์กที่ดําเนินการตั้งค่าเพิ่มเติมหลังจากที่หน้าเว็บโหลดแล้ว ให้มองหาเหตุการณ์เฉพาะเฟรมเวิร์กที่จะส่งสัญญาณเมื่อการทำงานเสร็จสิ้น

การเข้าชมครั้งต่อๆ ไป

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

เมื่อลงทะเบียน 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 ตั้งแต่เนิ่นๆ เหมาะสม ตัวอย่างหนึ่งที่นึกออกคือเมื่อ Service Worker ใช้ clients.claim() เพื่อควบคุมหน้าเว็บระหว่างการเข้าชมครั้งแรก และ Service Worker ดำเนินการแคชรันไทม์อย่างหนักหน่วงภายในตัวแฮนเดิล fetch ในกรณีนี้ การเปิดใช้งาน Service Worker ให้ทำงานโดยเร็วที่สุดจะมีประโยชน์ในการพยายามป้อนข้อมูลแคชรันไทม์ด้วยทรัพยากรที่อาจมีประโยชน์ในภายหลัง หากเว็บแอปของคุณจัดอยู่ในหมวดหมู่นี้ คุณควรลองตรวจสอบอีกครั้งว่าตัวแฮนเดิล install ของ Service Worker ไม่ได้ขอทรัพยากรที่แย่งแบนด์วิดท์กับคำขอของหน้าหลัก

การทดสอบ

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

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

การเข้าชมเครือข่ายที่มีการลงทะเบียนล่วงหน้า

ภาพหน้าจอด้านบนแสดงการรับส่งข้อมูลเครือข่ายเมื่อมีการแก้ไขตัวอย่างเพื่อลงทะเบียน Service Worker โดยเร็วที่สุด คุณดูคำขอที่แคชล่วงหน้า (รายการที่มีไอคอนรูปเฟืองอยู่ติดกัน) ที่มาจากเครื่องจัดการ install ของโปรแกรมทำงานของบริการ) ที่สลับกับคำขอสำหรับทรัพยากรอื่นๆ ที่จำเป็นต่อการแสดงหน้าเว็บได้

การจราจรของข้อมูลในเครือข่ายที่มีการลงทะเบียนล่าช้า

ในภาพหน้าจอด้านบน การลงทะเบียนโปรแกรมทำงานของบริการล่าช้าจนกระทั่งหน้าเว็บโหลดขึ้น คุณจะเห็นว่าคำขอแคชล่วงหน้าไม่เริ่มต้นจนกว่าระบบจะดึงทรัพยากรทั้งหมดจากเครือข่าย ซึ่งช่วยขจัดความขัดแย้งของแบนด์วิดท์ นอกจากนี้ เนื่องจากรายการบางส่วนที่เราแคชไว้ล่วงหน้าอยู่ในแคช HTTP ของเบราว์เซอร์อยู่แล้ว (รายการที่มี (from disk cache) ในคอลัมน์ "ขนาด") เราจึงสร้างแคชของ Service Worker ได้โดยไม่ต้องไปที่เครือข่ายอีกครั้ง

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

บทสรุป

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

วิธีง่ายๆ ในการหน่วงเวลาการลงทะเบียนครั้งแรกของ Service Worker จนกว่าจะโหลดหน้าแรกเสร็จแล้วคือใช้สิ่งต่อไปนี้

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
    navigator.serviceWorker.register('/service-worker.js');
    });
}