下一代 Web 应用模型 —— Progressive Web App (PWA)
今年 9 月份的時候,《程序員》雜志社就邀請我寫一篇關(guān)于 PWA 的文章。后來花式拖稿,拖過了 10 月的 QCon,11 月的 GDG DevFest,終于在 12 月把這篇長文熬了出來。幾次分享的不成熟,這次的結(jié)構(gòu)算是比較滿意了。「 可能是目前中文世界里對 PWA 最全面詳細的長文了」,希望你能喜歡。
本文首發(fā)于?CSDN?與《程序員》2017 年 2 月刊,同步發(fā)布于?Hux Blog、前端外刊評論 - 知乎專欄,轉(zhuǎn)載請保留鏈接 ;)
下一代 Web 應(yīng)用?
近年來,Web 應(yīng)用在整個軟件與互聯(lián)網(wǎng)行業(yè)承載的責任越來越重,軟件復(fù)雜度和維護成本越來越高,Web 技術(shù),尤其是 Web 客戶端技術(shù),迎來了爆發(fā)式的發(fā)展。
包括但不限于基于 Node.js 的前端工程化方案;諸如 Webpack、Rollup 這樣的打包工具;Babel、PostCSS 這樣的轉(zhuǎn)譯工具;TypeScript、Elm 這樣轉(zhuǎn)譯至 JavaScript 的編程語言;React、Angular、Vue 這樣面向現(xiàn)代 web 應(yīng)用需求的前端框架及其生態(tài),也涌現(xiàn)出了像同構(gòu) JavaScript與通用 JavaScript 應(yīng)用這樣將服務(wù)器端渲染(Server-side Rendering)與單頁面應(yīng)用模型(Single-page App)結(jié)合的 web 應(yīng)用架構(gòu)方式,可以說是百花齊放。
但是,Web 應(yīng)用在移動時代并沒有達到其在桌面設(shè)備上流行的程度。究其原因,盡管上述的各種方案已經(jīng)充分利用了現(xiàn)有的 JavaScript 計算能力、CSS 布局能力、HTTP 緩存與瀏覽器 API 對當代基于?Ajax?與響應(yīng)式設(shè)計的 web 應(yīng)用模型的性能與體驗帶來了工程角度的巨大突破,我們?nèi)匀粺o法在不借助原生程序輔助瀏覽器的前提下突破 web 平臺本身對 web 應(yīng)用固有的桎梏:客戶端軟件(即網(wǎng)頁)需要下載所帶來的網(wǎng)絡(luò)延遲;與 Web 應(yīng)用依賴瀏覽器作為入口所帶來的體驗問題。
Web 與原生應(yīng)用在移動平臺上的使用時長對比?圖片來源: Google
在桌面設(shè)備上,由于網(wǎng)絡(luò)條件穩(wěn)定,屏幕尺寸充分,交互方式趨向于多任務(wù),這兩點造成的負面影響對比 web 應(yīng)用免于安裝、隨叫隨到、無需更新等優(yōu)點,瑕不掩瑜。但是在移動時代,脆弱的網(wǎng)絡(luò)連接與全新的人機交互方式使得這兩個問題被無限放大,嚴重制約了 web 應(yīng)用在移動平臺的發(fā)展。在用戶眼里,原生應(yīng)用不會出現(xiàn)「白屏」,清一色都擺在主屏幕上;而 web 應(yīng)用則是瀏覽器這個應(yīng)用中的應(yīng)用,使用起來并不方便,而且加載也比原生應(yīng)用要慢。
Progressive Web Apps(以下簡稱 PWA)以及構(gòu)成 PWA 的一系列關(guān)鍵技術(shù)的出現(xiàn),終于讓我們看到了徹底解決這兩個平臺級別問題的曙光:能夠顯著提高應(yīng)用加載速度、甚至讓 web 應(yīng)用可以在離線環(huán)境使用的 Service Worker 與 Cache Storage;用于描述 web 應(yīng)用元數(shù)據(jù)(metadata)、讓 web 應(yīng)用能夠像原生應(yīng)用一樣被添加到主屏、全屏執(zhí)行的 Web App Manifest;以及進一步提高 web 應(yīng)用與操作系統(tǒng)集成能力,讓 web 應(yīng)用能在未被激活時發(fā)起推送通知的 Push API 與 Notification API 等等。
將這些技術(shù)組合在一起會是怎樣的效果呢?「印度阿里巴巴」 ——?Flipkart?在 2015 年一度關(guān)閉了自己的移動端網(wǎng)站,卻在年底發(fā)布了現(xiàn)在最為人津津樂道的 PWA 案例?FlipKart Lite,成為世界上第一個支撐大規(guī)模業(yè)務(wù)的 PWA。發(fā)布的一周后它就亮相于?Chrome Dev Summit 2015?上,筆者當時就被驚艷到了。為了方便各媒介上的讀者觀看,筆者做了幾幅圖方便給大家介紹:
圖片來源: Hux &?Medium.com
當瀏覽器發(fā)現(xiàn)用戶需要?Flipkart Lite 時,它就會提示用戶「嘿,你可以把它添加至主屏哦」(用戶也可以手動添加)。這樣,Flipkart Lite 就會像原生應(yīng)用一樣在主屏上留下一個自定義的 icon 作為入口;與一般的書簽不同,當用戶點擊 icon 時,Flipkat Lite 將直接全屏打開,不再受困于瀏覽器的 UI 中,而且有自己的啟動屏效果。
圖片來源: Hux &?Medium.com
更強大的是,在無法訪問網(wǎng)絡(luò)時,Flipkart Lite 可以像原生應(yīng)用一樣照常執(zhí)行,還會很騷氣的變成黑白色;不但如此,曾經(jīng)訪問過的商品都會被緩存下來得以在離線時繼續(xù)訪問。在商品降價、促銷等時刻,Flipkart Lite 會像原生應(yīng)用一樣發(fā)起推送通知,吸引用戶回到應(yīng)用。
無需擔心網(wǎng)絡(luò)延遲;有著獨立入口與獨立的保活機制。之前兩個問題的一并解決,宣告著 web 應(yīng)用在移動設(shè)備上的浴火重生:滿足 PWA 模型的 web 應(yīng)用,將逐漸成為移動操作系統(tǒng)的一等公民,并將向原生應(yīng)用發(fā)起挑戰(zhàn)與「復(fù)仇」。
更令筆者興奮的是,就在今年 11 月的?Chrome Dev Summit 2016?上,Chrome 的工程 VP Darin Fisher 介紹了 Chrome 團隊正在做的一些實驗:把「添加至主屏」重命名為「安裝」,被安裝的 PWA 不再僅以 widget 的形式顯示在桌面上,而是真正做到與所有原生應(yīng)用平級,一樣被收納進應(yīng)用抽屜(App Drawer)里,一樣出現(xiàn)在系統(tǒng)設(shè)置中 ������。
圖片來源: Hux &?@adityapunjani
圖中從左到右分別為:類似原生應(yīng)用的安裝界面;被收納在應(yīng)用抽屜里的 Flipkart Lite 與 Hux Blog;設(shè)置界面中并列出現(xiàn)的 Flipkart 原生應(yīng)用與 Flipkart Lite PWA (可以看到 PWA 巨大的體積優(yōu)勢)
筆者相信,PWA 模型將繼約 20 年前橫空出世的 Ajax 與約 10 年前風靡移動互聯(lián)網(wǎng)的響應(yīng)式設(shè)計之后,掀起 web 應(yīng)用模型的第三次根本性革命,將 web 應(yīng)用帶進一個全新的時代。
PWA 關(guān)鍵技術(shù)的前世今生
Web App Manifest
Web App Manifest,即通過一個清單文件向瀏覽器暴露 web 應(yīng)用的元數(shù)據(jù),包括名字、icon 的 URL 等,以備瀏覽器使用,比如在添加至主屏或推送通知時暴露給操作系統(tǒng),從而增強 web 應(yīng)用與操作系統(tǒng)的集成能力。
讓 web 應(yīng)用在移動設(shè)備上的體驗更接近原生應(yīng)用的嘗試其實早在 2008 年的?iOS 1.1.3 與 iOS 2.1.0?時就開始了,它們分別為 web 應(yīng)用增加了對自定義 icon 和全屏打開的支持。
圖片來源:?appleinsider.com
但是很快,隨著越來越多的私有平臺通過?<meta>/<link>?標簽來為 web 應(yīng)用添加「私貨」,<head>?很快就被塞滿了:
<!-- Add to homescreen for Safari on iOS --> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-title" content="Lighten"><!-- Add to homescreen for Chrome on Android --> <meta name="mobile-web-app-capable" content="yes"> <mate name="theme-color" content="#000000"><!-- Icons for iOS and Android Chrome M31~M38 --> <link rel="apple-touch-icon-precomposed" sizes="144x144" href="images/touch/apple-touch-icon-144x144-precomposed.png"> <link rel="apple-touch-icon-precomposed" sizes="114x114" href="images/touch/apple-touch-icon-114x114-precomposed.png"> <link rel="apple-touch-icon-precomposed" sizes="72x72" href="images/touch/apple-touch-icon-72x72-precomposed.png"> <link rel="apple-touch-icon-precomposed" href="images/touch/apple-touch-icon-57x57-precomposed.png"><!-- Icon for Android Chrome, recommended --> <link rel="shortcut icon" sizes="196x196" href="images/touch/touch-icon-196x196.png"><!-- Tile icon for Win8 (144x144 + tile color) --> <meta name="msapplication-TileImage" content="images/touch/ms-touch-icon-144x144-precomposed.png"> <meta name="msapplication-TileColor" content="#3372DF"><!-- Generic Icon --> <link rel="shortcut icon" href="images/touch/touch-icon-57x57.png">顯然,這種做法并不優(yōu)雅:分散又重復(fù)的元數(shù)據(jù)定義多余且難以維持同步,與 html 耦合在一起也加重了瀏覽器檢查元數(shù)據(jù)未來變動的成本。與此同時,社區(qū)里開始出現(xiàn)使用 manifest 文件以中心化地描述元數(shù)據(jù)的方案,比如?Chrome Extension、 Chrome Hosted Web Apps (2010)?與?Firefox OS App Manifest (2011)?使用 JSON;Cordova?與?Windows Pinned Site?使用 XML;
2013 年,W3C WebApps 工作組開始對基于 JSON 的 Manifest 進行標準化,于同年年底發(fā)布第一份公開 Working Draft,并逐漸演化成為今天的 W3C Web App Manifest:
{"short_name": "Manifest Sample","name": "Web Application Manifest Sample","icons": [{"src": "launcher-icon-2x.png","sizes": "96x96","type": "image/png"}],"scope": "/sample/","start_url": "/sample/index.html","display": "standalone","orientation": "landscape""theme_color": "#000","background_color": "#fff", } <!-- document --> <link rel="manifest" href="/manifest.json">諸如?name、icons、display?都是我們比較熟悉的,而大部分新增的成員則為 web 應(yīng)用帶來了一系列以前 web 應(yīng)用想做卻做不到(或在之前只能靠 hack)的新特性:
- scope:定義了 web 應(yīng)用的瀏覽作用域,比如作用域外的 URL 就會打開瀏覽器而不會在當前 PWA 里繼續(xù)瀏覽。
- start_url:定義了一個 PWA 的入口頁面。比如說你添加?Hux Blog?的任何一個文章到主屏,從主屏打開時都會訪問?Hux Blog?的主頁。
- orientation:終于,我們可以鎖定屏幕旋轉(zhuǎn)了(喜極而泣…)
- theme_color/background_color:主題色與背景色,用于配置一些可定制的操作系統(tǒng) UI 以提高用戶體驗,比如 Android 的狀態(tài)欄、任務(wù)欄等。
這個清單的成員還有很多,比如用于聲明「對應(yīng)原生應(yīng)用」的?related_applications?等等,本文就不一一列舉了。作為 PWA 的「戶口本」,承載著 web 應(yīng)用與操作系統(tǒng)集成能力的重任,Web App Manifest 還將在日后不斷擴展,以滿足 web 應(yīng)用高速演化的需要。
Service Worker
我們原有的整個 Web 應(yīng)用模型,都是構(gòu)建在「用戶能上網(wǎng)」的前提之下的,所以一離線就只能玩小恐龍了。其實,對于「讓 web 應(yīng)用離線執(zhí)行」這件事,Service Worker 至少是 web 社區(qū)的第三次嘗試了。
故事可以追溯到 2007 年的?Google Gears:為了讓自家的 Gmail、Youtube、Google Reader 等 web 應(yīng)用可以在本地存儲數(shù)據(jù)與離線執(zhí)行,Google 開發(fā)了一個瀏覽器拓展來增強 web 應(yīng)用。Google Gears 支持 IE 6、Safari 3、Firefox 1.5 等瀏覽器;要知道,那一年 Chrome 都還沒出生呢。
在 Gears API 中,我們通過向 LocalServer 模塊提交一個緩存文件清單來實現(xiàn)離線支持:
// Somewhere in your javascript var localServer = google.gears.factory.create("bata.localserver"); var store = localServer.createManagedStore(STORE_NAME); store.manifestUrl = "manifest.json" // manifest.json - 假設(shè) JSON 有注釋 { "betaManifestVersion": 1, "version": "1.0", "entries": [ { "url": "index.html"}, { "url": "main.js"} ] }是不是感到很熟悉?好像?HTML5 規(guī)范中的 Application Cache 也是類似的東西?
<html manifest="cache.appcache"> CACHE MANIFESTCACHE: index.html main.js是的,Gears 的 LocalServer 就是后來大家所熟知的 App Cache 的前身,大約從?2008?年開始 W3C 就開始嘗試將 Gears 進行標準化了;除了 LocalServer,Gears 中用于提供并行計算能力的 WorkerPool 模塊與用于提供本地數(shù)據(jù)庫與 SQL 支持的 Database 模塊也分別是日后 Web Worker 與 Web SQL Database(后被廢棄)的前身。
HTML5 App Cache 作為第二波「讓 web 應(yīng)用離線執(zhí)行」的嘗試,確實也服務(wù)了比如 Google Doc、尤雨溪早年作品 HTML5 Clear、以及一直用 web 應(yīng)用作為自己 iOS 應(yīng)用的 FT.com(Financial Times)等不少 web 應(yīng)用。那么,還有 Service Worker 什么事呢?
是啊,如果 App Cache 沒有被設(shè)計得爛到完全不可編程、無法清理緩存、幾乎沒有路由機制、出了 Bug 一點救都沒有,可能就真沒 Service Worker 什么事了。App Cache 已經(jīng)在前不久定稿的 HTML5.1 中被拿掉了,W3C 為了挽救 web 世界真是不惜把自己的臉都打腫了……
時至今日,我們終于迎來了 Service Worker 的曙光。簡單來說,Service Worker 是一個可編程的 Web Worker,它就像一個位于瀏覽器與網(wǎng)絡(luò)之間的客戶端代理,可以攔截、處理、響應(yīng)流經(jīng)的 HTTP 請求;配合隨之引入 Cache Storage API,你可以自由管理 HTTP 請求文件粒度的緩存,這使得 Service Worker 可以從緩存中向 web 應(yīng)用提供資源,即使是在離線的環(huán)境下。
Service Worker 就像一個運行在客戶端的代理
比如說,我們可以給網(wǎng)頁?foo.html?注冊這么一個 Service Worker,它將劫持由?foo.html?發(fā)起的一切 HTTP 請求,并統(tǒng)統(tǒng)返回未設(shè)置?Content-Type?的?Hello World!:
// sw.js self.onfetch = (e) => {e.respondWith(new Response('Hello World!')) }Service Worker 第一次發(fā)布于 2014 年的 Google IO 上,目前已處于 W3C 工作草案的狀態(tài)。其設(shè)計吸取了 Application Cache 的失敗經(jīng)驗,作為 web 應(yīng)用的開發(fā)者的你有著完全的控制能力;同時,它還借鑒了 Chrome 多年來在 Chrome Extension 上的設(shè)計經(jīng)驗(Chrome Background Pages 與 Chrome Event Pages),采用了基于「事件驅(qū)動」的喚醒機制,以大幅節(jié)省后臺計算的能耗。比如上面的?fetch?其實就是會喚醒 Service Worker 的事件之一。
Service Worker 的生命周期
除了類似?fetch?這樣的功能事件外,Service Worker 還提供了一組生命周期事件,包括安裝、激活等等。比如,在 Service Worker 的「安裝」事件中,我們可以把 web 應(yīng)用所需要的資源統(tǒng)統(tǒng)預(yù)先下載并緩存到 Cache Storage 中去:
// sw.js self.oninstall = (e) => {e.waitUntil(caches.open('installation').then(cache => cache.addAll(['./','./styles.css','./script.js']))) });這樣,當用戶離線,網(wǎng)絡(luò)無法訪問時,我們就可以從緩存中啟動我們的 web 應(yīng)用:
//sw.js self.onfetch = (e) => {const fetched = fetch(e.request)const cached = caches.match(e.request)e.respondWith(fetched.catch(_ => cached)) }可以看出,Service Worker 被設(shè)計為一個相對底層(low-level)、高度可編程、子概念眾多,也因此異常靈活且強大的 API,故本文只能展示它的冰山一角。出于安全考慮,注冊 Service Worker 要求你的 web 應(yīng)用部署于 HTTPS 協(xié)議下,以免利用 Service Worker 的中間人攻擊。筆者在今年 GDG 北京的 DevFest 上分享了?Service Worker 101,涵蓋了 Service Worker 譬如「網(wǎng)絡(luò)優(yōu)先」、「緩存優(yōu)先」、「網(wǎng)絡(luò)與緩存比賽」這些更復(fù)雜的緩存策略、學(xué)習(xí)資料、以及示例代碼,可以供大家參考。
Service Worker 的一種緩存策略:讓網(wǎng)絡(luò)請求與讀取緩存比賽
你也可以嘗試在支持 PWA 的瀏覽器中訪問筆者的博客?Hux Blog,感受 Service Worker 的實際效果:所有訪問過的頁面都會被緩存并允許在離線環(huán)境下繼續(xù)訪問,所有未訪問過的頁面則會在離線環(huán)境下展示一個自定義的離線頁面。
在筆者看來,Service Worker 對 PWA 的重要性相當于?XMLHTTPRequest?之于 Ajax,媒體查詢(Media Query)之于響應(yīng)式設(shè)計,是支撐 PWA 作為「下一代 web 應(yīng)用模型」的最核心技術(shù)。由于 Service Worker 可以與包括 Indexed DB、Streams 在內(nèi)的大部分 DOM 無關(guān) API 進行交互,它的潛力簡直無可限量。筆者幾乎可以斷言,Service Worker 將在未來十年里成為 web 客戶端技術(shù)工程化的兵家必爭之地,帶來「離線優(yōu)先(Offline-first)」的架構(gòu)革命。
Push Notification
PWA 推送通知中的「推送」與「通知」,其實使用的是兩個不同但又相得益彰的 API:
Notification API?相信大家并不陌生,它負責所有與通知本身相關(guān)的機制,比如通知的權(quán)限管理、向操作系統(tǒng)發(fā)起通知、通知的類型與音效,以及提供通知被點擊或關(guān)閉時的回調(diào)等等,目前國內(nèi)外的各大網(wǎng)站(尤其在桌面端)都有一定的使用。Notification API 最早應(yīng)該是在?2010?年前后由 Chromium 提出草案以?webkitNotifications?前綴方式實現(xiàn);隨著 2011 年進入標準化;2012 年在 Safari 6(Mac OSX 10.8+)上獲得支持;2015 年 Notification API 成為?W3C Recommendation;2016 年?Edge 的支持;Web Notifications 已經(jīng)在桌面瀏覽器中獲得了全面支持(Chrome、Edge、Firefox、Opera、Safari)的成就。
Push API?的出現(xiàn)則讓推送服務(wù)具備了向 web 應(yīng)用推送消息的能力,它定義了 web 應(yīng)用如何向推送服務(wù)發(fā)起訂閱、如何響應(yīng)推送消息,以及 web 應(yīng)用、應(yīng)用服務(wù)器與推送服務(wù)之間的鑒權(quán)與加密機制;由于 Push API 并不依賴 web 應(yīng)用與瀏覽器 UI 存活,所以即使是在 web 應(yīng)用與瀏覽器未被用戶打開的時候,也可以通過后臺進程接受推送消息并調(diào)用 Notification API 向用戶發(fā)出通知。值得一提的是,Mac OSX 10.9 Mavericks 與 Safari 7 在 2013 年就發(fā)布了自己的私有推送支持,基于 APNS 的?Safari Push Notifications。
在 PWA 中,我們利用 Service Worker 的后臺計算能力結(jié)合 Push API 對推送事件進行響應(yīng),并通過 Notification API 實現(xiàn)通知的發(fā)出與處理:
// sw.js self.addEventListener('push', event => {event.waitUntil(// Process the event and display a notification.self.registration.showNotification("Hey!")); });self.addEventListener('notificationclick', event => { // Do something with the event event.notification.close(); });self.addEventListener('notificationclose', event => { // Do something with the event });對于 Push Notification,筆者的幾次分享中一直都提的稍微少一些,一是因為 Push API 還處于 Editor Draft 的狀態(tài),二是目前瀏覽器與推送服務(wù)間的協(xié)議支持還不夠成熟:Chrome(與其它基于 Blink 的瀏覽器)在 Chromium 52 之前只支持基于 Google 私有的 GCM/FCM 服務(wù)進行通知推送。不過好消息是,繼 Firefox 44 之后,Chrome 52 與 Opera 39 也緊追其后實現(xiàn)了正在由 IETF 進行標準化的?Web 推送協(xié)議(Web Push Protocol)。
如果你已經(jīng)在使用 Google 的云服務(wù)(比如 Firebase),并且主要面向的是海外用戶,那么在 web 應(yīng)用上支持基于 GCM/FCM 的推送通知并不是一件費力的事情,筆者推薦你閱讀一下 Google Developers 的系列文章,很多國外公司已經(jīng)玩起來了。
從 Hybrid 到 PWA,從封閉到開放
2008 年,當移動時代來臨,唱衰移動 Web 的聲音開始出現(xiàn),而瀏覽器的進化并不能跟上時,來自 Nitobi 的 Brian Leroux 等人創(chuàng)造了?Phonegap,希望它能以 Polyfill 的形式、彌補目前瀏覽器與移動設(shè)備間的「鴻溝」,從此開啟了混合應(yīng)用(Hybrid Apps)的時代。
幾年間,Adobe AIR、Windows Runtime Apps、Chrome Apps、Firefox OS、WebOS、Cordova/Phonegap、Electron?以及國內(nèi)比如微信、淘寶,無數(shù)的 Hybrid 方案拔地而起,讓 web 開發(fā)者可以在繼續(xù)使用 web 客戶端技術(shù)的同時,做到一些只有原生應(yīng)用才能做到的事情,包括訪問一些設(shè)備與操作系統(tǒng) API,給用戶帶來更加 「Appy」 的體驗,以及進入 App Store 等等。
眾多的 Hybrid 方案
PWA 作為一個涵蓋性術(shù)語,與過往的這些或多或少通過私有平臺 API 增強 web 應(yīng)用的嘗試最大的不同,在于構(gòu)成 PWA 的每一項基本技術(shù),都已經(jīng)或正在被 IETF、ECMA、W3C 或 WHATWG 標準化,不出意外的話,它們都將被納入開放 web 標準,并在不遠的將來得到所有瀏覽器與全平臺的支持。我們終于可以逃出 App Store 封閉的秘密花園,重新回到屬于 web 的那片開放自由的大地。
有趣的是,從上文中你也可以發(fā)現(xiàn),組成 PWA 的各項技術(shù)的草案正是由上述各種私有方案背后的瀏覽器廠商或開發(fā)者直接貢獻或間接影響的。可以說,PWA 的背后并不是某一家或兩家公司,而是整個 web 社區(qū)與整個 web 規(guī)范。正是因為這種開放與去中心化的力量,使得萬維網(wǎng)(World Wide Web)能夠成為當今世界上跨平臺能力最強、且?guī)缀跏俏ㄒ灰粋€具備這種跨平臺能力的應(yīng)用平臺。
「我們相信 Web,是因為相信它是解決設(shè)備差異化的終極方案;我們相信,當 Web 在今天做不到一件事的時候,是因為它還沒來得及去實現(xiàn),而不是因為他做不到。而 Phonegap,它的終極目的就是消失在 Web 標準的背后。」
在不丟失 web 的開放靈魂,在不需要依靠 Hybrid 把應(yīng)用放在 App Store 的前提下,讓 web 應(yīng)用能夠漸進式地跳脫出瀏覽器的標簽,變成用戶眼中的 App。這是 Alex Russell 在 2015 年提出 PWA 概念的原委。
而又正因為 web 是一個整體,PWA 可以利用的技術(shù)遠不止上述的幾個而已:Ajax、響應(yīng)式設(shè)計、JavaScript 框架、ECMAScript Next、CSS Next、Houdini、Indexed DB、Device APIs、Web Bluetooth、Web Socket、Web Payment、孵化中的?Background Sync API、Streams、WebVR……開放 Web 世界 27 年來的發(fā)展以及未來的一切,都與 PWA 天作之合。
魚與熊掌的兼得
經(jīng)過幾年來的摸索,整個互聯(lián)網(wǎng)行業(yè)仿佛在「Web 應(yīng)用 vs. 原生應(yīng)用」這個問題上達成了共識:
- web 應(yīng)用是魚:迭代快,獲取用戶成本低;跨平臺強體驗弱,開發(fā)成本低。適合拉新。
- 原生應(yīng)用是熊掌:迭代慢,獲取用戶成本高;跨平臺弱體驗強,開發(fā)成本高。適合保活。
要知道,雖然用戶花在原生應(yīng)用上的時間要明顯多于 web 應(yīng)用,但其中有 80% 的時間是花在前五個應(yīng)用中的。調(diào)查顯示,美國有一半的智能手機用戶平均每月新 App 安裝量為零,而月均網(wǎng)站訪問量卻有 100 個,更別提 Google Play 上有 60% 的應(yīng)用從未被人下載過了。于是,整個行業(yè)的產(chǎn)品策略清一色地「拿魚換熊掌」,比如筆者的老東家阿里旅行(飛豬旅行),web 應(yīng)用布滿阿里系各種渠道,提供「優(yōu)秀的第一手體驗」,等你用的開心了,再引誘你去下載安裝原生應(yīng)用。
原生應(yīng)用、當代 Web 與 PWA 圖片來源: Hux &?Google
但是,PWA 的出現(xiàn),讓魚與熊掌兼得變成了可能 —— 它同時具備了 web 應(yīng)用與原生應(yīng)用的優(yōu)點,有著自己獨有的先進性:「瀏覽器 -> 添加至主屏/安裝 -> 具備原生應(yīng)用體驗的 PWA -> 推送通知 -> 具備原生應(yīng)用體驗的 PWA」,PWA 自身就包含著從拉新到保活的閉環(huán)。
除此之外,PWA 還繼承了 web 應(yīng)用的另外兩大優(yōu)點:無需先付出幾十兆的下載安裝成本即可開始使用,以及不需要經(jīng)過應(yīng)用超市審核就可以發(fā)布新版本。所以,PWA 可以稱得上是一種「流式應(yīng)用(Streamable App)」與「常青應(yīng)用(Evergreen App)」
未來到來了嗎
在筆者分享 PWA 的經(jīng)歷中,最不愿意回答的兩個問題莫過于「PWA 已經(jīng)被廣泛支持了嗎?」以及「PWA 與 ABCDEFG 這些技術(shù)方案相比有什么優(yōu)劣?」,但是這確實是兩個逃不開的問題。
PWA 的支持情況?
當我們說到 PWA 是否被支持時,其實我們在說的是 PWA 背后的幾個關(guān)鍵技術(shù)都得到支持了沒有。以瀏覽器內(nèi)核來劃分的話,Blink(Chrome、Oprea、Samsung Internet 等)與 Gecko(Firefox)都已經(jīng)實現(xiàn)了 PWA 所需的所有關(guān)鍵技術(shù)(
總結(jié)
以上是生活随笔為你收集整理的下一代 Web 应用模型 —— Progressive Web App (PWA)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 14个你可能不知道的JavaScript
- 下一篇: vue 组件 - 非单文件组件