网站首页 > 技术文章 正文
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 manifest
const 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 caches
const 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 URLs
const 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的又一种方案吧。
- 上一篇: 运行时 Bun 又添王炸,支持 Bun宏!
- 下一篇: 可观测系统如何识别网站有多少文件命中了缓存?
猜你喜欢
- 2024-11-14 每个JavaScript开发人员都应该了解的编程概念
- 2024-11-14 Next.js Api Router 数据处理 router next参数
- 2024-11-14 2023 黑马前端就业版最新线下课程(8月版本)
- 2024-11-14 23 个超实用 JS 技巧 js简明教程
- 2024-11-14 HTTP 规范中的那些暗坑 http+规范中的那些暗坑有哪些
- 2024-11-14 使用 JS 操作 HTML 元素 用js写html
- 2024-11-14 一面 2:JS-Web-API 知识点与高频考题解析
- 2024-11-14 MutationObserver 都被传烂了,你怎么到现在都还不会?
- 2024-11-14 无名前端库 无名前端库是什么
- 2024-11-14 可观测系统如何识别网站有多少文件命中了缓存?
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-