漸進式 Web 應用(PWA)
- 運用現代的 Web API 以及傳統的漸進式加強策略來建立跨平臺 Web 應用程序。
PWA 的優點
- 可被發現
- 易安裝
- manifest(https://developer.mozilla.org/zh-CN/docs/Web/Manifest)
- 可連接(經過url訪問應用)
- 獨立於網絡
- Service Workers(https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API)
- Cache API(https://developer.mozilla.org/zh-CN/docs/Web/API/Cache)
- Web Storage and IndexedDB
- 漸進式(新功能不被舊瀏覽器支持,退而求其次)
- 可重用(通知)
- Push API(https://developer.mozilla.org/zh-CN/docs/Web/API/Push_API)
- Notifications API(https://developer.mozilla.org/zh-CN/docs/Web/API/Notifications_API)
- 響應性(自適應全部終端)
- 安全的(原生應用用戶不容易察覺僞造的應用)
PWA 介紹
- 桌面和移動設備上的全部主流瀏覽器都支持 service worker。
- Web App Manifest(安裝),Push(通知接收),Notifications(通知顯示)和 Add to Home Screen(添加到屏幕) 功能也獲得了普遍的支持。
- 目前,Safari 對 Web App Manifest 和 Add to Home Screen 的支持有限,而且不支持 Web 推送通知。
- 應該遵循漸進加強規則 - 僅在支持它們的狀況下使用提供此類加強功能的技術
PWA 結構
- 最流行的方法是「app shell」概念,它徹底按照上述方式混合SSR(服務端渲染)和CSR(瀏覽器端渲染),此外還遵循「離線優先」方法
- 一種涉及Streams API(流)的新方法
App shell
- App shell意圖儘快加載最小的用戶界面,而後緩存它,以便在後續訪問時能夠離線使用,而後加載應用程序的全部內容。
- 經過service worker控制從服務器請求的內容以及從緩存中檢索的內容
- 響應式網頁設計也適用於漸進式網絡應用程序,使用 viewport meta tag,CSS media queries,Flexbox,和 CSS Grid 等技術。
- viewport meta tag:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
meta標籤
- CSS media queries:
@media (max-width: 600px) {
css媒體查詢
- Flexbox:彈性盒子佈局
- CSS Grid:CSS 網格佈局
Streams API(實驗功能)
- 流將你但願經過網絡接收的資源拆分紅小塊,而後按位處理它。
- 瀏覽器在接收用於顯示web頁面的資源時就是這麼處理的,例如:視頻緩衝區和更多的內容能夠逐漸播放,有時候隨着內容的加載,你能夠看到圖像逐漸地顯示。
- Streams API出現之前,流對於JavaScript是不可用的。之前,若是咱們想要處理某種資源(如視頻、文本文件等),咱們必須下載完整的文件,等待它反序列化成適當的格式,而後在完整地接收到全部的內容後再進行處理。
- It provides fine-grained control — the stream can be started, chained with another stream, cancelled, checked for errors, and more.(它提供了細粒度的控制——流能夠啓動、與另外一個流連接、取消、檢查錯誤等等。)
Structure of our example application(示例)
經過 Service workers 讓 PWA 離線工做
Service workers 解釋
- Service Workers是瀏覽器和網絡之間的虛擬代理。解決了如何正確緩存網站資源並使其在用戶設備離線時可用。
- 運行在一個與咱們頁面的 JavaScript 主線程獨立的線程上
- 對 DOM 結構沒有任何訪問權限
- 能夠在不一樣的上下文之間發送和接收信息
- 不單單提供離線功能,還提供包括處理通知,在單獨的線程上執行繁重的計算等
- 能夠控制網絡請求,修改網絡請求,返回緩存的自定義響應,或合成響應。
- 其內的 API 都是非阻塞(異步的)
安全
- Service Workers 只能在安全的上下文中執行(即 HTTPS )
- 若是您想在將代碼推送到生產環境以前先進行實驗,則能夠始終在本地主機上進行測試或設置 GitHub 頁面 - 二者都支持HTTPS。
離線優先
PWA 漸進加強
js13kPWA應用程序中的 Service workers
註冊 Service Worker
- 注意這裏是navigator下的一個方法,用來註冊 Service Worker
if('serviceWorker' in navigator) {
navigator.serviceWorker.register('/pwa-examples/js13kpwa/sw.js');
};
Service Worker 的聲明週期
- 註冊完成後,sw.js 文件會自動下載,而後安裝,最後激活。
安裝
- In the install listener, we can initialize the cache and add files to it for offline use. Our js13kPWA app does exactly that.(在安裝偵聽器中,咱們能夠初始化緩存並向其中添加文件以供脫機使用。)
- The service worker does not install until the code inside waitUntil is executed. It returns a promise(在執行e.waitUntil內的代碼前,service worker 不會被安裝?它會返回一個 promise)
- caches is a special CacheStorage object available in the scope of the given Service Worker to enable saving data(caches 是一個CacheStorage 對象,用於保存數據,它是異步的)
- we open a cache with a given name, then add all the files our app uses to the cache, so they are available next time it loads (identified by request URL).(經過給定名稱cacheName區分不一樣緩存庫,經過請求URL標識不一樣緩存)
var cacheName = 'js13kPWA-v1';
var appShellFiles = [
'/pwa-examples/js13kpwa/',
'/pwa-examples/js13kpwa/index.html',
'/pwa-examples/js13kpwa/app.js',
'/pwa-examples/js13kpwa/style.css',
'/pwa-examples/js13kpwa/fonts/graduate.eot',
'/pwa-examples/js13kpwa/fonts/graduate.ttf',
'/pwa-examples/js13kpwa/fonts/graduate.woff',
'/pwa-examples/js13kpwa/favicon.ico',
'/pwa-examples/js13kpwa/img/js13kgames.png',
'/pwa-examples/js13kpwa/img/bg.png',
'/pwa-examples/js13kpwa/icons/icon-32.png',
'/pwa-examples/js13kpwa/icons/icon-64.png',
'/pwa-examples/js13kpwa/icons/icon-96.png',
'/pwa-examples/js13kpwa/icons/icon-128.png',
'/pwa-examples/js13kpwa/icons/icon-168.png',
'/pwa-examples/js13kpwa/icons/icon-192.png',
'/pwa-examples/js13kpwa/icons/icon-256.png',
'/pwa-examples/js13kpwa/icons/icon-512.png'
];
self.addEventListener('install', function(e) {
console.log('[Service Worker] Install');
e.waitUntil(
caches.open(cacheName).then(function(cache) {
console.log('[Service Worker] Caching all: app shell and content');
return cache.addAll(contentToCache);
})
);
});
Activation(激活)
- There is also an activate event, which is used in the same way as install. (還有一個activate事件,與install的使用方式相同。)
- This event is usually used to delete any files that are no longer necessary and clean up after the app in general. (此事件一般用於刪除再也不須要的任何文件,並在應用程序運行後進行清理。)
Responding to fetches 處理請求和緩存響應
- We also have a fetch event at our disposal, which fires every time an HTTP request is fired off from our app. (有一個fetch事件供咱們使用,它在每次從咱們的應用程序發出HTTP請求時都會觸發。)
- The response can be anything we want: the requested file, its cached copy, or a piece of JavaScript code that will do something specific(響應能夠是咱們想要的任何東西:請求的文件、其緩存副本或一段能夠執行特定操做的javascript代碼。)
- The FetchEvent.respondWith method takes over control — this is the part that functions as a proxy server between the app and the network. (FetchEvent.respondWith接管了請求的控制權,這應用程序和服務器間充當代理服務器)
self.addEventListener('fetch', function(e) {
e.respondWith(
caches.match(e.request).then(function(r) {
console.log('[Service Worker] Fetching resource: '+e.request.url);
return r || fetch(e.request).then(function(response) {
return caches.open(cacheName).then(function(cache) {
console.log('[Service Worker] Caching new resource: '+e.request.url);
cache.put(e.request, response.clone());
return response;
});
});
})
);
});
Updates(升級)
- how do you upgrade a Service Worker when a new version of the app containing new assets is available? The version number in the cache name is key to this:(經過修改cacheName來升級緩存庫,建議緩存庫名附帶版本號來區分)
- When this updates to v2, we can then add all of our files (including our new files) to a new cache:(把舊版本的緩存寫入新緩存)
- the available cache space in the browser is limited, so it is a good idea to clean up after ourselves.(瀏覽器中可用的緩存空間有限,所以最好本身清理。)
var cacheName = 'js13kPWA-v1';
Clearing the cache(清空緩存庫)
self.addEventListener('activate', function(e) {
e.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if(cacheName.indexOf(key) === -1) {
return caches.delete(key);
}
}));
})
);
});
Other use cases(其餘示例)
- Performance-wise, you can prefetch resources that are not needed right now, but might be in the near future, so the app will be faster when you actually need those resources.(能夠用來預加載數據)
Summary(總結)
- Service Workers are also used when dealing with push notifications(處理推送通知時也使用 Service Workers)
How to make PWAs installable(使PWA可安裝)
Requirements(可安裝的條件)
- To make the website installable, it needs the following things in place:(條件)
- The website to be served from a secure (HTTPS) domain(從安全(https)域提供服務的網站)
- A service worker registered, to make the app work offline (this is required only by Chrome for Android currently)(安卓下的谷歌瀏覽器須要service worker被註冊才支持安裝到桌面)
The manifest file