การลงทะเบียน 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 และเบราว์เซอร์ไม่มีทางรู้ล่วงหน้าว่าจะมีการติดตั้ง Service Worker หรือไม่

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

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

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

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

การปรับปรุงข้อความเทมเพลตที่ต้องใช้บ่อยๆ

ทางออกคือการควบคุมการเริ่มต้น 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 ที่มีอยู่ไม่ได้ทํางานก่อนการไปที่หน้าเว็บ 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 ของ Service Worker) แทรกอยู่ท่ามกลางคำขอทรัพยากรอื่นๆ ที่จําเป็นสําหรับแสดงหน้าเว็บ

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

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

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

บทสรุป

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

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

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