สรุป
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 หรือฉากที่เกี่ยวข้องกับสถานที่ถ่ายทอดสดของซานต้า ซึ่งมีให้เชื่อมต่อกับขั้วโลกเหนือโดยตรงเท่านั้น 📶☃️
ความท้าทาย
ซานต้าใช้การออกแบบที่ตอบสนองตามอุปกรณ์ซึ่งทำงานได้ดีบนโทรศัพท์ แท็บเล็ต และเดสก์ท็อป เว็บไซต์เต็มไปด้วยมัลติมีเดียที่ยอดเยี่ยม รวมถึงภาพสไตไลซ์และเสียงธีมเทศกาล อย่างไรก็ตาม การติดตามซานตาคลอสรุ่นปกติมีขนาดหลายร้อยเมกะไบต์ โดยมีสาเหตุ 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="{{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
:
- ระบบจะไม่ทราบองค์ประกอบทั้งหมดของฉาก (รวมถึง
<boatload-scene>
) ในเบื้องต้นและถือเป็นHTMLUnknownElement
พร้อมด้วยแอตทริบิวต์เพิ่มเติม - เมื่อเปลี่ยนฉากที่เลือก ระบบจะแจ้งเตือนองค์ประกอบ
<lazy-pages>
- องค์ประกอบ
<lazy-pages>
แก้ไของค์ประกอบของฉากและแอตทริบิวต์path
โดยกำลังโหลด HTML นำเข้าscenes/boatload/boatload-scene_en.html
มีองค์ประกอบ Polymer และองค์ประกอบ Dependency - โปรแกรมโหลดล่วงหน้าที่ใช้งานง่ายจะปรากฏขึ้น
- เมื่อการนำเข้า HTML ถูกโหลดและดำเนินการแล้ว
<boatload-scene>
จะได้รับการอัปเกรดเป็น ธาตุโพลิเมอร์จริงที่เต็มไปด้วยความสุขในวันหยุด 🎄🎉
แนวทางนี้มีความท้าทายในตัวเอง ตัวอย่างเช่น เราไม่ต้องการรวมคอมโพเนนต์เว็บที่ซ้ำกัน
หากฉาก 2 ฉากใช้องค์ประกอบที่เหมือนกัน เช่น paper-button
เรานำแอปดังกล่าวออกซึ่งเป็นส่วนหนึ่งของบิลด์
และรวมไว้ในโค้ดที่ใช้งานร่วมกันของซานต้าแทน
การออกแบบแบบออฟไลน์
ตามติดซานต้าแบ่งเป็นฉากต่างๆ อย่างสวยงามอยู่แล้วด้วย Polymer และ lazy-pages
บวกละ
มีไดเรกทอรีของตัวเอง
เราออกแบบโปรแกรมทำงานของบริการติดตามซานตาคลอส ซึ่งเป็นเครื่องมือหลักที่ช่วยให้ทำงานแบบออฟไลน์ได้
เบราว์เซอร์ของผู้ใช้ เพื่อระมัดระวังโค้ดที่แชร์เมื่อเทียบกับ "ฉาก" ความแตกต่าง
ทฤษฎีที่อยู่เบื้องหลัง Service Worker คืออะไร เมื่อผู้ใช้ในเบราว์เซอร์ที่รองรับโหลดเว็บไซต์
HTML ฟรอนท์เอนด์สามารถขอติดตั้ง Service Worker ได้
สำหรับติดตามซานตาคลอส พนักงานบริการอาศัยอยู่ที่ /sw.js
การดำเนินการนี้จะเริ่มการทำงานของเหตุการณ์ install
ซึ่งจะแคชโค้ดที่แชร์ทั้งหมดของซานต้าล่วงหน้า จึงไม่จำเป็นต้องมีสิ่งใดอีก
ในรันไทม์
เมื่อติดตั้ง Service Worker แล้ว จะสามารถสกัดกั้นคำขอ HTTP ทั้งหมดได้ สำหรับตามติดซานต้า ขั้นตอนการตัดสินใจที่ง่ายดายมีดังนี้
- คำขอได้รับการแคชไว้อยู่แล้วใช่ไหม
- เยี่ยม! แสดงผลการตอบกลับที่แคชไว้
- คำขอตรงกับไดเรกทอรีโหมด เช่น "pictures/boatload/boatload-เสนอราคา_en.html" ไหม
- ส่งคำขอเครือข่าย และจัดเก็บผลลัพธ์ไว้ในแคชก่อนส่งคืนให้กับผู้ใช้
- มิฉะนั้นให้ดำเนินการตามคำขอเครือข่ายตามปกติ
โฟลว์และกิจกรรม 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 ใหม่ตั้งแต่ต้น หรือหากคุณกำลังหา แนวทางที่ไม่ยึดติดกับเฟรมเวิร์ก ให้ลองใช้ คลังพื้นที่ทำงาน