如何检测Flutter web中的CanvasKit或HTML渲染器?

5
目前Flutter Web有两个后端,分别是HTML和CanvasKit。作为一个库的作者,出于性能原因,我想确定应用程序当前正在运行的是哪个后端。是否有办法在代码中检测到这一点?

你是在问你的Flutter网站是否使用了CanvasKit吗?如果你没有在发布时使用CanvasKit启用标志进行编译,那么你就没有启用CanvasKit。目前CK存在许多问题,大多数功能都无法正常工作。 - Mariano Zorrilla
正如我所说,我是一个库的作者。我无法控制我的客户会选择哪个后端。 - First_Strike
我认为目前很难检测到,因为应该没有人会在生产网站中使用CanvasKit... 绝大部分功能都无法正常工作。最大的区别是正常发布模式具有影子DOM,其中HTML元素正在被渲染,另一个性能优秀但基于画布上的渲染方式。同样,我认为除非Google或社区创建了适当的方法,否则很难轻易地检测到。 - Mariano Zorrilla
3个回答

10

Flutter 2.0 更新(2021年3月)

现在有一个新的“auto”模式来选择 Web 渲染器。正确的检查方法在https://github.com/flutter/flutter/issues/73369#issuecomment-760543461中描述。

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

(来源:github.com/slavap)


在研究Flutter存储库中的问题后,我自己找到了答案。

截至2020年8月,您可以通过以下方式检测后端是否为CanvasKit:

const bool.fromEnvironment('FLUTTER_WEB_USE_SKIA', defaultValue: false)

const bool.fromEnvironment('FLUTTER_WEB_USE_SKIA', defaultValue: false) 对我来说总是返回false。原始答案可行,@creativecreatorormaybenot 给出的答案在跨平台方面显著改进/更易用。 - Ben Roberts

5
在Web上,当使用CanvasKit时,窗口将添加一个flutterCanvasKit属性。这意味着我们可以通过context访问窗口并从中检索该属性,使用dart:js

布尔值获取器

为了在此处提供完整示例,我想扩展GitHub评论并添加具有条件支持的完整函数。设置函数的最简单方法是作为布尔值获取器:
import 'dart:js';

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

这个getter只在web上工作,并且将返回您是否正在运行CavasKit,根据@yjbanov的说法

条件逻辑

为了使您的应用程序能够在非web(移动设备和桌面)上编译,您需要确保在不运行web时不要导入此文件。
最简单的方法是使用条件导出

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

你需要将上面的代码存储在名为canvas_kit.dart的文件中。然后,你需要将上面的getter存储在同一目录下的名为canvas_kit_web.dart的文件中。最后一步是创建存根文件(canvas_kit_stub.dart),其内容如下:
/// Whether the CanvasKit renderer is being used on web.
///
/// Always returns `false` on non-web.
bool get isCanvasKit => false;

导入

现在,您只需简单地import 'canvas_kit.dart';(路径指向您创建的文件),这将适用于移动设备、桌面和 Web。请确保不要导入_stub_web版本。


2

我终于找到了答案。我注意到HTML body中包含一个名为“fit-renderer”的属性,它指定了使用的渲染器。因此,您可以使用以下代码:

import 'dart:html' as HTML;

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

如果您使用HTML渲染器,则返回“true”,如果您使用Canvaskit,则返回“false”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接