คู่มือสำหรับผู้เริ่มต้นใช้งานเว็บแอปแบบก้าวหน้า

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ PWAs ใช้ประโยชน์จากเทคโนโลยีล่าสุดเพื่อรวมสิ่งที่ดีที่สุดของเว็บและแอพมือถือ บทความนี้กล่าวถึงความก้าวหน้าล่าสุดในเบราว์เซอร์และโอกาสที่เราในฐานะนักพัฒนาจะต้องสร้างเว็บแอปเจเนอเรชันใหม่

เว็บแอปแบบโปรเกรสซีฟอาจเป็นสิ่งใหญ่ต่อไปสำหรับเว็บบนมือถือ เสนอโดย 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 หากผู้ใช้ไม่มีการเชื่อมต่ออินเทอร์เน็ตและโหลดเว็บแอปซ้ำ เราต้องการแสดงตารางเที่ยวบินเหมือนตอนที่พวกเขาดาวน์โหลดล่าสุดด้วยการเชื่อมต่อ

ภาพหน้าจอของ Sky High
Sky High เว็บแอปโปรเกรสซีฟที่สมมติขึ้นของเรา (ตัวอย่างขนาดใหญ่)

พื้นฐาน

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

เพิ่มไปที่หน้าจอหลักใน Chrome สำหรับ Android

พนักงานบริการ

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

เปลือกแอปพลิเคชัน
ทรัพยากรเครือข่าย Application Shell ใน Chrome Developer Tools (ดูเวอร์ชันขนาดใหญ่)

แบบทดสอบออฟไลน์

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

ล้มเหลวอย่างสง่างาม
แสดงหน้า HTML ที่กำหนดเองแทนหน้าเริ่มต้นของ Chrome (ดูเวอร์ชันขนาดใหญ่)

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

ปริศนาอักษรไขว้ออฟไลน์ของผู้พิทักษ์
ปริศนาอักษรไขว้ออฟไลน์ของเดอะการ์เดียน (ดูเวอร์ชันขนาดใหญ่)

การแจ้งเตือนแบบพุช

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

การแจ้งเตือนแบบพุช
การแจ้งเตือนแบบพุชบน Emojoy (ดูเวอร์ชันขนาดใหญ่)

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