ASP.NET Core Blazor Webassembly 之 渐进式应用(PWA)
Blazor支持漸進式應用開發也就是PWA。使用PWA模式可以使得web應用有原生應用般的體驗。
什么是PWA
PWA應用是指那些使用指定技術和標準模式來開發的web應用,這將同時賦予它們web應用和原生應用的特性。
例如,web應用更加易于發現——相比于安裝應用,訪問一個網站顯然更加容易和迅速,并且你可以通過一個鏈接來分享web應用。
在另一方面,原生應用與操作系統可以更加完美的整合,也因此為用戶提供了無縫的用戶體驗。你可以通過安裝應用使得它在離線的狀態下也可以運行,并且相較于使用瀏覽器訪問,用戶也更喜歡通過點擊主頁上的圖標來訪問它們喜愛的應用。
PWA賦予了我們創建同時擁有以上兩種優勢的應用的能力。
這并不是一個新概念——這樣的想法在過去已經在web平臺上通過許多方法出現了多次。漸進式增強和響應式設計已經可以讓我們構建對移動端友好的網站。在多年以前的Firefox OS的生態系統中離線運行和安裝web應用已經成為了可能。
PWAs, 不但如此,更是提供了所有的甚至是更多的特性,來讓web更加優秀。
引用自MDN
說人話就是PWA可以讓你的web程序跟一般應用一樣運行,有桌面圖標,能離線,沒有瀏覽器地址欄,一切看起來想個普通的程序/APP。
新建Blazor PWA程序
使用VS新建一個Blazor程序,選擇Webassembly模式,勾選支持PWA。
支持PWA的Blazor程序主要是多了幾個東西:
manifest.json
service-worker.js
manifest.json
manifest.json是個清單文件,當程序被安裝到設備上的時候會讀取里面的信息,名稱是什么,圖標是什么,什么語言等等。
{"name": "BlazorPWA","short_name": "BlazorPWA","start_url": "./","display": "standalone","background_color": "#ffffff","theme_color": "#03173d","icons": [{"src": "icon-512.png","type": "image/png","sizes": "512x512"}] }service-worker.js
service-worker用來跑一些后臺任務。它跟瀏覽器主進程是隔離的,也就是說跟原來的JavaScript運行時是分開,當然了它不會阻塞頁面。我們可以用它來完成一些功能,比如對所有的fetch/xhr請求進行過濾,哪些請求走緩存,哪些不走緩存;比如在后臺偷偷給你拉一些數據緩存起來。
// Caution! Be sure you understand the caveats before publishing an application with // offline support. See https://aka.ms/blazor-offline-considerations self.importScripts('./service-worker-assets.js'); self.addEventListener('install', event => event.waitUntil(onInstall(event))); self.addEventListener('activate', event => event.waitUntil(onActivate(event))); self.addEventListener('fetch', event => event.respondWith(onFetch(event))); const cacheNamePrefix = 'offline-cache-'; const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`; const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/ ]; const offlineAssetsExclude = [ /^service-worker\.js$/ ]; async function onInstall(event) {console.info('Service worker: Install');// Fetch and cache all matching items from the assets manifestconst assetsRequests = self.assetsManifest.assets.filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url))).filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url))).map(asset => new Request(asset.url, { integrity: asset.hash }));await caches.open(cacheName).then(cache => cache.addAll(assetsRequests)); } async function onActivate(event) {console.info('Service worker: Activate');// Delete unused cachesconst cacheKeys = await caches.keys();await Promise.all(cacheKeys.filter(key => key.startsWith(cacheNamePrefix) && key !== cacheName).map(key => caches.delete(key))); } async function onFetch(event) {let cachedResponse = null;if (event.request.method === 'GET') {// For all navigation requests, try to serve index.html from cache// If you need some URLs to be server-rendered, edit the following check to exclude those URLsconst shouldServeIndexHtml = event.request.mode === 'navigate';const request = shouldServeIndexHtml ? 'index.html' : event.request;const cache = await caches.open(cacheName);cachedResponse = await cache.match(request);}return cachedResponse || fetch(event.request); }項目里有2個service-worker.js文件,一個是開發時候的沒邏輯,還有一個是發布時候的有一些緩存的邏輯。
運行一下
如果是PWA程序,在瀏覽器地址欄有個+號一樣的圖標,點擊可以把程序安裝到本地。
安裝完了會在桌面生成一個圖標,打開會是一個沒有瀏覽器地址欄的界面。
這樣一個PWA程序已經可以運行了。
離線運行
如果只是這樣,僅僅是沒有瀏覽器地址欄,那PWA也太沒什么吸引力了。個人覺得PWA最大的魅力就是可以離線運行,在沒有網絡的情況下依然可以運行,這樣才像一個原生編寫的程序。
修改service-worker
離線的原理也很簡單,就是請求的數據都緩存起來,一般是緩存Get請求,比如各種頁面圖片等。
// In development, always fetch from the network and do not enable offline support. // This is because caching would make development more difficult (changes would not // be reflected on the first load after each change). self.addEventListener('fetch', event => event.respondWith(onFetch(event))); self.addEventListener('install', event => event.waitUntil(onInstall(event))); async function onInstall(event) {console.info('Service worker: Install'); } async function onFetch(event) {let cachedResponse = null;const cache = await caches.open('blazor_pwa');if (event.request.method === 'GET') {const request = event.request;cachedResponse = await caches.match(request);if (cachedResponse) {return cachedResponse;}var resp = await fetch(event.request)cache.put(event.request, resp.clone());return resp;}return fetch(event.request); }修改一下sevice-worker.js,把GET請求全部緩存起來。這里為了演示圖方便,其實情況顯然不會這么簡單粗暴。為了能緩存頁面,顯然必須先在線運行成功一次。
模擬離線
當我們修改完上面的js,然后在線正常一次后,可以看到所有GET請求的資源都被緩存起來了。
我們可以用chrome來模擬離線情況:
選擇offline模式,然后刷新我們的頁面,如果依然可以正常運行則表示可以離線運行。
總結
使用Blazor可以快速的開發PWA應用。利用PWA跟Blazor Webassembly的特性,可以開發出類似桌面的應用程序。或許這是跨平臺桌面應用開發除了electron的又一種方案吧。
關注我的公眾號一起玩轉技術
ASP.NET Core Blazor WebAssembly 之 .NET JavaScript互調
ASP.NET Core Blazor Webassembly 之 路由
ASP.NET Core Blazor Webassembly 之 數據綁定
ASP.NET Core Blazor Webassembly 之 組件
ASP.NET Core Blazor 初探之 Blazor Server
ASP.NET Core Blazor 初探之 Blazor WebAssembly
總結
以上是生活随笔為你收集整理的ASP.NET Core Blazor Webassembly 之 渐进式应用(PWA)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: asp.net core监控—引入Pro
- 下一篇: 进击吧! Blazor !第五期 安全