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

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

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

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

ทีนี้ลองนึกภาพว่าในขั้นตอนการดาวน์โหลด 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 ภาพจะถ่ายขณะไปที่ตัวอย่างแอปในโหมดไม่ระบุตัวตนโดยใช้การควบคุมเครือข่ายเพื่อจำลองการเชื่อมต่อที่ช้า

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

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

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

ในภาพหน้าจอด้านบน การลงทะเบียน 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');
    });
}