AgentSkillsCN

uno-wasm-pwa

Uno Platform WebAssembly与渐进式Web应用开发:引导程序设置、PWA清单、调试、托管、性能优化以及部署。在以下情况下使用此功能:(1) 使用Uno Platform瞄准WebAssembly;(2) 通过Service Worker添加PWA支持;(3) 调试Wasm应用;(4) 部署至Azure静态Web应用或Nginx;(5) 优化Wasm有效载荷大小与加载时间;(6) 为Wasm配置AOT编译。

SKILL.md
--- frontmatter
name: uno-wasm-pwa
description: "Uno Platform WebAssembly and Progressive Web App development: bootstrapper setup, PWA manifests, debugging, hosting, performance optimization, and deployment. Use when: (1) Targeting WebAssembly with Uno Platform, (2) Adding PWA support with service workers, (3) Debugging Wasm apps, (4) Deploying to Azure Static Web Apps or Nginx, (5) Optimizing Wasm payload size and load time, (6) Configuring AOT compilation for Wasm"

Uno Platform WebAssembly and PWA

Patterns for building, debugging, optimizing, and deploying Uno Platform apps as WebAssembly applications and Progressive Web Apps.

Prerequisites

bash
dotnet workload install wasm-tools

Verify: dotnet workload list should show wasm-tools installed.

Project Setup

The net9.0-browserwasm TFM is included by default in Uno Platform Single Project:

xml
<TargetFrameworks>
    net9.0-android;net9.0-ios;net9.0-browserwasm;net9.0-desktop;net9.0
</TargetFrameworks>

Enable PWA

Add via template or manually:

bash
dotnet new unoapp -pwa

Or add manually:

xml
<UnoFeatures>
    <!-- other features -->
</UnoFeatures>

PWA manifest file (manifest.webmanifest) must have Content build action. Place in the WebAssembly platform folder or project root.

Bootstrapper (Uno.Wasm.Bootstrap 9.x)

Version 9.x targets .NET 9 and uses Microsoft.NET.Sdk.WebAssembly. Key changes from 8.x:

  • SDK changed from Microsoft.NET.Sdk.Web to Microsoft.NET.Sdk.WebAssembly
  • Uno.Wasm.Bootstrap.DevServer package is no longer needed
  • Compression handled by .NET SDK (not bootstrapper properties)
  • IDBFS not enabled by default; must be explicitly restored

Bootstrapper Version Mapping

Bootstrapper.NET Runtime
9.x.NET 9
10.x.NET 10
8.x.NET 8

Debugging

Visual Studio 2022

Ensure launchSettings.json contains the inspect URI in every profile:

json
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}"

Browser DevTools

  • Use browser F12 console for Console.WriteLine output
  • Source maps available in debug builds
  • Set breakpoints in browser Sources tab under file:// paths

Common Wasm Debug Issues

  • Blank screen: Check browser console for .NET runtime errors
  • Missing assets: Verify Content build action on static files
  • CORS errors: Configure proper headers on hosting server

Hosting and Deployment

Azure Static Web Apps

yaml
# GitHub Actions workflow
- name: Publish
  run: dotnet publish -c Release -f net9.0-browserwasm
- name: Deploy
  uses: Azure/static-web-apps-deploy@v1
  with:
    app_location: "bin/Release/net9.0-browserwasm/publish/wwwroot"

Nginx

Required MIME types for Wasm:

nginx
types {
    application/wasm wasm;
    application/octet-stream clr;
    application/json json;
    application/javascript js;
}

# Enable compression
gzip on;
gzip_types application/wasm application/javascript application/json;

# Cache immutable assets
location /_framework/ {
    add_header Cache-Control "public, max-age=31536000, immutable";
}

Local Testing

bash
dotnet tool install -g dotnet-serve
dotnet publish -c Debug -f net9.0-browserwasm
dotnet serve -d bin/Debug/net9.0-browserwasm/publish/wwwroot -p 8000

Performance Optimization

AOT Compilation

Ahead-of-Time compilation improves runtime performance at the cost of larger payloads and longer builds.

xml
<PropertyGroup Condition="'$(TargetFramework)' == 'net9.0-browserwasm'">
    <RunAOTCompilation>true</RunAOTCompilation>
</PropertyGroup>

Payload Size Reduction

  • Enable trimming (default in Release): removes unused code
  • Use Brotli compression on the web server
  • Lazy-load assemblies for large features not needed at startup
  • Minimize embedded resources: large images and assets inflate the initial download

Startup Optimization

  • Keep initial visual tree minimal (use x:Load for deferred content)
  • Defer non-critical service registration
  • Use splash screen during .NET runtime initialization

Threading

WebAssembly threading is not supported in Uno Platform on .NET 9. Microsoft's runtime changes prevent managed code from running on the main JavaScript thread. Support may return in future .NET 10 previews.

Workarounds:

  • Use Task.Run for CPU-bound work (runs on thread pool when available)
  • Keep UI thread responsive with async/await
  • Avoid synchronous blocking calls

PWA Features

Service Worker

Configured automatically when PWA is enabled. Handles offline caching of app shell and assets.

Manifest

json
{
  "name": "My Uno App",
  "short_name": "UnoApp",
  "start_url": "./",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#6200EE",
  "icons": [
    { "src": "icon-192.png", "sizes": "192x192", "type": "image/png" },
    { "src": "icon-512.png", "sizes": "512x512", "type": "image/png" }
  ]
}

Install Prompt

PWA install is handled by the browser. Ensure manifest and service worker are correctly configured for the browser to show the install prompt.

Common Mistakes

  • Forgetting dotnet workload install wasm-tools before building
  • Using Microsoft.NET.Sdk.Web instead of Microsoft.NET.Sdk.WebAssembly with bootstrapper 9.x
  • Not setting proper MIME types on hosting server (especially application/wasm)
  • Expecting threading to work (not supported on .NET 9 Wasm)
  • Not adding inspectUri to launchSettings.json for debugging
  • Using deprecated bootstrapper properties from 8.x (see migration list in docs)

Detailed References