小蘿蔔(滬江前端開發工程師)
本文原創翻譯,有不當的地方歡迎指出。轉載請指明出處。前端
若是你在過去幾個月一直關注web開發社區,你極可能已經閱讀了 progressive web apps,下面簡稱PWAs (中文有譯做漸進式web應用).它是一個術語,統稱那些擁有離線支持, 可安裝,「Retina」,滿屏顯示,個性化支持,流暢的瀏覽效果,推送通知和強大的UI等能夠和原生媲美的web應用。git
這是一些谷歌Progressive Web APPs示範
雖然當你網站一加載,Service Work API就會幫你緩存全部網站資源,但就像你初次見一我的第一眼印象很重要,最新DoubleClick study的數據代表,若是首次加載花費的時間超過3秒,超過53%的用戶會離開。web
3秒,在現實中是一個很是殘酷的目標。移動端鏈接,平均有300毫秒的延遲,還受制於帶寬、弱信號,因此實際上你只有不到1秒的時間去下載你app所須要初始化所須要的資源。shell
以上顯示了用戶請求的延時後端
固然,咱們有辦法去減小首次加載的時間,好比服務端預渲染基本佈局、按需懶加載等等,可是咱們能作到的是有限的,還必須專門有我的去作性能優化。因此,既要迅速加載又要有原生的體驗,咱們該怎樣作?
AMP, For Accelerated Mobile Pages瀏覽器
網站一個巨大的優點在於無摩擦的入口——它不須要安裝,用戶老是隻需點擊一下便可當即加載。安全
爲了享受這麼輕鬆、瞬間的瀏覽體驗,你全部要作的是讓你的網站跑的飛快,可是如何讓你的網站跑到飛快?咱們能夠適當的減小開銷,沒有兆級別容量的圖片,沒有阻塞渲染的廣告,不超過10萬行的js代碼,全部的只是純內容的展現。性能優化
Accelerated Mobile Pages, 簡稱AMPs, 就很是擅長作這些,事實這也是它們的宗旨。經過它精心設計的規則能保證優先顯示頁面的主要內容。經過建立要嚴格的靜態佈局,它能使平臺像google Search經過首屏預加載達到瞬間加載的效果。
https://www.ampproject.org/
https://www.ampproject.org/le...
https://www.ampproject.org/le...
這個AMP 的hero image 和 headline會預加載, 以保證用戶能夠立馬看到它
AMP 仍是 PWA?
爲了快速加載你引入了AMP, 但你引入AMP的同時你不少功能會受限。AMP並不適用一些高級的功能 好比通知推送,網頁支付或者一切須要引入其它js的功能。以及由於AMP的頁面是受AMP Cache控制的,你享受不到PWA的的優點,由於你本身的Service Worker不能運行。另外一方面PWA並不能像AMP在第一次加載那麼快,而且能安全且容易的嵌入。
因此AMP仍是漸進式的app?是一次性加載仍是選擇性的加載,是最新的平臺特性仍是輕巧的應用代碼?咱們是否是有可能結合二者,綜合兩個的好處?
PWAMP 結合模式
你能夠經過如下方式結合AMPs和progressive web apps
AMP AS PWA
當你能接受AMP的侷限性
AMP TO PWA
當你但願在二者之間無縫過分
AMP IN PWA
當你但願AMP做爲一個資源在你的PWA裏面可複用, 如今讓咱們來單獨的談談它們。
不少網站在AMPs範圍不須要別的功能。例如,Amp by Example既是一個AMP APP,也是PWA APP。
它有一個service worker,所以它容許離線訪問等。
它有一個manifest,因此支持「添加到主屏幕」。
當用戶在google search頁面點擊Amp by Example,而後點擊該網站上的另外一個連接時,他們將脫離AMP Cache去遠程拉數據。網站仍然使用AMP庫,固然,可是由於它依賴遠程,因此它可使用service worker,而後安裝及激活等等。
你可使用此技術讓你的AMP網站支持離線訪問,而後在線時及時更新你的網頁,由於在線時您能夠經過service workor的fetch事件修改響應,返回你想要返回的內容:
若是上面的不能知足你,你須要非凡的PWA體驗圍繞你的內容,這是你能夠考慮爲高級的模式
全部的內容子頁面(那些指定的內容,不是全局的頁面)做爲AMP發佈,享受當即加載
這些AMP頁面用AMP特定的元素<amp-install-serviceworker>在用戶閱讀你內容的時候爲緩存和PWA腳本作準備
當用戶點擊你網站的另一個連接(好比喚起相似原生app的操做),這時候service worker截取請求,接管頁面控制權加載PWA腳本
你能夠實施這三部,若是你熟悉Service Works的是怎樣運行的(若是你不熟悉,我強烈推薦你閱讀我同事 Jake’s Udacity 的課程)。
首先在你全部AMP引入入Service Worker.
第二步, 在Service Worker安裝事件中,緩存PWA須要的全部數據
最後, 仍是在Service Worker裏面, 用返回PWA取代原有的AMP導航請求
(下面的代碼只是爲了展現原理因此簡化了,高級的例子在最後的Demo裏)
如今,當用戶在你從AMP Cache返回的頁面裏面點擊一個連接,Service Worker會註冊這個navigate 請求而後接管, 變成一個徹底成型的已經緩存的PWA。
這個技術有意思的在於它是漸進加強的從AMP轉變成PWA. 這也意味着,若是你的瀏覽器不支持Service Worker,它將不會被導航到PWA, 而是AMP跳AMP
AMP經過shell url rewriting實現這種漸進加強。經過在<amp-install-serviceworker>添加一個回調屬性, 若是檢測到不支持Service Worker,AMP會用shell Url重寫全部匹配全部鏈接,全部的後續的點擊再也不會導航到PWA.
在此模式中,用戶已經在一個漸進式的app裏面了,你正好用AJAX獲取獲取數據,可是你的真實需求是獲得兩種後端返回的數據,一種是AMP內容,另外一種是你Progressive Web App所須要的JSON格式數據。
固然,一種簡單方式是在iframes裏面加載 AMP內容。可是iframe比較慢,並且你須要一次又一次從新編譯和從新初始化AMP Library。今天cutting-edge 技術提供一個更好的辦法: shadow-dom
AMP 能夠安全的被嵌入其餘網站, mp liabrary在整個PWA只會被編譯和加載一次。
PWA劫持任何導航點擊
而後它發一個XMLHttpRequest 去fetch AMP頁面
拉到後它把內容放到一個新的shadow root
而後它通知 main AMP Library, 「這裏有個新的document,請檢查」(運行的時候叫 attachShadowDoc)
用這個技術,AMP Library在PWA只編譯和加載一次,它會響應每一個你綁定的shadow document。而且由於你是經過XMLHttpRequests去fetch頁面,你能夠在插入到新的 shadow document以前更改AMP 資源。打個比方你能夠用來:
過濾掉不須要的信息,好比headers 和footers
插入額外的內容, 好比廣告和工具
用更動態的內容替換某些內容
如今你把你的漸進式Web APP變得稍微複雜點了,你能夠減輕後端的複雜度。
爲了闡述 shadow dom的這個方法(PWA包含AMP),AMP團隊已經制做了React-based demo called The Scenic, ---- 一個虛擬的旅遊雜誌.
這個Demo在GitHub
咱們看看 Mic’s new PWA(in beta)這個以及上線的例子: 若是你強刷任意一個頁面(會暫時忽略Service Worker),而後你看你請求返回的結果,你會發現是AMP頁面資源。如今你單價「hamburger menu」: 它會從新加載當前頁面,然而由於<amp-install-serviceworker>已經加載在PWA app shell, 這個從新加載幾乎是瞬間的,菜單在刷新後打開,看上去好像根本沒有刷新過。
我對這種新的結合方式很興奮,這種結合帶來了它們各自的好處, 再強調下:
老是很快
內置大型分佈(經過AMP平臺套件)漸進式加強
一種後端返回規則
減小客戶端的複雜程度
更少的總體投入
可是咱們只是探索了不一樣方式的差別,打造2016年及將來的最好的Web體驗還仍需努力,爲開闢Web新篇章繼續前行。
iKcamp原創新書《移動Web前端高效開發實戰》已在亞馬遜、京東、噹噹開售。