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程序主要是多了几个东西:

  1. manifest.json
  2. 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的又一种方案吧。

ASP.NET Core Blazor Webassembly 之 渐进式应用(PWA)的更多相关文章

  1. ASP.NET Core Blazor Webassembly 之 数据绑定

    上一次我们学习了Blazor组件相关的知识(Asp.net Core Blazor Webassembly - 组件).这次继续学习Blazor的数据绑定相关的知识.当代前端框架都离不开数据绑定技术. ...

  2. ASP.NET Core Blazor Webassembly 之 路由

    web最精妙的设计就是通过url把多个页面串联起来,并且可以互相跳转.我们开发系统的时候总是需要使用路由来实现页面间的跳转.传统的web开发主要是使用a标签或者是服务端redirect来跳转.那今天来 ...

  3. ASP.NET Core Blazor Webassembly 之 组件

    关于组件 现在前端几大轮子全面组件化.组件让我们可以对常用的功能进行封装,以便复用.组件这东西对于搞.NET的同学其实并不陌生,以前ASP.NET WebForm的用户控件其实也是一种组件.它封装ht ...

  4. [Asp.Net Core] Blazor WebAssembly - 工程向 - 如何在欢迎页面里, 预先加载wasm所需的文件

    前言, Blazor Assembly 需要最少 1.9M 的下载量.  ( Blazor WebAssembly 船新项目下载量测试 , 仅供参考. ) 随着程序越来越复杂, 引用的东西越来越多,  ...

  5. ASP.NET Core Blazor WebAssembly 之 .NET JavaScript互调

    Blazor WebAssembly可以在浏览器上跑C#代码,但是很多时候显然还是需要跟JavaScript打交道.比如操作dom,当然跟angular.vue一样不提倡直接操作dom:比如浏览器的后 ...

  6. ASP.NET Core Blazor WebAssembly实现一个简单的TODO List

    基于blazor实现的一个简单的TODO List 最近看到一些大佬都开始关注blazor,我也想学习一下.做了一个小的demo,todolist,仅是一个小示例,参考此vue项目的实现http:// ...

  7. ASP.NET Core Blazor 用Inspinia静态页模板搭建简易后台(实现菜单选中)

    Blazor 是一个用于使用 .NET 生成交互式客户端 Web UI 的框架: 使用 C# 代替 JavaScript 来创建丰富的交互式 UI. 共享使用 .NET 编写的服务器端和客户端应用逻辑 ...

  8. ASP.NET Core Blazor 初探之 Blazor Server

    上周初步对Blazor WebAssembly进行了初步的探索(ASP.NET Core Blazor 初探之 Blazor WebAssembly).这次来看看Blazor Server该怎么玩. ...

  9. [Asp.Net Core] Blazor Server Side 扩展用途 - 配合CEF来制作带浏览器核心的客户端软件 (二) 可运行版本

    前言 大概3个星期之前立项, 要做一个 CEF+Blazor+WinForms 三合一到同一个进程的客户端模板. 这个东西在五一的时候做出了原型, 然后慢慢修正, 在5天之前就上传到github了. ...

随机推荐

  1. Web缓存欺骗

    该漏洞主要是cdn安全配置的问题,cdn主要存储以下文件,加快访问速度 class, css, jar, js, jpg, jpeg, gif, ico, png, bmp, pict, csv, d ...

  2. Java实现 蓝桥杯 图书排列(全排列)

    标题:图书排列 将编号为1~10的10本书排放在书架上,要求编号相邻的书不能放在相邻的位置. 请计算一共有多少种不同的排列方案. 注意,需要提交的是一个整数,不要填写任何多余的内容. 9 9 10 9 ...

  3. Java实现UVA10131越大越聪明(蓝桥杯每周一题)

    10131越大越聪明(蓝桥杯每周一题) [问题描述] 一些人认为,大象的体型越大,脑子越聪明.为了反驳这一错误观点,你想要分析一组大象的数据,找出尽量 多的大象组成一个体重严格递增但 IQ 严格递减的 ...

  4. Spring Data Jpa Specification 调用Oracle 函数/方法

    开发框架用的Jpa,数据库是 Oracle. 在开发中难免会遇到需要数据库字段是字符串格式,但是又需要对其进行范围查询(数据库设计问题,后续应避免).那么问题来了, Jpa Specification ...

  5. 性能测试中TPS上不去的原因

    TPS(Transaction Per Second):每秒事务数,指服务器在单位时间内(秒)可以处理的事务数量,一般以request/second为单位. 压测中为什么TPS上不去的原因: .网络带 ...

  6. App自动化测试框架学习探索--从零开始设计

    App自动化测试框架学习探索--从零开始设计---持续更新中,敬请关注 1 批量执行app自动化测试使用多线程设计思路: 1)并发级别选择用methods 2)采用@Test多线程,数据提供类dp单线 ...

  7. Hive的基本介绍以及常用函数

    一.Hive的简介: Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能. 优点: ) 操作接口采用类SQL语法,提供快速开发的能力(简单.容易上 ...

  8. Tomcat 配置必备的 10 个小技巧

    现在开发Java Web应用,建立和部署Web内容是一件很简单的工作.使用Jakarta Tomcat作为Servlet和JSP容器的人已经遍及全世界.Tomcat具有免费.跨平台等诸多特性,并且更新 ...

  9. HDU-3033 I love sneakers! 题解

    题目大意 有 n 个物品,分成了 k 组,每个物品有体积和价值,把 n 个物品放到容量为 V 的背包中,保证每组至少放一件,求能获得的最大价值,如果不能实现,输出"Impossible&qu ...

  10. Servlet Session MVC模式

    一   什么是Session 当首次使用session时,服务器端要创建session,session是保存在服务器端,而给客户端的session的id(一个cookie中保存了sessionId). ...