ติดตามซานตาคลอสในฐานะ PWA

ดูเว็บไซต์

สรุป

Santa Tracker ได้อัปเกรดเป็น Progressive Web App ออฟไลน์สำหรับช่วงเทศกาลวันหยุดปี 2016 อย่างรวดเร็ว ส่วนหนึ่งมาจากการออกแบบฉากที่เรามีอยู่แล้ว

ผลลัพธ์

  • ซานต้าเป็น Progressive Web App (PWA) ที่รองรับการเพิ่มลงในหน้าจอหลัก (ATHS) และแบบออฟไลน์
  • 10% ของเซสชันที่มีสิทธิ์เริ่มขึ้นผ่านไอคอน ATHS
  • 75% ของผู้ใช้ได้รับการรองรับองค์ประกอบที่กำหนดเองและ Shadow DOM ซึ่งเป็น 2 ส่วนหลักของคอมโพเนนต์เว็บ
  • คะแนนของ Lighthouse จาก 81 คะแนน
  • การใช้งานออฟไลน์ผ่าน Service Worker API จะเชื่อมโยงกับการโหลดแบบ Lazy Loading เพื่อแคชฉากที่เข้าชมเท่านั้นและอัปเกรดไปใช้รุ่นใหม่อย่างเงียบๆ

ข้อมูลเบื้องต้น

ตามติดซานต้าเป็นธรรมเนียมวันหยุดที่ Google ทุกๆ ปี คุณจะเฉลิมฉลองเทศกาลนี้ด้วยเกมและประสบการณ์ด้านการศึกษาได้ตลอดเดือนธันวาคม และระหว่างที่ซานต้าได้พักผ่อนอย่างเพียงพอ เหล่าเอลฟ์ก็ร่วมมือกันเผยแพร่ "ติดตามซานตาคลอส" ในรูปแบบ โอเพนซอร์ส ทั้งในเว็บและสำหรับ Android

บนเว็บ ตามติดซานต้าเป็นไซต์ขนาดใหญ่แบบอินเทอร์แอคทีฟที่มี "ฉาก" ที่ไม่ซ้ำกันมากมายซึ่งเขียนขึ้นโดยใช้ พอลิเมอร์ - รองรับเบราว์เซอร์ที่ทันสมัยส่วนใหญ่ การประเมินว่าเบราว์เซอร์ของผู้ใช้ "ทันสมัย" หรือไม่ จะกำหนดผ่านการตรวจหาฟีเจอร์ ดังนี้ ซานต้าต้องการ Set และ Web Performance API ทำงานร่วมกับ อื่นๆ

ในปี 2016 เราได้อัปเกรดเครื่องมือที่อยู่เบื้องหลังการติดตามซานตาคลอสเพื่อรองรับประสบการณ์ออฟไลน์สำหรับ ต่างๆ ยกเว้นฉากที่สนับสนุนโดยวิดีโอ YouTube หรือฉากที่เกี่ยวข้องกับสถานที่ถ่ายทอดสดของซานต้า ซึ่งมีให้เชื่อมต่อกับขั้วโลกเหนือโดยตรงเท่านั้น 📶☃️

วันที่ ติดตามซานตาคลอสบนอุปกรณ์ Android
ติดตามซานตาคลอสบนอุปกรณ์ Android

ความท้าทาย

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

  • รองรับซานต้ามากกว่า 35 ภาษา ดังนั้นเนื้อหาจำนวนมากต้องทำซ้ำ
  • แพลตฟอร์มที่แตกต่างกันมีการรองรับสื่อแตกต่างกัน (เช่น mp3 หรือ ogg)
  • บางครั้งไฟล์มัลติมีเดียก็มีขนาดและความละเอียดแตกต่างกันไป

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

ความท้าทายมีดังนี้

  • แหล่งข้อมูลมัลติมีเดียขนาดใหญ่สำหรับ 'ฉาก' ต่างๆ
  • การเปลี่ยนแปลงที่เผยแพร่ตลอดทั้งเดือน

...ส่งผลให้กลยุทธ์ออฟไลน์แบบไร้เดียงสามีความไม่เหมาะสม

ซานต้าที่สร้างด้วย Polymer

การย้อนกลับไปและพูดถึงการออกแบบโดยรวมของซานต้า ก่อนจะเราจะเจาะลึกรายละเอียดเกี่ยวกับวิธีที่เรา อัปเกรดเป็น PWA แบบออฟไลน์แล้ว

ซานต้าเป็นแอปพลิเคชันหน้าเว็บเดียว ซึ่งแต่เดิมเขียนด้วย Polymer 0.5 และตอนนี้ได้อัปเกรดเป็น Polymer 1.7 ซานต้าประกอบด้วยชุดโค้ดที่ใช้ร่วมกัน เช่น เราเตอร์ เนื้อหาการนำทางที่แชร์ ฯลฯ และยังมี "ฉาก" ที่ไม่เหมือนใครมากมาย

ตัวโหลดล่วงหน้า

แต่ละฉากจะเข้าถึงได้ผ่าน URL ที่แตกต่างกัน เช่น /village.html, /codelab.html และ /boatload.html และเป็นคอมโพเนนต์เว็บของตัวเอง เมื่อผู้ใช้เปิดฉาก เราจะโหลด HTML และเนื้อหาที่จำเป็นทั้งหมดไว้ล่วงหน้า (รูปภาพ, เสียง, CSS, js) ซึ่งอยู่ใน /scenes/[[sceneName]] ในที่เก็บตามติดซานต้า ในกรณีนี้ ผู้ใช้จะเห็นตัวโหลดล่วงหน้าที่ใช้งานง่ายซึ่งจะแสดงความคืบหน้า

วิธีนี้ช่วยให้เราไม่ต้องโหลดเนื้อหาที่ไม่จำเป็นสำหรับฉากที่ผู้ใช้มองไม่เห็น (ซึ่งมีข้อมูลจำนวนมาก) และยังหมายความว่าเราจำเป็นต้องเก็บ "ไฟล์ Manifest ของแคช" ภายในไว้ จากเนื้อหาทั้งหมดที่จำเป็นสำหรับ ในทุกๆ ฉาก ไฟล์ Manifest ของแคชเป็นไฟล์ JSON ที่จัดเก็บการแมปจากชื่อไฟล์ไปยังแฮช MD5 ของเนื้อหา

โหลดสิ่งที่คุณใช้

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

<lazy-pages id="lazypages" selected-item="&#123;{selectedScene}}" ... >
    <dorf-scene id="village" route="village" icon="1f384" permanent
        mode$="[[mode]]"
        path$="scenes/dorf/dorf-scene_[[language]].html"
        class="santa-scene" allow-page-scrolling></dorf-scene>

    <boatload-scene route="boatload" icon="26f5"
        path$="scenes/boatload/boatload-scene_[[language]].html"
        loading-bg-color="#8fd7f7"
        loading-src="scenes/boatload/img/loading.svg"
        logo="scenes/boatload/img/logo.svg"
        class="santa-scene"></boatload-scene>

ตามติดซานต้าทำตามขั้นตอนต่อไปนี้เพื่อโหลดฉาก เช่น boatload-scene:

  1. ระบบจะไม่ทราบองค์ประกอบทั้งหมดของฉาก (รวมถึง <boatload-scene>) ในเบื้องต้นและถือเป็น HTMLUnknownElement พร้อมด้วยแอตทริบิวต์เพิ่มเติม
  2. เมื่อเปลี่ยนฉากที่เลือก ระบบจะแจ้งเตือนองค์ประกอบ <lazy-pages>
  3. องค์ประกอบ <lazy-pages> แก้ไของค์ประกอบของฉากและแอตทริบิวต์ path โดยกำลังโหลด HTML นำเข้า scenes/boatload/boatload-scene_en.html มีองค์ประกอบ Polymer และองค์ประกอบ Dependency
  4. โปรแกรมโหลดล่วงหน้าที่ใช้งานง่ายจะปรากฏขึ้น
  5. เมื่อการนำเข้า HTML ถูกโหลดและดำเนินการแล้ว <boatload-scene> จะได้รับการอัปเกรดเป็น ธาตุโพลิเมอร์จริงที่เต็มไปด้วยความสุขในวันหยุด 🎄🎉

แนวทางนี้มีความท้าทายในตัวเอง ตัวอย่างเช่น เราไม่ต้องการรวมคอมโพเนนต์เว็บที่ซ้ำกัน หากฉาก 2 ฉากใช้องค์ประกอบที่เหมือนกัน เช่น paper-button เรานำแอปดังกล่าวออกซึ่งเป็นส่วนหนึ่งของบิลด์ และรวมไว้ในโค้ดที่ใช้งานร่วมกันของซานต้าแทน

การออกแบบแบบออฟไลน์

ตามติดซานต้าแบ่งเป็นฉากต่างๆ อย่างสวยงามอยู่แล้วด้วย Polymer และ lazy-pages บวกละ มีไดเรกทอรีของตัวเอง เราออกแบบโปรแกรมทำงานของบริการติดตามซานตาคลอส ซึ่งเป็นเครื่องมือหลักที่ช่วยให้ทำงานแบบออฟไลน์ได้ เบราว์เซอร์ของผู้ใช้ เพื่อระมัดระวังโค้ดที่แชร์เมื่อเทียบกับ "ฉาก" ความแตกต่าง

ทฤษฎีที่อยู่เบื้องหลัง Service Worker คืออะไร เมื่อผู้ใช้ในเบราว์เซอร์ที่รองรับโหลดเว็บไซต์ HTML ฟรอนท์เอนด์สามารถขอติดตั้ง Service Worker ได้ สำหรับติดตามซานตาคลอส พนักงานบริการอาศัยอยู่ที่ /sw.js การดำเนินการนี้จะเริ่มการทำงานของเหตุการณ์ install ซึ่งจะแคชโค้ดที่แชร์ทั้งหมดของซานต้าล่วงหน้า จึงไม่จำเป็นต้องมีสิ่งใดอีก ในรันไทม์

แผนภาพขั้นตอน SW

เมื่อติดตั้ง Service Worker แล้ว จะสามารถสกัดกั้นคำขอ HTTP ทั้งหมดได้ สำหรับตามติดซานต้า ขั้นตอนการตัดสินใจที่ง่ายดายมีดังนี้

  1. คำขอได้รับการแคชไว้อยู่แล้วใช่ไหม
    • เยี่ยม! แสดงผลการตอบกลับที่แคชไว้
  2. คำขอตรงกับไดเรกทอรีโหมด เช่น "pictures/boatload/boatload-เสนอราคา_en.html" ไหม
    • ส่งคำขอเครือข่าย และจัดเก็บผลลัพธ์ไว้ในแคชก่อนส่งคืนให้กับผู้ใช้
  3. มิฉะนั้นให้ดำเนินการตามคำขอเครือข่ายตามปกติ

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

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

เราจะทำแบบสดๆ

ตามที่เรากล่าวไปแล้วว่าเอลฟ์ของซานต้าทำงานหนักตลอดเดือนธันวาคมและมักจะต้องปลดปล่อย อัปเดตใหม่ๆ ตลอดทั้งเดือน เมื่อมีการเปิดตัวแอปติดตามซานตาคลอส จะมีป้ายกำกับเฉพาะ เช่น v20161204112055 การประทับเวลาของการเผยแพร่ (11:20:55 ในวันที่ 4 ธันวาคม 2016)

สำหรับรุ่นที่มีป้ายกำกับนี้ เราสร้างแฮช MD5 สำหรับทุกไฟล์และจัดเก็บไว้ใน "แคช" ของเรา Manifest" บนดิสก์ Solid State ที่ทันสมัย การทำงานนี้จะเพิ่มเพียงไม่กี่วินาทีในกระบวนการสร้าง

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

นอกจากนี้ เรายังติดตั้งใช้งานสิ่งที่เราเรียกว่า "prod" เวอร์ชันใหม่ด้วย ทรัพยากร — HTML และบริการของซานต้า ผู้ปฏิบัติงาน ซึ่งอยู่บน https://santatracker.google.com/ การดำเนินการนี้จะแทนที่เวอร์ชันเก่า

แผนภาพแบบคงที่

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

ในขั้นตอนนี้ เบราว์เซอร์ของผู้ใช้จะดู "ไฟล์ Manifest ของแคช" ใหม่ ซึ่งจะเปรียบเทียบกับแคชเดิมของผู้ใช้ และหากเนื้อหามีแฮช MD5 ต่างกัน ให้ลบไฟล์ออกจากแคช และขอให้เบราว์เซอร์ดึงข้อมูลอีกครั้ง แต่ในกรณีส่วนใหญ่ เนื้อหาที่แคชไว้จะยังคงเหมือนเดิมหรือแตกต่างกันเพียงเล็กน้อย

แผนภาพแคช

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

ประสบการณ์การเรียกดูแบบออฟไลน์

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

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

ออฟไลน์

ตามติดซานต้าจะส่งคำขอไปยัง API ของซานต้าเป็นประจำ หากคำขอเหล่านี้ไม่สำเร็จหรือหมดเวลา เราจะถือว่าผู้ใช้ออฟไลน์อยู่ เราใช้ API นี้แทน navigator.onLine ในตัวของเบราว์เซอร์ พร็อพเพอร์ตี้: การดำเนินการนี้จะ แจ้งให้เราทราบว่าผู้ใช้อาจออนไลน์หรือไม่ (หรือเรียกอีกอย่างว่า Lie-Fi)

การเชื่อมต่อระหว่างประเทศ

แม้ว่าผู้ใช้ส่วนใหญ่ของเราจะใช้ภาษาอังกฤษ (ตามด้วยภาษาญี่ปุ่น โปรตุเกส สเปน ฝรั่งเศส) ซานต้าได้รับการสร้างและเปิดตัวในภาษาต่างๆ กว่า 35 ภาษา

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

ภาษา

พูดง่ายๆ ก็คือ การติดตามซานตาคลอสเวอร์ชันปัจจุบันตามวัตถุประสงค์ของโปรแกรมทำงานของบริการ ที่จริงแล้วเป็น tuple ของ (build,language)

เพิ่มลงในหน้าจอหลัก

เนื่องจากซานต้าทำงานแบบออฟไลน์และมีโปรแกรมทำงานของบริการ ผู้ใช้ที่มีสิทธิ์จะได้รับแจ้งให้ติดตั้ง ลงในหน้าจอหลัก ในปี 2016 การโหลดที่มีสิทธิ์ประมาณ 10% มาจากไอคอนหน้าจอหลัก

บทสรุป

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

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