คู่มือสำหรับผู้เริ่มต้นใช้งานเว็บแอปแบบก้าวหน้า
เผยแพร่แล้ว: 2022-03-10เว็บแอปแบบโปรเกรสซีฟอาจเป็นสิ่งใหญ่ต่อไปสำหรับเว็บบนมือถือ เสนอโดย Google ในปี 2558 พวกเขาได้รับความสนใจอย่างมากเนื่องจากความง่ายในการพัฒนาและการชนะประสบการณ์ผู้ใช้แอปพลิเคชันเกือบจะในทันที
อ่านเพิ่มเติม เกี่ยวกับ SmashingMag:
- การสร้างบล็อกของเว็บแอปโปรเกรสซีฟ
- Conversational Design Essentials: เคล็ดลับในการสร้าง Chatbot
- การสร้างแอปชั้นหนึ่งที่ใช้ประโยชน์จากเว็บไซต์ของคุณ
- การสร้างเว็บแอปที่สมบูรณ์ในพื้นฐานสำหรับแอป
เว็บแอปพลิเคชันแบบโปรเกรสซีฟใช้ประโยชน์จากเทคโนโลยีล่าสุดเพื่อ รวมสิ่งที่ดีที่สุดของเว็บและแอปบนอุปกรณ์เคลื่อนที่ คิดว่าเป็นเว็บไซต์ที่สร้างขึ้นโดยใช้เทคโนโลยีเว็บ แต่ทำหน้าที่และให้ความรู้สึกเหมือนเป็นแอป ความก้าวหน้าล่าสุดในเบราว์เซอร์และความพร้อมใช้งานของพนักงานบริการ และใน Cache และ Push API ทำให้นักพัฒนาเว็บอนุญาตให้ผู้ใช้ติดตั้งเว็บแอปในหน้าจอหลัก รับการแจ้งเตือนแบบพุช และแม้กระทั่งทำงานแบบออฟไลน์
เว็บแอปแบบโปรเกรสซีฟใช้ประโยชน์จากระบบนิเวศของเว็บ ปลั๊กอิน และชุมชนที่มีขนาดใหญ่กว่ามาก และความสะดวกในการปรับใช้และบำรุงรักษาเว็บไซต์เมื่อเทียบกับแอปพลิเคชันดั้งเดิมในร้านค้าแอปที่เกี่ยวข้อง สำหรับผู้ที่พัฒนาทั้งบนมือถือและเว็บ คุณจะประทับใจที่เว็บไซต์สามารถสร้างขึ้นได้ในเวลาน้อยลง ที่ API ไม่จำเป็นต้องได้รับการดูแลให้มีความเข้ากันได้แบบย้อนหลัง (ผู้ใช้ทั้งหมดจะใช้เวอร์ชันเดียวกันของเว็บไซต์ของคุณ ซึ่งแตกต่างจากการแตกแฟรกเมนต์เวอร์ชันของแอปเนทีฟ) และ โดยทั่วไปแอปจะปรับใช้และบำรุงรักษาได้ง่ายกว่า
ทำไมต้องโปรเกรสซีฟเว็บแอป?
จากการศึกษาพบว่า โดยเฉลี่ยแล้ว แอปสูญเสียผู้ใช้ 20% ในทุกย่างก้าวระหว่างการติดต่อครั้งแรกของผู้ใช้กับแอปกับผู้ใช้ที่เริ่มใช้แอป ผู้ใช้ต้องค้นหาแอปใน App Store ก่อน ดาวน์โหลด ติดตั้ง จากนั้นเปิดแอปในที่สุด เมื่อผู้ใช้พบ Progressive Web App ของคุณ พวกเขาจะสามารถเริ่มใช้งานได้ทันที ขจัดขั้นตอนการดาวน์โหลดและการติดตั้งที่ไม่จำเป็น และเมื่อผู้ใช้กลับมาที่แอป จะได้รับแจ้งให้ติดตั้งแอปและอัปเกรดเป็นประสบการณ์เต็มหน้าจอ
อย่างไรก็ตาม แอปเนทีฟไม่ได้แย่ไปเสียทั้งหมด แอปพลิเคชันมือถือที่มีการแจ้งเตือนแบบพุชสามารถรักษาผู้ใช้ได้มากกว่าถึงสามเท่าโดยไม่ต้องกด และผู้ใช้มีโอกาสเปิดแอปพลิเคชันบนมือถืออีกครั้งมากกว่าเว็บไซต์ถึงสามเท่า นอกจากนี้ แอปพลิเคชันมือถือที่ออกแบบมาอย่างดียังใช้ข้อมูลน้อยกว่าและเร็วกว่ามาก เนื่องจากทรัพยากรบางส่วนอยู่ในอุปกรณ์
โปรเกรสซีฟเว็บแอปพลิเคชันใช้ประโยชน์จากคุณลักษณะของแอปบนอุปกรณ์เคลื่อนที่ ส่งผลให้การรักษาผู้ใช้และประสิทธิภาพการทำงานดีขึ้น โดยไม่มีความยุ่งยากที่เกี่ยวข้องกับการบำรุงรักษาแอปพลิเคชันบนมือถือ
ใช้กรณี
คุณควรสร้างเว็บแอปแบบโปรเกรสซีฟเมื่อใด โดยปกติแล้ว Native จะแนะนำสำหรับแอปพลิเคชันที่คุณคาดหวังให้ผู้ใช้กลับมาใช้บ่อยๆ และเว็บแอปแบบโปรเกรสซีฟก็ไม่ต่างกัน Flipkart ใช้เว็บแอปแบบโปรเกรสซีฟสำหรับแพลตฟอร์มอีคอมเมิร์ซยอดนิยม Flipkart Lite และ SBB ใช้เว็บแอปแบบโปรเกรสซีฟสำหรับกระบวนการเช็คอินออนไลน์ ทำให้ผู้ใช้สามารถเข้าถึงตั๋วได้โดยไม่ต้องเชื่อมต่ออินเทอร์เน็ต
เมื่อประเมินว่าแอปพลิเคชันถัดไปของคุณควรเป็นเว็บแอปแบบโปรเกรสซีฟ เว็บไซต์ หรือแอปพลิเคชันมือถือที่มาพร้อมเครื่อง ก่อนอื่นให้ระบุผู้ใช้ของคุณและการดำเนินการที่สำคัญที่สุดของผู้ใช้ แอปพลิเคชันเว็บแบบโปรเกรสซีฟ "ก้าวหน้า" ทำงานได้ในทุกเบราว์เซอร์ และประสบการณ์จะได้รับการปรับปรุงทุกครั้งที่เบราว์เซอร์ของผู้ใช้ได้รับการอัปเดตด้วยคุณลักษณะใหม่และ API ที่ได้รับการปรับปรุง
ดังนั้นจึงไม่มีการประนีประนอมในประสบการณ์ของผู้ใช้กับเว็บแอปแบบโปรเกรสซีฟเมื่อเทียบกับเว็บไซต์แบบดั้งเดิม อย่างไรก็ตาม คุณอาจต้องตัดสินใจเลือกฟังก์ชันที่จะรองรับออฟไลน์ และคุณจะต้องอำนวยความสะดวกในการนำทาง (โปรดจำไว้ว่าในโหมดสแตนด์อโลน ผู้ใช้จะไม่สามารถเข้าถึงปุ่มย้อนกลับได้) หากเว็บไซต์ของคุณมีอินเทอร์เฟซที่เหมือนแอปพลิเคชันอยู่แล้ว การใช้แนวคิดของเว็บแอปแบบโปรเกรสซีฟจะทำให้ดีขึ้น เท่านั้น
หากจำเป็นต้องใช้คุณลักษณะบางอย่างสำหรับการดำเนินการที่สำคัญของผู้ใช้แต่ยังไม่พร้อมใช้งานเนื่องจากขาดการสนับสนุนข้ามเบราว์เซอร์ แอปพลิเคชันมือถือที่มาพร้อมเครื่องอาจเป็นตัวเลือกที่ดีกว่า โดยรับประกันว่าผู้ใช้ทุกคนจะได้รับประสบการณ์เดียวกัน
ลักษณะของเว็บแอปโปรเกรสซีฟ
ก่อนที่เราจะพูดถึงโค้ด สิ่งสำคัญคือต้องเข้าใจว่าแอปโปรเกรสซีฟเว็บมีลักษณะดังต่อไปนี้:
- ก้าวหน้า . ตามคำนิยาม เว็บแอปแบบโปรเกรสซีฟต้องทำงานบนอุปกรณ์ใดๆ ก็ได้ และปรับปรุงอย่างเป็นขั้นเป็นตอน โดยใช้ประโยชน์จากคุณลักษณะใดๆ ที่มีอยู่ในอุปกรณ์และเบราว์เซอร์ของผู้ใช้
- ค้นพบ ได้ เนื่องจากโปรเกรสซีฟเว็บแอปเป็นเว็บไซต์ จึงควรสามารถค้นพบได้ในเครื่องมือค้นหา นี่เป็นข้อได้เปรียบที่สำคัญเหนือแอปพลิเคชันที่มาพร้อมเครื่อง ซึ่งยังคงล้าหลังเว็บไซต์ในด้านความสามารถในการค้นหา
- เชื่อมโยง ได้ เนื่องจากเป็นคุณลักษณะอื่นที่สืบทอดมาจากเว็บไซต์ เว็บไซต์ที่ออกแบบมาอย่างดีควรใช้ URI เพื่อระบุสถานะปัจจุบันของแอปพลิเคชัน การดำเนินการนี้จะช่วยให้เว็บแอปสามารถรักษาหรือโหลดสถานะซ้ำเมื่อผู้ใช้บุ๊กมาร์กหรือแชร์ URL ของแอป
- ตอบสนอง UI ของเว็บแอปโปรเกรสซีฟต้องพอดีกับฟอร์มแฟคเตอร์และขนาดหน้าจอของอุปกรณ์
- เหมือนแอพ เว็บแอปแบบโปรเกรสซีฟควรมีลักษณะเหมือนแอปที่มาพร้อมเครื่องและสร้างขึ้นจากโมเดลแอปพลิเคชันเชลล์ โดยมีการรีเฟรชหน้าน้อยที่สุด
- การเชื่อมต่อที่ไม่ ขึ้นกับ ควรทำงานในพื้นที่ที่มีการเชื่อมต่อต่ำหรือออฟไลน์ (คุณลักษณะที่เราชื่นชอบ)
- มีส่วนร่วมอีก ครั้ง ผู้ใช้แอปบนอุปกรณ์เคลื่อนที่มีแนวโน้มที่จะใช้แอปของตนซ้ำมากกว่า และเว็บแอปแบบโปรเกรสซีฟมีจุดมุ่งหมายเพื่อให้บรรลุเป้าหมายเดียวกันผ่านคุณลักษณะต่างๆ เช่น การแจ้งเตือนแบบพุช
- ติดตั้ง ได้. สามารถติดตั้งเว็บแอปโปรเกรสซีฟบนหน้าจอหลักของอุปกรณ์ได้ ทำให้พร้อมใช้งาน
- สด . เมื่อมีการเผยแพร่เนื้อหาใหม่และผู้ใช้เชื่อมต่อกับอินเทอร์เน็ต เนื้อหานั้นควรพร้อมใช้งานในแอป
- ปลอดภัย เนื่องจากโปรเกรสซีฟเว็บแอปมีประสบการณ์ผู้ใช้ที่ใกล้ชิดยิ่งขึ้น และเนื่องจากคำขอของเครือข่ายทั้งหมดสามารถสกัดกั้นผ่านพนักงานบริการ จึงจำเป็นที่แอปจะต้องโฮสต์ผ่าน HTTPS เพื่อป้องกันการโจมตีจากคนกลาง
มาโค้ดกันเถอะ!
เว็บแอปโปรเกรสซีฟตัวแรกของเรา Sky High จะจำลองตารางการมาถึงของสนามบิน ครั้งแรกที่ผู้ใช้เข้าถึงเว็บแอปของเรา เราต้องการแสดงรายการเที่ยวบินที่กำลังจะมาถึงซึ่งดึงมาจาก API หากผู้ใช้ไม่มีการเชื่อมต่ออินเทอร์เน็ตและโหลดเว็บแอปซ้ำ เราต้องการแสดงตารางเที่ยวบินเหมือนตอนที่พวกเขาดาวน์โหลดล่าสุดด้วยการเชื่อมต่อ

พื้นฐาน
คุณลักษณะแรกของเว็บแอปแบบโปรเกรสซีฟคือต้องทำงานบนอุปกรณ์ทั้งหมดและต้องปรับปรุงในอุปกรณ์และเบราว์เซอร์ที่อนุญาต ดังนั้นเราจึงสร้างเว็บไซต์ของเราโดยใช้ HTML5 แบบดั้งเดิมและด้วย JavaScript ที่จำลองการดึงข้อมูลจาก API จำลอง ตลอดทั้งแอปพลิเคชัน เราใช้สิ่งที่น่าพิศวงเล็กน้อยในการจัดการการเชื่อมโยง Model-View-ViewModel (MVVM) ของเรา ซึ่งเป็นเฟรมเวิร์ก JavaScript แบบเบาที่ช่วยให้เราสามารถผูกโมเดล JavaScript กับมุมมอง HTML ของเราได้ เราเลือกใช้สิ่งที่น่าพิศวงเพราะเข้าใจได้ง่ายและไม่เกะกะโค้ด อย่างไรก็ตาม คุณสามารถแทนที่สิ่งนี้ด้วยเฟรมเวิร์กอื่น ๆ เช่น React หรือ AngularJS
เว็บไซต์ของเราเป็นไปตามแนวทางการออกแบบวัสดุของ Google ซึ่งเป็นชุดของหลักการที่เป็นแนวทางในการออกแบบและการโต้ตอบ การออกแบบ Material ไม่เพียงแต่ทำหน้าที่เป็นมาตรฐานเดียวสำหรับแอปพลิเคชันและอุปกรณ์ต่างๆ เท่านั้น แต่ยังให้ความหมายในการออกแบบอีกด้วย เราใช้ดีไซน์ Material สำหรับมุมมองการมาถึงของ Sky High เพื่อให้เว็บแอปแบบโปรเกรสซีฟของเรามีรูปลักษณ์และความรู้สึกของแอปที่มาพร้อมเครื่อง
สุดท้าย เราได้ทดสอบแอปของเราเพื่อให้แน่ใจว่าไม่มีไฟล์ขยะและการเลื่อนเป็นไปอย่างราบรื่น มีการแสดงการแสดงผลที่ปราศจากปัญหาเพื่อปรับปรุงการมีส่วนร่วมของผู้ใช้ ตั้งเป้าการเรนเดอร์ 60 เฟรมต่อวินาที
สำหรับการสาธิตนี้ เราจะเรียกไฟล์ JSON แบบคงที่ แทนที่จะเป็น API จริง นี่เป็นเพียงเพื่อให้สิ่งต่าง ๆ เรียบง่าย ในโลกแห่งความเป็นจริง คุณจะต้องสอบถาม API หรือใช้ WebSockets
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sky-High Airport Arrivals</title> <link async rel="stylesheet" href="./css/style.css"> <link href="https://fonts.googleapis.com/css?family=Roboto:300,600,300italic,600italic" rel="stylesheet" type="text/css"> </head> <body> <header> <div class="content"> <h3>Arrivals</h3> </div> </header> <div class="container"> <div class="content"> <ul class="arrivals-list" data-bind="foreach: arrivals"> <li class="item"> <span class="title" data-bind="html: title"></span> <span class="status" data-bind="html: status"></span> <span class="time" data-bind="html: time"></span> </li> </ul> </div> </div> <script src="./js/build/vendor.min.js"></script> <script src="./js/build/script.min.js"></script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sky-High Airport Arrivals</title> <link async rel="stylesheet" href="./css/style.css"> <link href="https://fonts.googleapis.com/css?family=Roboto:300,600,300italic,600italic" rel="stylesheet" type="text/css"> </head> <body> <header> <div class="content"> <h3>Arrivals</h3> </div> </header> <div class="container"> <div class="content"> <ul class="arrivals-list" data-bind="foreach: arrivals"> <li class="item"> <span class="title" data-bind="html: title"></span> <span class="status" data-bind="html: status"></span> <span class="time" data-bind="html: time"></span> </li> </ul> </div> </div> <script src="./js/build/vendor.min.js"></script> <script src="./js/build/script.min.js"></script> </body> </html>
ไฟล์ index.html
ค่อนข้างมาตรฐาน เราได้สร้างรายการ HTML และผูกคุณสมบัติ View Model ที่ arrivals
ถึงโดยใช้สิ่งที่น่าพิศวง ผ่านแอตทริบิวต์ data-bind=“foreach: arrivals”
การมาถึงของ View Model ได้รับการประกาศใน page.js
arrivals
ล่างและเปิดเผยในโมดูล Page
ในหน้า HTML ของเรา สำหรับแต่ละรายการในอาร์เรย์ arrivals
เราได้ผูกคุณสมบัติ title
status
และ time
กับมุมมอง HTML
page.js
(var Page = (function() { // declare the view model used within the page function ViewModel() { var self = this; self.arrivals = ko.observableArray([]); } // expose the view model through the Page module return { vm: new ViewModel(), hideOfflineWarning: function() { // enable the live data document.querySelector(".arrivals-list").classList.remove('loading') // remove the offline message document.getElementById("offline").remove(); // load the live data }, showOfflineWarning: function() { // disable the live data document.querySelector(".arrivals-list").classList.add('loading') // load html template informing the user they are offline var request = new XMLHttpRequest(); request.open('GET', './offline.html', true); request.onload = function() { if (request.status === 200) { // success // create offline element with HTML loaded from offline.html template var offlineMessageElement = document.createElement("div"); offlineMessageElement.setAttribute("id", "offline"); offlineMessageElement.innerHTML = request.responseText; document.getElementById("main").appendChild(offlineMessageElement); } else { // error retrieving file console.warn('Error retrieving offline.html'); } }; request.onerror = function() { // network errors console.error('Connection error'); }; request.send(); } } })();
ไฟล์ page.js
นี้แสดงโมดูล Page
ซึ่งมี ViewModel vm
ของเราและสองฟังก์ชันคือ hideOfflineWarning
และ showOfflineWarning
View Model ViewModel
คือจาวาสคริปต์แบบง่ายที่จะถูกใช้ทั่วทั้งแอปพลิเคชัน การ arrivals
ของคุณสมบัติบน ViewModel คือ observableArray
ของ Knockout ซึ่งผูก HTML ของเรากับอาร์เรย์ JavaScript โดยอัตโนมัติ ทำให้เราสามารถพุชและป๊อปไอเท็มบนอาร์เรย์ของเราใน JavaScript และอัปเดต HTML ของหน้าโดยอัตโนมัติ
ฟังก์ชัน hideOfflineWarning
และ showOfflineWarning
ช่วยให้แอปพลิเคชันที่เหลือของเราสามารถเรียกใช้ฟังก์ชันเหล่านี้เพื่ออัปเดต UI ของหน้าเว็บที่แสดงว่าเราเชื่อมต่อออนไลน์หรือไม่ showOfflineWarning
เพิ่มคลาสของ loading
ไปยังองค์ประกอบ HTML ของ arrivals-list
ของเราเพื่อทำให้รายการจางลง จากนั้นจะดึงไฟล์ HTML offline.html
.html ผ่าน XHR สมมติว่าดึงไฟล์สำเร็จแล้ว ( response.status === 200
) เราผนวกสิ่งนี้กับ HTML ของเรา แน่นอน หากเราไม่ได้ใช้บริการของผู้ปฏิบัติงานด้านบริการ และผู้ใช้ไม่ได้เชื่อมต่อกับอินเทอร์เน็ต จะไม่สามารถเรียกข้อมูล offline.html
ได้ ดังนั้นผู้ใช้จะเห็นหน้าออฟไลน์ของเบราว์เซอร์

ตรรกะทางธุรกิจที่เราดึงข้อมูลจาก API ของเราและผูกเข้ากับ View Models และ Views นั้นพบได้ใน arrivals.js
และเป็นฟังก์ชัน MVVM มาตรฐานโดยใช้ Knockout ในไฟล์ arrivals.js
เราเพียงแค่เริ่มต้นบริการและดูโมเดลที่เราจะใช้ตลอดทั้งแอปพลิเคชัน และเราแสดงฟังก์ชัน — Arrivals.loadData()
— ที่ดึงข้อมูลและผูกเข้ากับโมเดลการดู
รายการแอปบนเว็บ
มาทำให้เว็บแอปของเราเหมือนแอปกันดีกว่า ไฟล์ Manifest ของเว็บแอปเป็นไฟล์ JSON อย่างง่ายที่เป็นไปตามข้อกำหนดของ W3C ด้วยวิธีนี้ คุณสามารถเรียกใช้เว็บแอปในโหมดเต็มหน้าจอเป็นแอปพลิเคชันแบบสแตนด์อโลน กำหนดไอคอนที่จะแสดงเมื่อติดตั้งแอปพลิเคชันบนอุปกรณ์ และกำหนดธีมและสีพื้นหลังให้กับแอป นอกจากนี้ Chrome บน Android จะแนะนำให้ผู้ใช้ติดตั้งเว็บแอปผ่านแบนเนอร์การติดตั้งเว็บแอป ในการแสดงข้อความแจ้งการติดตั้ง เว็บแอปของคุณต้อง:
- มีไฟล์รายการเว็บแอปที่ถูกต้อง
- ให้บริการผ่าน HTTPS
- มีการลงทะเบียนพนักงานบริการที่ถูกต้อง
- มีการเยี่ยมชมสองครั้ง อย่างน้อยห้านาทีระหว่างการเยี่ยมชมแต่ละครั้ง

manifest.json
{ "short_name": "Arrivals", "name": "Arrivals at Sky High", "description": "Progressive web application demonstration", "icons": [ { "src": "launcher-icon.png", "sizes": "48x48", "type": "image/png" }, { "src": "launcher-icon-96.png", "sizes": "96x96", "type": "image/png" }, { "src": "launcher-icon-144.png", "sizes": "144x144", "type": "image/png" }, { "src": "launcher-icon-192.png", "sizes": "192x192", "type": "image/png" }, { "src": "launcher-icon-256.png", "sizes": "256x256", "type": "image/png" } ], "start_url": "./?utm_source=web_app_manifest", "display": "standalone", "orientation": "portrait", "theme_color": "#29BDBB", "background_color": "#29BDBB" }
มาแยกย่อยไฟล์รายการนี้กัน:
-
short_name
เป็นชื่อที่มนุษย์อ่านได้สำหรับแอปพลิเคชัน ใน Chrome สำหรับ Android ชื่อนี้จะมาพร้อมกับไอคอนบนหน้าจอหลักด้วย -
name
ยังเป็นชื่อที่มนุษย์อ่านได้สำหรับแอปพลิเคชัน และกำหนดวิธีการแสดงรายการแอปพลิเคชัน -
description
ให้คำอธิบายทั่วไปของเว็บแอปพลิเคชัน -
icons
กำหนดอาร์เรย์ของรูปภาพที่มีขนาดต่างกันซึ่งจะทำหน้าที่เป็นชุดไอคอนของแอปพลิเคชัน ใน Chrome สำหรับ Android ไอคอนจะถูกใช้บนหน้าจอเริ่มต้น บนหน้าจอหลัก และในตัวสลับงาน -
start_url
คือ URL เริ่มต้นของแอปพลิเคชัน -
display
กำหนดโหมดการแสดงผลเริ่มต้นสำหรับเว็บแอปพลิเคชัน:fullscreen
,standalone
,minimal-ui
หรือbrowser
-
orientation
กำหนดการวางแนวเริ่มต้นสำหรับเว็บแอปพลิเคชัน:portrait
หรือlandscape
-
theme_color
เป็นสีของธีมเริ่มต้นสำหรับแอปพลิเคชัน บน Android ค่านี้ยังใช้เพื่อกำหนดสีแถบสถานะ -
background_color
กำหนดสีพื้นหลังของเว็บแอปพลิเคชัน ใน Chrome มันยังกำหนดสีพื้นหลังของหน้าจอเริ่มต้น -
related_applications
ไม่ได้ใช้งานในตัวอย่างของเรา แต่ใช้เพื่อระบุทางเลือกของแอปพลิเคชั่นดั้งเดิมในแอพสโตร์ต่างๆ
เพิ่มการอ้างอิง manifest.json
ไปยังแท็ก head
ของไฟล์ index.html
:
<link rel="manifest" href="./manifest.json">
เมื่อผู้ใช้เพิ่มเว็บแอปลงในหน้าจอหลักแล้ว พวกเขาจะสามารถมีส่วนร่วมกับแอปพลิเคชันของคุณอีกครั้งทันทีจากอุปกรณ์ของพวกเขา โดยไม่ต้องเปิดเบราว์เซอร์โดยตรง คุณสามารถดูว่ามันเป็นอะไรที่มากกว่าบุ๊กมาร์กเว็บ
เพิ่มไปที่หน้าจอหลักบน Chrome สำหรับ Android จาก Smashing Magazine บน Vimeo
พนักงานบริการ
แง่มุมที่น่าตื่นเต้นอีกอย่างหนึ่งของ Progressive Web App คือสามารถทำงานแบบออฟไลน์ได้ เมื่อใช้พนักงานบริการ จะแสดงข้อมูลที่ดึงมาในเซสชันก่อนหน้าของแอป (โดยใช้ IndexedDB) หรือแสดงเปลือกแอปพลิเคชันและแจ้งให้ผู้ใช้ทราบว่าไม่ได้เชื่อมต่อกับอินเทอร์เน็ต (วิธีที่เราได้ทำ ถ่ายในเดโมนี้) เมื่อผู้ใช้เชื่อมต่ออีกครั้ง เราก็สามารถดึงข้อมูลล่าสุดจากเซิร์ฟเวอร์ได้
ทั้งหมดนี้เป็นไปได้ผ่านพนักงานบริการ ซึ่งเป็นสคริปต์ที่ขับเคลื่อนด้วยเหตุการณ์ (เขียนด้วย JavaScript) ที่มีสิทธิ์เข้าถึงเหตุการณ์ทั่วทั้งโดเมน รวมถึงการดึงข้อมูลเครือข่าย เมื่อใช้สิ่งเหล่านี้ เราสามารถแคชทรัพยากรแบบคงที่ทั้งหมด ซึ่งสามารถลดคำขอของเครือข่ายได้อย่างมากและปรับปรุงประสิทธิภาพอย่างมากเช่นกัน
แอพลิเคชันเชลล์
เปลือกแอปพลิเคชันคือ HTML, CSS และ JavaScript ขั้นต่ำที่จำเป็นในการขับเคลื่อนส่วนต่อประสานผู้ใช้ แอปพลิเคชันมือถือแบบเนทีฟมีเปลือกแอปพลิเคชันเป็นส่วนหนึ่งของการแจกจ่าย ในขณะที่เว็บไซต์มักจะร้องขอสิ่งนี้ผ่านเครือข่าย แอปพลิเคชันเว็บแบบโปรเกรสซีฟเชื่อมช่องว่างนี้ด้วยการวางทรัพยากรและทรัพย์สินของเปลือกแอปพลิเคชันในแคชของเบราว์เซอร์ ในแอปพลิเคชัน Sky High ของเรา เราจะเห็นว่าเปลือกแอปพลิเคชันของเราประกอบด้วยแถบส่วนหัวด้านบน แบบอักษร และ CSS ที่จำเป็นในการเรนเดอร์เหล่านี้อย่างหรูหรา
ในการเริ่มต้นกับพนักงานบริการ อันดับแรก เราต้องสร้างไฟล์ JavaScript ของพนักงานบริการ sw.js
ซึ่งวางไว้ในไดเร็กทอรีราก
sw.js
// Use a cacheName for cache versioning var cacheName = 'v1:static'; // During the installation phase, you'll usually want to cache static assets. self.addEventListener('install', function(e) { // Once the service worker is installed, go ahead and fetch the resources to make this work offline. e.waitUntil( caches.open(cacheName).then(function(cache) { return cache.addAll([ './', './css/style.css', './js/build/script.min.js', './js/build/vendor.min.js', './css/fonts/roboto.woff', './offline.html' ]).then(function() { self.skipWaiting(); }); }) ); }); // when the browser fetches a URL… self.addEventListener('fetch', function(event) { // … either respond with the cached object or go ahead and fetch the actual URL event.respondWith( caches.match(event.request).then(function(response) { if (response) { // retrieve from cache return response; } // fetch as normal return fetch(event.request); }) ); });
มาดูพนักงานบริการของเรากันดีกว่า อันดับแรก เรากำลังตั้งค่าตัวแปร cacheName
ใช้เพื่อระบุว่ามีการเปลี่ยนแปลงใดๆ กับเนื้อหาที่แคชของเราหรือไม่ สำหรับตัวอย่างนี้ เราจะใช้ชื่อคงที่ หมายความว่าสินทรัพย์ของเราจะไม่เปลี่ยนแปลงหรือจำเป็นต้องอัปเดต
self.addEventListener('install', function(e) { // declare which assets to cache }
เหตุการณ์การ install
ตั้งจะเริ่มทำงานในระหว่างขั้นตอนการติดตั้งของพนักงานบริการ และจะเริ่มทำงานเพียงครั้งเดียวหากติดตั้งพนักงานบริการแล้ว ดังนั้น การรีเฟรชหน้าจะไม่ทริกเกอร์ขั้นตอนการติดตั้งอีก ในระหว่างขั้นตอนการติดตั้ง เราสามารถประกาศได้ว่าสินทรัพย์ใดจะถูกแคช ในตัวอย่างข้างต้น เรากำลังแคชไฟล์ CSS หนึ่งไฟล์ ไฟล์ JavaScript สองไฟล์ ไฟล์ฟอนต์ เทมเพลต HTML แบบออฟไลน์ และแน่นอนว่าเป็นรูทของแอปพลิเคชัน self.skipWaiting()
บังคับให้พนักงานบริการที่รอเปิดใช้งาน
จนถึงตอนนี้ เราได้ประกาศให้พนักงานบริการของเราทราบแล้ว แต่ก่อนที่เราจะเห็นมันมีผลบังคับใช้ เราต้องอ้างอิงใน JavaScript ของเรา ในใบสมัครของเรา เราลงทะเบียนใน main.js
// Register the service worker if available. if ('serviceWorker' in navigator) { navigator.serviceWorker.register('./sw.js').then(function(reg) { console.log('Successfully registered service worker', reg); }).catch(function(err) { console.warn('Error whilst registering service worker', err); }); } window.addEventListener('online', function(e) { // Resync data with server. console.log("You are online"); Page.hideOfflineWarning(); Arrivals.loadData(); }, false); window.addEventListener('offline', function(e) { // Queue up events for server. console.log("You are offline"); Page.showOfflineWarning(); }, false); // Check if the user is connected. if (navigator.onLine) { Arrivals.loadData(); } else { // Show offline message Page.showOfflineWarning(); } // Set Knockout view model bindings. ko.applyBindings(Page.vm);
เรายังได้รวมผู้ฟังเหตุการณ์สองคนเพื่อตรวจสอบว่าสถานะของเซสชันเปลี่ยนจาก online
เป็น offline
หรือกลับกัน จากนั้นตัวจัดการเหตุการณ์จะเรียกใช้ฟังก์ชันต่างๆ เพื่อดึงข้อมูลผ่าน Arrivals.loadData()
และเพื่อเปิดใช้งานหรือปิดใช้งานข้อความออฟไลน์ผ่าน Page.showOfflineWarning
และ Page.hideOfflineWarning
ตามลำดับ แอปพลิเคชันของเรายังตรวจสอบด้วยว่าผู้ใช้ออนไลน์อยู่หรือไม่ โดยใช้ navigator.onLine และดึงข้อมูลหรือแสดงคำเตือนออฟไลน์ตามลำดับ และในบรรทัดสุดท้ายของ main.js
เราใช้การเชื่อมโยงที่น่าพิศวงกับ View Model Page.vm
ของเรา
หากเราโหลดแอปพลิเคชันของเราเป็นครั้งแรก (ด้วยเครื่องมือสำหรับนักพัฒนา Chrome) เราจะไม่เห็นสิ่งใหม่ อย่างไรก็ตาม เมื่อทำการโหลดซ้ำ เราจะพบว่ามีการดึงทรัพยากรเครือข่ายจำนวนหนึ่งจากพนักงานบริการ นี่คือเปลือกแอปพลิเคชันของเรา

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

The Guardian ใช้แนวทางที่น่าสนใจเป็นพิเศษเมื่อผู้ใช้ออฟไลน์เข้าถึงเว็บไซต์ โดยนำเสนอปริศนาอักษรไขว้:

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

Push API ได้รับการสนับสนุนในเบราว์เซอร์ Chrome, Opera และ Samsung และอยู่ระหว่างการพัฒนาใน Firefox และ Microsoft Edge ขออภัย ไม่มีข้อบ่งชี้ว่าคุณลักษณะนี้จะถูกนำมาใช้ใน Safari
ผลงาน
ชัยชนะที่ง่ายที่สุดอย่างหนึ่งของผู้ปฏิบัติงานบริการคือ เราสามารถปรับปรุงประสิทธิภาพการทำงานได้โดยไม่ต้องใช้ความพยายามเพียงเล็กน้อยหรือไม่ต้องใช้ความพยายามเลย การเปรียบเทียบเว็บไซต์ของเรากับตัวเองก่อนที่จะมีการใช้งานพนักงานบริการ ก่อนที่เราจะเรียกข้อมูลมากกว่า 200 KB เมื่อโหลดหน้าเว็บ ที่ตอนนี้ลดเหลือ 13 KB ในเครือข่าย 3G ปกติ หน้าจะใช้เวลาโหลด 3.5 วินาที; ตอนนี้ใช้เวลา 500 มิลลิวินาที
การปรับปรุงประสิทธิภาพเหล่านี้รุนแรงมาก เนื่องจากตัวแอปพลิเคชันมีขนาดเล็กมากและมีฟังก์ชันการทำงานที่จำกัด อย่างไรก็ตาม ด้วยการใช้แคชอย่างถูกต้อง จึงสามารถปรับปรุงประสิทธิภาพและประสิทธิภาพที่รับรู้ได้อย่างมีนัยสำคัญ โดยเฉพาะอย่างยิ่งสำหรับผู้ใช้ในสถานที่ที่มีการเชื่อมต่อต่ำ
ประภาคาร
ทีมงาน Chrome ของ Google ได้รวบรวมเครื่องมือสำหรับทดสอบเว็บแอปแบบโปรเกรสซีฟ Lighthouse ทำงานใน Node.js หรือเป็นปลั๊กอินของ Chrome และสามารถพบได้บน GitHub ด้วย
หากต้องการเรียกใช้การทดสอบ Lighthouse เว็บไซต์ของคุณต้องพร้อมใช้งานออนไลน์ หมายความว่าคุณไม่สามารถทดสอบบน localhost
ได้
ในการเริ่มต้น ให้ดาวน์โหลดแพ็คเกจ npm:
npm install -g GoogleChrome/lighthouse
เมื่อติดตั้งแล้ว ให้เรียกใช้ Chrome (เวอร์ชัน 52 เป็นต้นไป):
npm explore -g lighthouse -- npm run chrome lighthouse https://incredibleweb.github.io/pwa-tutorial/
ผลลัพธ์ของการรัน Lighthouse จะปรากฏในบรรทัดคำสั่ง และจะให้คะแนนเว็บไซต์ของคุณตามคุณสมบัติและคุณสมบัติของแอพ Progressive Web App ที่คุณใช้งาน ตัวอย่างเช่น คุณกำลังใช้ไฟล์ manifest.json
หรือหน้าเว็บของคุณพร้อมใช้งานแบบออฟไลน์หรือไม่ .
บทสรุป
บทความนี้เป็นเพียงอาหารเรียกน้ำย่อยสำหรับเว็บแอปแบบโปรเกรสซีฟ เราสามารถทำอะไรได้อีกมากเพื่อสร้างประสบการณ์ที่เหมือนแอปที่ผู้ใช้กำลังมองหา ไม่ว่าจะด้วยการสนับสนุนการแจ้งเตือนแบบพุชด้วย Push API ทำให้แอปสามารถมีส่วนร่วมอีกครั้ง หรือใช้ IndexedDB และการซิงค์พื้นหลังเพื่อปรับปรุงประสบการณ์ออฟไลน์
การสนับสนุนข้ามเบราว์เซอร์
สิ่งเหล่านี้ยังคงเป็นช่วงแรกๆ สำหรับเว็บแอปแบบก้าวหน้า และการสนับสนุนข้ามเบราว์เซอร์ยังคงมีอยู่อย่างจำกัด โดยเฉพาะอย่างยิ่งใน Safari และ Edge อย่างไรก็ตาม Microsoft ให้การสนับสนุนเว็บแอปแบบโปรเกรสซีฟอย่างเปิดเผยและควรใช้งานคุณลักษณะเพิ่มเติมภายในสิ้นปีนี้
- พนักงานบริการและ Cache API รองรับในเบราว์เซอร์ Chrome, Firefox, Opera และ Samsung อยู่ระหว่างการพัฒนาใน Microsoft Edge คาดว่าจะวางจำหน่ายภายในสิ้นปี 2559 อยู่ระหว่างการพิจารณาของ Safari
- เพิ่มไปยังหน้าจอหลัก รองรับใน Chrome, Firefox, Opera, เบราว์เซอร์ Android และเบราว์เซอร์ของ Samsung ดูเหมือนว่า Microsoft จะระบุว่าเว็บแอปแบบโปรเกรสซีฟจะพร้อมใช้งานเป็นรายการร้านค้า ยังไม่มีแผนสำหรับ Safari ในตอนนี้
- พุช API ส่วนใหญ่รองรับในเบราว์เซอร์ Chrome, Firefox, Opera และ Samsung ในการพัฒนา Microsoft Edge ยังไม่มีแผนสำหรับ Safari ในตอนนี้
หากนักพัฒนาจำนวนมากขึ้นใช้ประโยชน์จากคุณสมบัติที่นำเสนอโดยโปรเกรสซีฟเว็บแอป ซึ่งค่อนข้างง่ายต่อการใช้งานและให้รางวัลทันที ผู้ใช้จะชอบใช้เว็บแอปเหล่านี้ในเบราว์เซอร์ที่รองรับโดยหวังว่าจะโน้มน้าวให้ผู้จำหน่ายเบราว์เซอร์รายอื่นปรับตัว
รหัสแหล่งที่มา
ซอร์สโค้ดทั้งหมดสำหรับบทช่วยสอนนี้มีอยู่ในที่เก็บ Github และการสาธิตมีอยู่ใน GitHub Pages