PWA技術及其用戶體驗設計
摘要:serviceWorker使得網頁在速度跟體驗上接近原生app,除此之外,還需要引導用戶添加pwa應用到桌面,以方便下次使用。console.log('[Service Worker] Caching all: app shell and content')。
實驗室最近多了一個實驗產品 MAX :羣控手機的項目。主要包括:後端服務、web前端客戶端、安卓app客戶端。涉及到的編程語言:Java、Nodejs。技術上主要涉及安卓的MediaProjection API、配合websocket來實現。
MediaProjection 提供了錄屏功能; websocket 主要是傳輸方便,可以做到實時。
今天主要介紹下web前端客戶端的實現,主要使用了PWA技術。
- 什麼是PWA?
PWA全稱Progressive Web Apps , 漸進增強 Web 應用程序 ,它可以離線運行,並且可以在運行的系統中選擇性安裝,它從外觀還是執行效果來看,與一般應用程序無異。
不知大家體驗過微軟的郵件服務沒?Outlook.com已經完成了 PWA 版本,可以在瀏覽器裏面像本地應用一樣直接打開即用。
比如我使用的mac,添加了一個PWA應用之後,底部菜單欄多了一個應用的icon,效果如下:
就是mixlab那個logo
PWA是一系列技術的集合,裏面最核心的是一個叫“app shell”的概念。
- 什麼是App shell?
我們先了解下,渲染網站主要有兩種方法:在服務器上或在客戶端上。
-服務器端渲染(SSR)
意味着網站每次都是在服務器上渲染,因此它提供了更快的首次加載,但是在頁面之間跳轉需要每次都下載所有內容,因而它的加載速度往往會比較慢。
-客戶端渲染(CSR)
頁面是在客戶端(瀏覽器)渲染的,因而加載速度往往取決於瀏覽器的性能,訪問速度會比較快,但是在開始時需要更多的初始下載(首次訪問時網站速度較慢),以保證整個網站其他頁面實現客戶端渲染所需要的數據。
兩種方式各有利弊,而PWA使用的方法是“app shell”,它混合了SSR和CSR的方式。
App shell,可以理解爲程序的外殼 。App shell意圖儘快加載最小的用戶界面,然後緩存它,以便在後續訪問時可以離線使用,然後加載應用程序的所有內容。這樣,下次有人從設備訪問應用程序時,UI立即從緩存加載,並從服務器請求新內容(如果它已在緩存中不可用)。
一個App shell的代碼結構如下:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title>Max</title>
<meta name="description" content="app的介紹">
<meta name="author" content="作者">
<meta name="theme-color" content="#B12A34">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta property="og:image" content="icons/icon-512.png">
<link rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" href="style.css">
<link rel="manifest" href="manifest.json">
<script src="app.js" defer></script>
</head>
<body>
<header>
<p>MAX-demo</p>
</header>
<main>
<h1>HELLO WORLD</h1>
<button id="notifications">Request notifications</button>
<section id="content">
// Content inserted in here
</section>
</main>
<footer>
<p>© max 2012-2018, created and maintained by shadow.</p>
</footer>
</body>
</html>
爲了配合app shell,需要一個叫Service Worker API的支持。
- Service Worker
Service Worker API可以完成2種任務,一種是緩存App shell所需的數據,另一種是如果你有比較耗時的計算,你可以把它們從主線程中抽離出來,在Service Worker中進行計算,最後在它們計算完畢的時候從Service Worker中取得計算結果。
Service Worker主要由3項技術構成:
-
緩存機制是依賴 Cache API 實現的
-
依賴 HTML5 fetch API 發起網絡請求
-
依賴 Promise 實現異步
service worker是需要註冊的,我們在app.js中,輸入:
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/serviceWorker.js', { scope: '/' })
.then(function(registration) {
// 註冊成功
console.log('ServiceWorker registration successful with scope: ', registration.scope);
})
.catch(function(err) {
// 註冊失敗
console.log('ServiceWorker registration failed: ', err);
});
});
};
即可,使用上我們編寫好的serviceWorker.js文件。
serviceWorker.js主要對有install跟fetch事件進行監聽,對cache進行操作,達到緩存的目的。
let cacheName = 'max-v1';
let contentToCache = [
'/',
'/index.html',
'/style.css',
'/app.js'
];
// 對app shell和主體內容(content)裏面的數據創建緩存
self.addEventListener('install', function(e) {
console.log('[Service Worker] Install');
e.waitUntil(
// 安裝成功後操作 CacheStorage 緩存,使用之前需要先通過 caches.open() 打開對應緩存空間。
caches.open(cacheName).then(function(cache) {
console.log('[Service Worker] Caching all: app shell and content');
// 通過 cache 緩存對象的 addAll 方法添加 緩存
return cache.addAll(contentToCache);
})
);
});
//如果條件允許,service worker將從緩存中請求content中所需的數據,從而提供離線應用功能
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;
});
});
})
);
});
兩種方式可以比較一下:
- install
優點是第二次訪問即可離線,缺點是需要將需要緩存的 URL 在編譯時插入到腳本中,增加代碼量和降低可維護性;
- fetch
優點是無需更改編譯過程,也不會產生額外的流量,缺點是需要訪問過一次才能離線使用。
因此,在設計技術架構的時候,需要考慮到2種方式的優缺點。
除了配置serviceWorker.js之外,我們還需要配置manifest.json文件。
- 添加至桌面功能
serviceWorker使得網頁在速度跟體驗上接近原生app,除此之外,還需要引導用戶添加pwa應用到桌面,以方便下次使用。
實現 PWA 應用添加至桌面的功能,除了要求站點支持 HTTPS 之外,需要準備 manifest.json 文件去配置應用的圖標、名稱等信息。一個基本的 manifest.json 應包含如下信息:
{
"name": "max-demo-v1",
"short_name": "max",
"description": "demo",
"icons": [{
"src": "icons/mix-logo.png",
"sizes": "72x72 96x96 128x128 256x256",
"type": "image/png"
}],
"start_url": "/index.html",
"display": "fullscreen",
"theme_color": "#4a4a4a",
"background_color": "#eeeeee"
}
運行之後,在瀏覽器地址欄右側,可以看到一個+號,點擊安裝。
另外, 調試可以在chrome的Application面板中進行查看 。
由於PWA的api不是所有瀏覽器都支持,因而,你還需要注意使用 caniuse.com 來查看主流瀏覽器的支持情況。
- 如何告知普通用戶什麼是離線模式?或者什麼是PWA?
這是體驗設計上需要注意的地方,我們應該認識到並不是每個用戶都是技術出身,都對PWA的概念瞭解得很清楚 。 因而,用戶體驗設計需要爲用戶提供指導,以便他們可以瞭解什麼是PWA(或者離線模式)。
確實,離線模式比PWA(漸進式)更爲容易理解,但是離線模式對每個人來說都是一個全新的心智模式。 通俗來講,您需要告訴用戶當他們無法連接上網絡時會發生什麼變化。 比如:
哪些功能無法使用;
或者是頁面上的數據是什麼時間更新的;
目前的網絡連接情況;
等等。
除此之外,設計上要考慮首次加載的問題 ,如首次加載時間過長,需要設計動畫提示,可以把加載的文件內容簡要告知用戶,讓用戶知道網頁正在加載,而不是“死機了”。
下一步,擬集成TensorFlowJS,探索下可能性。
近期推薦:
目前《人工智能Mix》專欄已積累了上百篇資料,都是AI+各種領域的應用,涉及技術、設計等。穩步保持日更,歡迎加入,365天都在學習~
加入社羣
歡迎交流