Wasm support in Flutter

Wasm support in Flutter

Wasm support in Flutter – With the release of Flutter 3.22, Wasm support is available in the Flutter stable channel, bringing substantial performance enhancements. 

Internal benchmarks, conducted using Chrome on an M1 MacBook, showed that the Wonderous app’s frame rendering time improved by an average of 2x and up to 3x in the worst-case scenarios.

Wasm support in Flutter
Wasm support in Flutter

These enhancements are crucial for applications featuring animations and rich transitions, where sustaining a smooth frame rate is imperative. Wasm mitigates performance bottlenecks, leading to smoother animations and transitions.

Wasm support in Flutter

A browser with WasmGC support is required to run a Flutter app compiled for Wasm.

  • Chromium and V8 introduced stable WasmGC support in Chromium 119. 
  • Firefox announced stable support for WasmGC in Firefox 120, but it currently doesn’t function due to a known limitation
Wasm support in Flutter
Wasm support in Flutter

What is Web Assembly?

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.

Web Assembly
Web Assembly
  1. Efficiency and Speed:
    The Wasm stack machine is crafted to be encoded in a compact binary format, optimizing both size and load times. 

2. Safety:
WebAssembly provides a memory-safe, sandboxed execution environment, and it can even be implemented within existing JavaScript virtual machines 

3. Openness and Debugging:
WebAssembly is structured to be easily readable in a textual format, facilitating debugging, testing, experimentation, optimization, learning, teaching, and manual program creation.

4. Part of the Open Web Platform:
WebAssembly is integrated into the open web platform, maintaining the version less

Getting Started

  1. Switch to the Flutter 3.22 stable or newer
  • To ensure you’re using the latest version of Flutter, run
flutter upgrade

To verify that your Flutter installation supports Wasm, run 

flutter build web - help

At the bottom of the output, you should see experimental Wasm options such as:

Experimental options
    --wasm                       Compile to WebAssembly (with fallback to JavaScript).
                                 See https://flutter.dev/wasm for more information.
    --[no-]strip-wasm            Whether to strip the resulting wasm file of static symbol names.
                                 (defaults to on)

2. Modify index.html

Make sure your app’s web/index.html is updated to the latest Flutter web app initialization for Flutter 3.22 and later.

3. Run flutter build web --wasm

To build a web application with Wasm, add the --wasm flag to the existing flutter build web command:

flutter build web --wasm

The command produces output into the build/web directory relative to the package root, just like the flutter build web command.

4. Serve the output with an HTTP server

Flutter Web Assembly uses multiple threads to render your application faster and with less jank. It utilizes advanced browser features that require specific HTTP response headers to achieve this.

Headers for Web Assembly
Headers for Web Assembly

5. Serve Wasm locally

If you don’t have a local HTTP server installed, you can use the dhttpd package

flutter pub global activate dhttpd

Then change to the build/web directory and run the server with special headers:

cd build/web
dhttpd '--headers=Cross-Origin-Embedder-Policy=credentialless;Cross-Origin-Opener-Policy=same-origin'
Server started on port 8080

6. Load it in a browser

If your configured browser meets the requirements, open localhost:8080 in the browser to view the app.

If the application doesn’t load:

  1. Check the developer console for errors.
  2. Validate a successful build with the typical JavaScript output.

Requires JS-interop to access browser and JS APIs

To support compilation to Wasm, Dart has modified its approach to enabling interop with browser and JavaScript APIs. This shift means that Dart code using dart:html or package:js will not compile to Wasm. Instead, Dart now offers new, lightweight interop solutions based on static JS interop:

  • package:web: Replaces dart:html (and other web libraries).
  • dart:js_interop: Replaces package:js and dart:js.

Most packages managed by the Dart and Flutter teams have been updated to be compatible with Wasm support in Flutter, such as package:url_launcher.

  • To check if a Wasm build failed due to incompatible APIs, review the error output. These often return soon after a build invocation. An API-related error should resemble the following:
Target dart2wasm failed: Exception: ../../../../.pub-cache/hosted/pub.dev/url_launcher_web-2.0.16/lib/url_launcher_web.dart:6:8: Error: Dart library 'dart:html' is not available on this platform.
import 'dart:html' as html;
       ^
Context: The unavailable library 'dart:html' is imported through these packages:

    web_plugin_registrant.dart => package:url_launcher_web => dart:html
    web_plugin_registrant.dart => package:url_launcher_web => package:flutter_web_plugins => dart:html
    web_plugin_registrant.dart => package:flutter_web_plugins => dart:html

What’s Next

As of Flutter 3.22, neither flutter run nor DevTools support Wasm. 

However, this feature has been implemented and will be available in the next stable release.