5

There are two backends for Flutter Web currently, namely HTML and CanvasKit. As a library author, for performance reasons, I would like to identify which backend the app is currently running on. Is there anyway to detect that in code?

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
First_Strike
  • 1,029
  • 1
  • 10
  • 27
  • Are you asking if your Flutter Website was build with CanvasKit or not? If you didn't compiled on release with the CanvasKit enabled flag, then you don't have CanvasKit enabled. Right now CK has many issues and most things wouldn't work. – Mariano Zorrilla Aug 01 '20 at 16:52
  • As I said, I am a library author. I have no control over which backend my customer will choose. – First_Strike Aug 01 '20 at 16:54
  • I don't think you currently can detect that easily as "no one" should be using CanvasKit for production websites... most things are broken. Big difference is that normal release mode has a Shadow DOM where HTML Elements are being render, the other one performance everyone on a canvas. Again, I don't think you can easily detect now without a proper method created from Google or the community. – Mariano Zorrilla Aug 01 '20 at 16:57

3 Answers3

10

Flutter 2.0 Update (Mar 2021)

Now that there is a new "auto" mode to choose web renderers. The correct way to check is described in https://github.com/flutter/flutter/issues/73369#issuecomment-760543461

import 'dart:js' as js;
final isCanvasKit = js.context['flutterCanvasKit'] != null;

(Credit: github.com/slavap)


After digging into issues in the Flutter repository, I found the answer myself

As of Aug 2020, you can detect whether the backend is CanvasKit by

const bool.fromEnvironment('FLUTTER_WEB_USE_SKIA', defaultValue: false)
First_Strike
  • 1,029
  • 1
  • 10
  • 27
  • `const bool.fromEnvironment('FLUTTER_WEB_USE_SKIA', defaultValue: false)` always returned false, for me. The original answer works, the answer given by @creativecreatorormaybenot is significantly improved/more usable for cross-platform. – Ben Roberts Jan 16 '23 at 18:08
5

On web, a flutterCanvasKit property will be added to the window when running with CanvasKit. This means that we can use dart:js to access the window via context and retrieve the property from there.

Boolean getter

To have a full example here, I want to expand on the GitHub comments and add a complete function with conditional support. The easiest way to set up the function is as a boolean getter:

import 'dart:js';

/// Whether the CanvasKit renderer is being used on web.
///
/// Always returns `false` on non-web.
bool get isCanvasKit => context['flutterCanvasKit'] != null;

This getter works only on web and will return whether you are running on CavasKit, according to @yjbanov.

Conditional logic

In order to make your app compile on non-web (mobile and desktop), you need to make sure to not import this file when not running on web.
The easiest way to do this is using conditional exports:

export 'canvas_kit_stub.dart' if (dart.library.html) 'canvas_kit_web.dart';

You store the line above in a file called canvas_kit.dart. Then, you store the getter from above in a file called canvas_kit_web.dart in the same directory. The last step is creating the stub file (canvas_kit_stub.dart) with the following contents:

/// Whether the CanvasKit renderer is being used on web.
///
/// Always returns `false` on non-web.
bool get isCanvasKit => false;

Importing

Now, you can simply import 'canvas_kit.dart'; (with the path pointing to the file you created) and this will work on both mobile, desktop, and web. You need to make sure to not import either the _stub or _web version.

creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
2

So I finally found it. I noticed that the HTML body contains a property called "fit-renderer" that specifies the renderer used. So you can use the following code

import 'dart:html' as HTML;

bool get usingHtmlRenderer =>
    html.document.body.getAttribute("flt-renderer").contains("html");

which returns "true" if you are using HTML renderer and "false" if you are using canvaskit.