整理 | 包包
前端技術這幾年發展迅速,其中就有PWA,全名Progressive Web APP即漸進式Web應用程序,在2016年,Google I/O 大會上提出的一個 Next Web Generation 概念。PWA是專門應對手機web開發提出來的,它可以將 web 和 app 各自優勢結合到一起:漸進式、離線加載等實現趨近于App的交互,實時更新、可推送、可安裝等,達到一個當我們使用Web應用時體驗可以像一款原生App一樣。特別說明一下,很多人以為PWA是一種新技術,然而并不是,它是應用多項Web技術的一個集合,其中核心技術即 “Service Worker”,我們把它放在后面說。
目前我們使用Web應用和很多國內SPA一樣,通常都是在打開一個頁面的時候發起請求來獲取數據,在離線的情況一般就不可用了。而PWA是旨在改善Web的體驗,將網絡的優勢與應用的優勢融合起來,給用戶更優的體驗。PWA具有的特點分別是:
可靠即使在不穩定的網絡環境下(包括無網絡的情況),也可以立即加載并展現。
響應快速用戶交互響應迅速,有平滑流暢的動畫進行響應。
粘性像設備上原生應用一樣,具有逼真的用戶體驗,同時用戶還可以將其添加到桌面。
漸進式適用于使用任何瀏覽器的用戶,因為它的核心是以漸進式增強。
自適應任何形式上都可使用:桌面設備、移動設備等。
安全通過HTTPS,防止窺探以及保障內容不會被篡改。
可發現因為W3C清單和服務工作注冊范圍,可以讓搜索引擎找到它,將其識別為“應用程序”。
可安裝用戶再去app store去下載,可以直接將應用添加到主屏幕從而保留進行使用。
可鏈接可以通過url地址分享應用程序,省去了復雜的安裝。
我們在其中選擇幾點著重解釋一下:
(1)可安裝
它是指在設備的主屏幕上像原生APP一樣留有圖標。要實現這特點首先需要提供Web app manifest(web應用程序清單),manifest是一個json文件,它里面描述的是應用程序的圖標如何在主屏幕顯示以及點擊后跳轉到的頁面是什么,我們可以直接在html中引用它“”,它的格式如下圖:
其中幾個屬性代表的意思是:
? start_url 設置跳轉的地址
? icons 讓我們設置頁面的圖標
? background_color 設置背景顏色, 應用啟動后會立即使用此顏色,這一顏色將保留在屏幕上,直至網絡應用首次呈現
? theme_color 會設置主題顏色
? display 設置是否啟動狀態
這里的display設置的是網絡應用是否隱藏瀏覽器的UI,當display的值為"standalone"時,網絡應用隱藏瀏覽器的UI;當display的值為"browser"時,則顯正常顯示。
關于manifest.json里字段更加具體的含義,感興趣的同學可以去谷歌開發者文檔里探索一下啦。
(2)這是一個非常diao的特性:可離線使用即在沒有網絡環境的情況下也能打開應用程序,實現這一強大功能的幕后大佬是:Service worker(服務人員)。
Service worker其實是一段腳本,我們平時緩存都是session、localStorage、CacheStorage這些,PWA通過Service worker訪問CacheStorage實現緩存及離線開發。
這里簡單講一下Service worker的概念,通常瀏覽器加載頁面運行的是主JavaScript線程,而Service worker作為一個獨立的線程,可以理解為在瀏覽器身后默默無聞運行的一個線程。
正因為這個特性,Service worker無論如何都不會阻塞我們的主線程,意味著不會使我們的瀏覽器頁面卡頓等。在使用Service worker時要注意,我們使用的協議必須是https,當然如果想在本地開發弄一個https是很讓人頭疼的,幸運的是Service worker允許在本地host為localhost或者127.0.0.1也可以跑起來。
我們來看一下,如何注冊Service worker?
首先,我們要判斷當前使用的瀏覽器是否支持Service worker,支持我們才能繼續進行下去,如果支持,那么在頁面加載的時候注冊位于/sw.js的Service worker,看下面的代碼:
每次頁面加載成功后,就會調用 register() 方法,瀏覽器將會判斷 Service Worker 線程是否已注冊并做出相應的處理。
register 方法的 scope 參數是可選的,用于指定你想讓 Service Worker 控制的內容的子目錄。本 demo 中服務工作線程文件位于根網域, 這意味著服務工作線程的作用域將是整個來源。
關于Service Worker更加詳細的介紹,感興趣的同學可以參考MDN文檔。
對啦,Service worker也是有生命周期的,它的詳細介紹可以參考下圖:
說了這么多,那我們開發者如何了解一個網頁是否具備了 PWA 的一些特點呢?
我們可以通過谷歌開發工具,在其中找到Audits面板,它可以檢測出頁面是否具備PWA的特點:
下面我們來看一個簡單的demo,看一下PWA在離線時依然能夠快速加載應用。
首先我們將加載loading直接顯示出來,確保用戶在打開網頁可以立即看到,讓用戶知道此時頁面在加載中:
此時我們將html頁面中引用的js的注釋取消,將我們寫的虛假數據加載出來:
那么如何實現緩存呢?即在離線的環境下加載出來數據,此時將網絡環境調成Offline,頁面無法加載:
這里就要應用到上面我們說的Service worker服務工作線程來實現。
先來檢查一下瀏覽器是否支持Service worker:
如果瀏覽器支持,就會注冊服務工作線程,當用戶第一次打開頁面時就會觸發安裝事件從而將緩存所需的內容。
下圖為核心代碼,實現了真正的離線緩存:
首先,我們需要通過 caches.open() 打開緩存并提供一個緩存名稱。提供緩存名稱可讓我們對文件進行版本控制,或將數據與 App Shell 分開,以便我們能輕松地更新某個數據,而不會影響其他數據。
我們在install偵聽器下面添加activate事件偵聽器,因為activate事件會在Service worker啟動時觸發,圖中activate事件里面的代碼可以確保文件更改的時候更新緩存。
最后我們需要從緩存中提取我們需要的內容,就是下面這段代碼:
caches.match() 會由內而外對觸發抓取事件的網絡請求進行評估,并檢查以確認它是否位于緩存內。它隨即使用已緩存版本作出響應,或者利用 fetch 從網絡獲取一個副本,response 通過 e.respondWith() 傳回至網頁。
現在來看一下我們在離線的時候頁面是否會加載呢?
如圖,在Offline的網絡環境下,我們的應用成功加載出來了。
這個小demo就到這里啦!
目前Progressive Web App仍處于初級階段,國內普及度還不夠,但是不可忽視其背后的的技術,以及對前端全新的定位,或許它會像十年前的AJAX那樣重新改變前端的生態。
發布評論請先 登錄
相關推薦
評論