Christian Liebel Patrick Jahr
@christianliebel @jahr_patrick
Consultant Developer Consultant
Progressive Web Apps mit Blazor: So
bringen Sie Ihre .NET-App ins Web!
Slide 2
Slide 2 text
Feel free to ask questions anytime!
Your instructors
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Patrick Jahr Christian Liebel
Slide 3
Slide 3 text
09:00–10:30 Block 1
10:30–11:00 Break
11:00–12:30 Block 2
12:30–13:30 Break
13:30–15:00 Block 3
15:00–15:30 Break
15:30–17:00 Block 4
Timetable
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 4
Slide 4 text
Things NOT to expect
- Blueprint for PWA
development
- No AuthN/AuthZ
- No 1:1 support
Things To Expect
- Extensive/up-to-date insights
into PWA and Project Fugu
- A productivity app use case
that works on your desktop &
smartphone
- Lots of fun
- Hands-on-exercises
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 5
Slide 5 text
https://paint.js.org
– Productivity app
– Draw images
– Lots of actions & tools
– Installable
– Read/save files
– Copy/paste images
from/to clipboard
– Share files to other apps
– Register for file extensions
Demo Use Case
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 6
Slide 6 text
(Workshop Edition)
– Productivity app
– Draw images
– Lots of actions & tools
– Installable
– Read/save files
– Copy/paste images
from/to clipboard
– Share files to other apps
– Register for file extensions
Demo Use Case
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 7
Slide 7 text
Setup complete?
(.NET 8 SDK, Visual Studio 2022, Chrome or Edge, Git)
Setup (1/2)
EX #0
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 8
Slide 8 text
git clone https://github.com/thinktecture-labs/ddc-
2023-blazor-project-fugu.git
Setup (2/2)
EX #0
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 9
Slide 9 text
Paint PWA
Capabilitie
s
Progressive
Enhanceme
nt
Agenda
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 10
Slide 10 text
Paint PWA
Capabilitie
s
Progressive
Enhanceme
nt
Agenda
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 11
Slide 11 text
Canvas
– Plain bitmap for the web
– Cross-platform, hardware-
accelerated graphics
operations
– Supports different contexts
(2D, 3D: WebGL, WebGL 2.0)
– Supported on all evergreen
browsers and on IE 9+
Paint
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 12
Slide 12 text
Canvas
Add a canvas element to Index.razor:
Query the canvas element in Index.razor.cs:
private Canvas? _canvas;
Paint
EX #1
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 13
Slide 13 text
Canvas 2D Context
fillRect(x, y, width, height)
strokeRect(x, y, width, height)
beginPath()
moveTo(x, y)
lineTo(x, y)
fill()
stroke()
Paint
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 14
Slide 14 text
Canvas 2D Context
Get the 2D context and prepare the canvas in Index.razor.cs in the
method OnAfterRenderAsync(bool firstRender):
await using var context = await _canvas!.GetContext2DAsync();
await context.FillStyleAsync("white");
await context.FillRectAsync(0, 0, 600, 480);
await context.FillStyleAsync("black");
Paint
EX #2
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 15
Slide 15 text
Low-latency Rendering
Paint
Web pages need to synchronize
with the DOM on graphics updates
causing latencies that can make
drawing difficult
Low-latency rendering skips
syncing with the DOM with can lead
to a more natural experience
Supported on Chrome (Chrome OS
and Windows only)
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 16
Slide 16 text
Low-latency Rendering
Opt-in to low-latency rendering (Index.razor.cs):
await using var context = await
_canvas!.GetContext2DAsync(desynchronized: true);
Paint
EX #3
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 17
Slide 17 text
Pointer Events
Paint
Users nowadays use different
input methods, cross-platform
apps should cover all of them
Pointer Events offer an
abstract interface to catch all
input methods (pointerdown,
pointermove, pointerup)
event.offsetX/event.offsetY
contain the pointer’s position
relative to the listener
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 18
Slide 18 text
Pointer Events
Add event listeners (Index.razor):
Paint
EX #4
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 19
Slide 19 text
Pointer Events
Add event listeners methods (Index.razor.cs):
private async void OnPointerMove(PointerEventArgs args)
{
var currentPoint = new Point
{
X = (int)Math.Floor(args.OffsetX),
Y = (int)Math.Floor(args.OffsetY)
};
await using var context = await _canvas!.GetContext2DAsync(desynchronized:
true);
await context.FillRectAsync(currentPoint.X, currentPoint.Y, 2, 2);
}
Paint
EX #4
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 20
Slide 20 text
Pointer Events
Add event listeners methods (Index.razor.cs):
private async void OnPointerDown(PointerEventArgs args)
{
_previousPoint = new Point
{
X = (int)Math.Floor(args.OffsetX),
Y = (int)Math.Floor(args.OffsetY)
};
}
Paint
EX #4
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 21
Slide 21 text
Bresenham Line Algorithm
The user may move faster than
the input can be processed
For this case, we need to
remember the previous point
and interpolate the points in
between
The Bresenham line algorithm
calculates the missing pixels
between two given points
Paint
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 22
Slide 22 text
Bresenham Line Algorithm
Update the method OnPointerMove() in Index.razor.cs:
if (_previousPoint != null)
{
var currentPoint = new Point
{
X = (int)Math.Floor(args.OffsetX),
Y = (int)Math.Floor(args.OffsetY)
};
var points = _paintService.BrensenhamLine(_previousPoint.Value, currentPoint);
await using var context = await _canvas.GetContext2DAsync();
foreach (var point in points)
{
await context.FillRectAsync(point.X, point.Y, 2, 2);
}
_previousPoint = currentPoint;
}
Paint
EX #5
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 23
Slide 23 text
Color Selection
For this demo, we will only
implement the brush tool. However,
we want to bring in some color.
A simple method to implement a
color selection is to use the HTML
color-type input element that
shows the native color picker:
Paint
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 24
Slide 24 text
Color Selection
1. In Index.razor, add the following input to the node:
2. In Index.razor.cs, add the following code in the method
OnColorChange():
await using var context = await _canvas!.GetContext2DAsync();
await context.FillStyleAsync(args.Value?.ToString());
Paint
EX #6
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 25
Slide 25 text
Paint PWA
Capabilitie
s
Progressive
Enhanceme
nt
Agenda
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 26
Slide 26 text
Responsive Linkable Discoverable Installable App-like
Connectivity
Independent
Fresh Safe Re-engageable Progressive
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 27
Slide 27 text
Web App
Manifest
Service
Worker
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 28
Slide 28 text
Web App Manifest
Distinguishes Web Apps from
Websites
JSON-based file containing
metadata for apps only
Apps can be identified by search
engines, app store providers, etc.
PWA
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 29
Slide 29 text
manifest.webmanifest
{
"short_name": "Paint",
"name": "Paint Workshop",
"theme_color": "white",
"icons": [{
"src": "icon.png",
"sizes": "512x512"
}],
"start_url": "./",
"display": "standalone",
"shortcuts": [/* … */]
}
PWA
Names
Icons
Display Mode
Shortcuts
Start URL
Theme color (status bar/window bar)
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 30
Slide 30 text
Manifest Display Modes
PWA
browser minimal-ui standalone fullscreen
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 31
Slide 31 text
Manifest Icon Purposes
(any)
any context (e.g. app icon)
monochrome
different color requirements
maskable
user agent masks icon as required
PWA
Safe Zone
Windows iOS Android
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 32
Slide 32 text
Blazor Support
The Blazor PWA template adds
a web app manifest and
service worker support
Progressive Web Apps mit Blazor
So bringen Sie Ihre .NET-App ins Web!
PWA
Slide 33
Slide 33 text
Web App Manifest
1. Update the file wwwroot/manifest.json and set:
a) name and short_name to values of your choice
b) theme_color to #000080 and background_color to #808080
2. In index.html, set theme_color to #000080 as well.
3. Run dotnet run
4. Test manifest in DevTools: F12 > Application > Manifest
PWA
EX #7
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 34
Slide 34 text
Manifest Shortcuts
PWA
Secondary entrypoints for your
application (e.g., home screen
quick actions, jump lists, …)
Static definition in Web App
Manifest (dynamic API may
follow in the future)
Supported by Google Chrome
for Android, macOS and
Windows
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 35
Slide 35 text
Web App Manifest
1. In wwwroot/manifest.json, add (at least) the following shortcut:
"shortcuts": [{
"name": "About Paint",
"short_name": "About",
"description": "Show information about Paint",
"url": "./",
"icons": [{ "src": "icon-512.png", "sizes": "512x512" }]
}],
2. Test in DevTools: F12 > Application > Manifest
PWA
EX #8
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 36
Slide 36 text
Web App Manifest – Installability Criteria
1. Web App is not already installed
2. User clicked the page at least once and had it open for at least 30
seconds (at any time)
3. Includes a Web App Manifest that has short_name or name, at least a
192px and 512px icon, a start_url and a display mode of fullscreen,
standalone or minimal-ui
4. Served over HTTPS
5. Has a registered service worker with a fetch event handler
https://web.dev/install-criteria/#criteria
PWA
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 37
Slide 37 text
Service Worker
JavaScript snippet executed in an
own thread, registered by the website
Acts as a controller, proxy, or
interceptor
Has a cache to store responses (for
offline availability and performance)
Can wake up even when the website
is closed and perform background
tasks (e.g., push notifications or sync)
PWA
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 38
Slide 38 text
Service Worker
PWA
Service
Worker
Internet
Website
HTML/JS
Cache
fetch
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 39
Slide 39 text
Blazor Service Worker
The Blazor PWA template
includes a custom service
worker implementation
All Blazor assets are precached
by default
Service Worker behavior can
be modified (e.g., for push)
à maximum flexibility
PWA
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 40
Slide 40 text
Service Worker
1. Start application with dotnet run or with Visual Studio
2. Test in DevTools: F12 > Application > Service Worker
3. Install the app: Address Bar > Install
PWA
EX #9
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 41
Slide 41 text
Push Notifications
Just as native apps, PWAs can
receive push notifications
Combination of two technologies:
Web Notifications and Push API
Supported by Chrome, Edge,
Firefox, Safari
Progressive Web Apps mit Blazor
So bringen Sie Ihre .NET-App ins Web!
PWA
Slide 42
Slide 42 text
Service Worker Debugging
More information on installed
service workers can be found on
• about://serviceworker-
internals (Google Chrome)
• about:serviceworkers
(Mozilla Firefox)
PWA
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 43
Slide 43 text
Service Worker Debugging
PWA
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 44
Slide 44 text
Lighthouse
PWA
Auditing tool by Google,
integrated in Chrome DevTools
Automatically checks
performance metrics, PWA
support, accessibility, SEO and
other best practices and gives
tips on how to improve
Can simulate mobile devices
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 45
Slide 45 text
Lighthouse
1. Make sure only one tab/window of your PWA is open
2. Open DevTools: F12 > Lighthouse
3. Make sure to select at least the “Progressive Web App” category
4. Click “Analyze page load”
PWA
EX #10
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 46
Slide 46 text
Paint PWA
Capabilitie
s
Progressive
Enhanceme
nt
Agenda
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 47
Slide 47 text
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 48
Slide 48 text
Project Fugu
Capabilities
»Let’s bring the web
back – API by API«
Thomas Steiner, Google
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 49
Slide 49 text
Capabilities
Contacts
Picker
Screen Wake
Lock API
File System
Access API
Shape
Detection API
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 50
Slide 50 text
Capabilities
https://goo.gle/fugu-api-tracker
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 51
Slide 51 text
Browser
Capabilities
navigator.share({ url: 'http://example.com' });
ShareIntent DataTransferManager
…
NSSharingServicePicker
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 52
Slide 52 text
File System Access API
Some applications heavily rely
on working with files (e.g.
Visual Studio Code, Adobe
Photoshop, …)
File System Access API allows
you to open, save and override
files and directories
Supported by Chrome, Edge
Capabilities
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 53
Slide 53 text
File System Access API
1. Add the following buttons to the bar in Index.razor (before the color input):
Open
Save
Copy
Paste
Share
Capabilities
EX #11
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 54
Slide 54 text
File System Access API
2. Add the following lines at the top of Index.razor.cs:
private static FilePickerAcceptType[] _acceptTypes = new
FilePickerAcceptType[]
{
new FilePickerAcceptType
{
Accept = new Dictionary {
{ "image/png", new[] {".png" } }
},
Description = "PNG files"
}
};
Capabilities
EX #11
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 55
Slide 55 text
File System Access API
3. Add the following lines at the top of Index.razor.cs:
private SaveFilePickerOptionsStartInWellKnownDirectory _savePickerOptions =
new SaveFilePickerOptionsStartInWellKnownDirectory
{
StartIn = WellKnownDirectory.Pictures,
Types = _acceptTypes
};
Capabilities
EX #11
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 56
Slide 56 text
File System Access API
4. Add the following lines in the method SaveLocalFile() of Index.razor.cs:
[Inject] private IFileSystemAccessService _fileSystemAccessService
{ get; set; } = default!;
if (_fileHandle == null)
{
_fileHandle = await _fileSystemAccessService
.ShowSaveFilePickerAsync(_savePickerOptions);
}
Capabilities
EX #11
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 57
Slide 57 text
File System Access API
5. Add the following lines in the method SaveLocalFile() of Index.razor.cs:
var writeable = await _fileHandle.CreateWritableAsync();
var image = await _imageService.GetImageDataAsync(_PAINT_CANVAS);
await writeable.WriteAsync(image);
await writeable.CloseAsync();
await _fileHandle.JSReference.DisposeAsync();
_fileHandle = null;
Capabilities
EX #11
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 58
Slide 58 text
File System Access API
1. Add the following lines at the top of Index.razor.cs:
private readonly OpenFilePickerOptionsStartInWellKnownDirectory
_filePickerOptions = new OpenFilePickerOptionsStartInWellKnownDirectory
{
Multiple = false,
StartIn = WellKnownDirectory.Pictures,
Types = _acceptTypes
};
Capabilities
EX #12
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 59
Slide 59 text
File System Access API
2. Add the following code int the method OpenLocalFile() of Index.razor.cs:
try
{
var fileHandles = await
_fileSystemAccessService.ShowOpenFilePickerAsync(_filePickerOptions);
_fileHandle = fileHandles.Single();
}
catch (JSException ex)
{
Console.WriteLine(ex);
}
Capabilities
EX #12
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 60
Slide 60 text
File System Access API
3. Add the following code int the method OpenLocalFile() of Index.razor.cs:
finally
{
if (_fileHandle is not null)
{
var file = await _fileHandle.GetFileAsync();
await _imageService.OpenFileAccessAsync(file.JSReference);
await using var context = await _canvas!.GetContext2DAsync();
await context.DrawImageAsync("image", 0, 0);
}
}
Capabilities
EX #12
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 61
Slide 61 text
Async Clipboard API
Allows reading from/writing to
the clipboard in an
asynchronous manner (UI won’t
freeze during long-running
operations)
Reading from the clipboard
requires user consent first
(privacy!)
Supported by Chrome, Edge,
Safari and Firefox (plain-text
only)
Capabilities
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 62
Slide 62 text
Async Clipboard API
Add the following code in the method Copy() of Index.razor.cs:
var imagePromise = _asyncClipboardService.GetObjectReference(
_module!, "getCanvasBlob", _PAINT_CANVAS);
var clipboardItem = new ClipboardItem(
new Dictionary
{
{_IMAGE_TYPE, imagePromise }
});
await _asyncClipboardService.WriteAsync(
new[] { clipboardItem }
);
Capabilities
EX #13
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 63
Slide 63 text
Async Clipboard API
Add the following code in the method Paste() of Index.razor.cs:
var clipboardItems = await _asyncClipboardService.ReadAsync();
var pngItem = clipboardItems
.FirstOrDefault(c => c.Types.Contains(_IMAGE_TYPE));
if (pngItem is not null)
{
var blob = await pngItem.GetTypeAsync(_IMAGE_TYPE);
await _imageService.OpenFileAccessAsync(blob);
await using var context = await _canvas!.GetContext2DAsync();
await context.DrawImageAsync(_IMAGE_ID, 0, 0);
}
Capabilities
EX #14
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 64
Slide 64 text
Web Share API
Allows sharing a title, URL, text, or
files
API can only be invoked as a
result of a user action (i.e. a click
or keypress)
Supported by Chrome, Edge,
Safari and Firefox (Android only)
Capabilities
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 65
Slide 65 text
Web Share API
Add the following code in the share() method in the Index.razor.cs:
var fileReference = await _imageService.GenerateFileReferenceAsync(
await _canvas!.ToDataURLAsync());
await _shareService.ShareAsync(
new WebShareDataModel
{
Files = new[] { fileReference }
});
Capabilities
EX #15
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 66
Slide 66 text
File System Handling API
Register your PWA as a
handler for file extensions
Requires installing the
application first
Declare supported extensions
in Web App Manifest and add
imperative code to your
application logic
Capabilities
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 67
Slide 67 text
File System Handling API
1. Add the following property to your manifest (wwwroot/manifest.json):
"file_handlers": [{
"action": "./",
"accept": {
"image/png": [".png"]
}
}]
Capabilities
EX #16
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 68
Slide 68 text
File System Handling API
2. Add the following code to the Index.razor.js file at row 23:
export function initializeLaunchQueue(component) {
if ('launchQueue' in window) {
window.launchQueue.setConsumer(async params => {
const [handle] = params.files;
if (handle) {
const file = await handle.getFile();
await createImageElement(file);
component.invokeMethodAsync('DrawImageAsync');
}
});
}
}
Capabilities
EX #16
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 69
Slide 69 text
File System Handling API
3. Add the following code to method OnAfterRenderAsync in the Index.razor.cs file:
_selfReference = DotNetObjectReference.Create(this);
if (_module == null)
{
_module = await JS.InvokeAsync("import", "./Pages/Index.razor.js");
}
await _module.InvokeVoidAsync("initializeLaunchQueue", _selfReference);
Capabilities
EX #16
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 70
Slide 70 text
File System Handling API
4. Add the following code to the method DrawImageAsync in the Index.razor.cs file:
[JSInvokable]
public async Task DrawImageAsync()
{
await using var context = await _canvas!.GetContext2DAsync();
await context.DrawImageAsync("image", 0, 0);
}
Capabilities
EX #16
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 71
Slide 71 text
Paint PWA
Capabilitie
s
Progressive
Enhanceme
nt
Agenda
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 72
Slide 72 text
Overview
Use available interfaces and functions of
a system (opposite of Graceful
Degradation)
Users with modern, feature-rich
browsers get a better experience
Apps are available on older browsers, but
with limited functionality
Concept: Browser feature support should
grow over time—thereby more users can
enjoy an increasing number of features
Progressive Enhancement
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 73
Slide 73 text
Overview
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register(…)
.then(() => /* … */);
}
In JavaScript: check whether an API/feature is available. If yes—use it!
Otherwise:
1. Disable the functionality
2. Fall back to an alternative API (if available)
Progressive Enhancement
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 74
Slide 74 text
Disabling unsupported features
In Index.razor.cs, hide the buttons in case the respective API does not exist, e.g.:
_fileSystemAccessSupported = await _fileSystemAccessService.IsSupportedAsync();
And hide the buttons which are not supported in the Index.razor, e.g.:
@if(_fileSystemAccessSupported) {
Open
Save
} else {
Download
}
Progressive Enhancement
EX #17
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 75
Slide 75 text
Disabling unsupported features
1. Copy: await _asyncClipboardService.IsSupportedAsync();
2. Paste: await _asyncClipboardService.IsSupportedAsync();
3. Share: await _shareService.IsSupportedAsync();
Progressive Enhancement
EX #17
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 76
Slide 76 text
Disabling unsupported features
Add the following code to the method OnInitializedAsync in the Index.razor.cs file:
_fileSystemAccessSupported = await _fileSystemAccessService.IsSupportedAsync();
_clipboardApiSupported = await _asyncClipboardService.IsSupportedAsync();
_shareApiSupported = await _shareService.IsSupportedAsync();
Progressive Enhancement
EX #17
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 77
Slide 77 text
Disabling unsupported features
Replace the following code to the Index.razor file:
Copy
Paste
Share
Progressive Enhancement
EX #17
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 78
Slide 78 text
Providing an alternative implementation
If the feature are not supported, fall back to the following code for the DownloadFile()
Method:
await _imageService.DownloadAsync(await _canvas!.ToDataURLAsync());
Progressive Enhancement
EX #18
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 79
Slide 79 text
Providing an alternative implementation
If the feature are not supported, fall back to the following code for the OpenFile()
Method:
await using var context = await _canvas!.GetContext2DAsync();
await _imageService.OpenAsync(args.File.OpenReadStream(1024 * 15 * 1000));
await context.DrawImageAsync("image", 0, 0);
Progressive Enhancement
EX #19
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 80
Slide 80 text
– Productivity apps
– IDEs, code editors
– Video editors
– Image editors
– Office applications
– Document editors
– Presentation apps
– Enterprise applications
Progressive Web Apps mit Blazor
So bringen Sie Ihre .NET-App ins Web!
Use Cases
Slide 81
Slide 81 text
Spotify
Progressive Web Apps mit Blazor
So bringen Sie Ihre .NET-App ins Web!
Use Cases
https://open.spotify.com/
Slide 82
Slide 82 text
VS Code
Progressive Web Apps mit Blazor
So bringen Sie Ihre .NET-App ins Web!
Use Cases
https://vscode.dev/
Slide 83
Slide 83 text
Photoshop
Progressive Web Apps mit Blazor
So bringen Sie Ihre .NET-App ins Web!
Use Cases
https://photoshop.adobe.com/
Slide 84
Slide 84 text
PWA
– Installation may not be obvious
– Only web platform APIs can be called
– Antivirus software or cloud sync agents can’t be implemented
– Some APIs may not be available on all browsers and OS’s
Progressive Web Apps mit Blazor
So bringen Sie Ihre .NET-App ins Web!
Limitations
Slide 85
Slide 85 text
Blazor
– C#, but knowledge of HTML, CSS and JS will still be required
– Rider support is not great
– Caching can lead to confusion while testing
– Very large bundles = high initial loading time (mobile users!)
– Blazor WebAssembly: 2 MB (without culture info)
– Angular: 50 kB
– Firewalls may block the transfer of DLL files
– Summary: Maybe not the best solution for B2C apps where the
environment cannot be controlled
Progressive Web Apps mit Blazor
So bringen Sie Ihre .NET-App ins Web!
Limitations
Slide 86
Slide 86 text
Blazor: Reuse your existing C# and .NET knowledge and implement great
applications that run just fine in the browser and all relevant OS’s
PWA: Improve the experience by allowing users to install your app and
run it offline
Fugu: Add capabilities for an even deeper integration with the OS using
C#-based NuGet packages
Progressive Enhancement: Ensure that users of older or less powerful
browsers can still use the app
Let’s build great apps for the web!
Summary
So bringen Sie Ihre .NET-App ins Web!
Progressive Web Apps mit Blazor
Slide 87
Slide 87 text
Thank you
for your kind attention!
Christian Liebel
@christianliebel
[email protected]
https://www.thinktecture.com/ueber-uns/karriere/
Patrick Jahr
@jahr_patrick
[email protected]