Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Progressive Web Apps mit Blazor: So bringen Sie...

Progressive Web Apps mit Blazor: So bringen Sie Ihre .NET-App ins Web!

Stellen Sie sich vor, Sie schreiben Ihre moderne Businessanwendung genau einmal – und sie läuft auf Windows, macOS, Linux, Android, iOS und im Browser. Diese Anwendungen werden per Fingertippen aus dem Browser auf dem Gerät installiert und funktionieren auch dann, wenn das WiFi im Zug gerade mal wieder nicht funktioniert. Das klingt fantastisch? Dank Progressive Web Apps (PWA) wird all das Wirklichkeit. Mit Hilfe moderner Webtechnologien wird aus einer Webanwendung eine App, die einer nativen App in nichts nachsteht.

In diesem Workshop zeigen wir anhand eines durchgängigen Beispiels die Grundlagen der PWA-Entwicklung mit Microsofts Single Page App Framework Blazor, bei denen Sie aktiv mitentwickeln können. Jede(r) geht mit einer PWA nach Hause!

Christian Liebel

November 27, 2023
Tweet

More Decks by Christian Liebel

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. 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
  4. 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
  5. (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
  6. 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
  7. Paint PWA Capabilitie s Progressive Enhanceme nt Agenda So bringen

    Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  8. Paint PWA Capabilitie s Progressive Enhanceme nt Agenda So bringen

    Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  9. 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
  10. Canvas Add a canvas element to Index.razor: <Canvas @ref="_canvas" id="@_PAINT_CANVAS"

    width="600" height="480"></Canvas> 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
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. Pointer Events Add event listeners (Index.razor): <Canvas #canvas width="600" height="480"

    @onpointerdown="OnPointerDown" @onpointerup="InternalPointerUp" @onpointermove="OnPointerMove"> </Canvas> Paint EX #4 So bringen Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  17. 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
  18. 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
  19. 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
  20. 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
  21. 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: <input type="color"> Paint So bringen Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  22. Color Selection 1. In Index.razor, add the following input to

    the <nav> node: <input type="color" @onchange="OnColorChange" /> 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
  23. Paint PWA Capabilitie s Progressive Enhanceme nt Agenda So bringen

    Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  24. 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
  25. Web App Manifest Service Worker So bringen Sie Ihre .NET-App

    ins Web! Progressive Web Apps mit Blazor
  26. 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
  27. 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
  28. Manifest Display Modes PWA browser minimal-ui standalone fullscreen So bringen

    Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  29. 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
  30. 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
  31. 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
  32. 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
  33. 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
  34. 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
  35. 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
  36. Service Worker PWA Service Worker Internet Website HTML/JS Cache fetch

    So bringen Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  37. 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
  38. 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
  39. 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
  40. 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
  41. 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
  42. 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
  43. Paint PWA Capabilitie s Progressive Enhanceme nt Agenda So bringen

    Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  44. 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
  45. 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
  46. 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
  47. File System Access API 1. Add the following buttons to

    the <nav> bar in Index.razor (before the color input): <button @onclick="OpenLocalFile">Open</button> <button @onclick="SaveFileLocal">Save</button> <button @onclick="Copy">Copy</button> <button @onclick="Paste">Paste</button> <button @onclick="Share">Share</button> Capabilities EX #11 So bringen Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  48. 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<string, string[]> { { "image/png", new[] {".png" } } }, Description = "PNG files" } }; Capabilities EX #11 So bringen Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  49. 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
  50. 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
  51. 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
  52. 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
  53. 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
  54. 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
  55. 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
  56. 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<string,IJSObjectReference> { {_IMAGE_TYPE, imagePromise } }); await _asyncClipboardService.WriteAsync( new[] { clipboardItem } ); Capabilities EX #13 So bringen Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  57. 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
  58. 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
  59. 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
  60. 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
  61. 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
  62. 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
  63. 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<IJSObjectReference>("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
  64. 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
  65. Paint PWA Capabilitie s Progressive Enhanceme nt Agenda So bringen

    Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  66. 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
  67. 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
  68. 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) { <button @onclick="OpenLocalFile">Open</button> <button @onclick="SaveFileLocal">Save</button> } else { <InputFile OnChange="OpenFile"></InputFile> <button @onclick="DownloadFile">Download</button> } Progressive Enhancement EX #17 So bringen Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  69. 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
  70. 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
  71. Disabling unsupported features Replace the following code to the Index.razor

    file: <button @onclick="Copy" disabled="@(!_clipboardApiSupported)">Copy</button> <button @onclick="Paste" disabled="@(!_clipboardApiSupported)">Paste</button> <button @onclick="Share" disabled="@(!_shareApiSupported)">Share</button> Progressive Enhancement EX #17 So bringen Sie Ihre .NET-App ins Web! Progressive Web Apps mit Blazor
  72. 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
  73. 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
  74. – 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
  75. Spotify Progressive Web Apps mit Blazor So bringen Sie Ihre

    .NET-App ins Web! Use Cases https://open.spotify.com/
  76. VS Code Progressive Web Apps mit Blazor So bringen Sie

    Ihre .NET-App ins Web! Use Cases https://vscode.dev/
  77. Photoshop Progressive Web Apps mit Blazor So bringen Sie Ihre

    .NET-App ins Web! Use Cases https://photoshop.adobe.com/
  78. 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
  79. 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
  80. 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
  81. Thank you for your kind attention! Christian Liebel @christianliebel [email protected]

    https://www.thinktecture.com/ueber-uns/karriere/ Patrick Jahr @jahr_patrick [email protected]