Flutter web 最新进展: 发掘更多可能!

作者 / Mariam Hasnany, Product Manager, Flutter

差不多一年前,我们分享了 Flutter 针对 web 支持的首个技术预览版。我们对 Flutter 的愿景是提供一个便携式的工具包,让您在任何能绘制的界面上都能打造出精美的体验。对于无处不在的 web,Flutter 自然是尝鲜首选,但 web 的特性显然与 Android 和 iOS 这样的移动平台有相当大的区别。

让 Flutter 代码在浏览器中运行,为我们带来了各种有趣的可能性,包括:

  • 让开发者们可以轻松将现有的应用从移动端带向 Web 端 —— 不论是完整功能迁移版的应用、PWA (Progressive Web App),抑或是作为移动应用安装前的功能体验;

  • 让桌面应用开发者可以通过一次构建决定是以高性能的安装式桌面应用发布,还是以接受度更高、即用即走的网页应用形式发布;

  • 通过 DartPad 和 CodePen 这样的工具可以快速实验一些 Dart 代码,不需要在本地安装任何环境就能实时看到结果;

  • 在移动应用和 web 应用之间以最小的代价进行代码复用。

  • DartPad

    https://dartpad.dev/b3ccb26497ac84895540185935ed5825

  • CodePen

    https://codepen.io/topic/flutter/templates

从框架和 API 层面上来说,毫无疑问 Flutter 是以应用为中心的。我们相信 Flutter 为丰富多样的 web 开发解决方案提供了一种独树一帜的可能性。如果我们达成了这个愿景,Flutter web 会充分利用 web 平台提供的所有优势,让开发者能够在浏览器中打造出优美、丰富、自然的交互应用。

△ Ampstor: 无需代码即可创建更具表现力的网页,由 Flutter web 打造

Ampstor 就是一个强有力的示范。该团队致力于打造一套工具,让内容创作者们制作 AMP 故事 —— 这是一种全新的呈现形式,用于在移动设备上创作视觉叙事内容。Ampstor 团队在使用 Flutter web 后如此说道:

"我们是一个致力于帮助用户打造高度个性化体验的初创团队,因此将产品快速发布,并根据用户的反馈快速迭代至关重要。我们选择 Flutter,是因为它让我们得以将精力集中在产品而不是平台上。我们对目前的体验十分满意,用户也非常喜爱我们的应用。"

  • Ampstor

    https://ampstor.app/

  • AMP 故事

    https://amp.dev/about/stories/

我们给 web 支持设定的早期目标很直接: 证明 Flutter 框架可以移植到 web。去年夏天,我们将 web 代码合并回主框架中,使用单一代码库就可以支持移动端和 web 端 (还有桌面版!)。从那时起,我们的重点就转移到了利用 web 平台的最新功能来实现快速、无卡顿的性能表现,提高 Flutter 在各个平台的行为一致性,并彻底修复那些在 web 上感觉不自然的场景。

基于上述介绍,接下来我们将和大家分享自去年 12 月 Flutter web 发布 beta 版以来的最新进展。

进展一览

PWA 支持

Flutter 的 web 应用默认模板现已包含了可安装、可离线使用的 PWA 应用 (Progressive Web App) 所需的核心功能。

  • PWA

    https://web.dev/what-are-pwas/

△ Flutter的 "计数器" 模板应用,

在 macOS 中作为 PWA 运行

请注意,虽然看起来像是一个普通的桌面应用,但实际上它是一个 Flutter web 应用,它已经作为 PWA 安装到了浏览器中。您可以通过标题栏中额外出现的按钮发现二者之间的区别,这些按钮其实是 Chrome 的功能。基于 Flutter 的 PWA 的安装方式与其他基于 web 的 PWA 相同,您可以通过 manifest.json 将一个 Flutter 应用设置为 PWA,它由 web/ 子文件夹中的 flutter create 生成。

  • 如何将 PWA 设置为可安装

    https://web.dev/install-criteria/

主流的移动和桌面浏览器都支持 PWA。我们一直在努力打通原生平台和 web 之间的隔阂,PWA 则是努力的一个方向。

  • 打通原生与 web 应用

    https://www.youtube.com/watch?v=JKVZMqpiY7w

PWA 支持的开发仍在进行中,如果您发现了任何问题,请反馈给我们。

插件

当我们推出 beta 版时,只有少数插件支持 web。但从那时起,我们看到越来越多的插件增加了 web 支持。感谢社区的巨大贡献,例如: 

  • audioplayers: 同时播放多个音频文件

  • connectivity: 让应用发现网络连接并作出相应配置

  • cloud_firestore: 经由 Cloud Firestore API 访问的 NoSQL 云端数据库

  • cloud_functions: 使用 Firebase 提供的 Cloud Functions 服务

  • 您可以在这里找到以上 package

    https://pub.flutter-io.cn/flutter/packages?platform=web

我们计划维护一些 Google 开发的 web 插件,但很大程度上我们需要依靠社区来为现有的 package 提供 web 支持。为了帮助您上手实践,我们也发布了一系列文章,介绍如何编写 web 插件。

  • 如何编写 web 插件

    https://medium.com/flutter/how-to-write-a-flutter-web-plugin-5e26c689ea1

使用表达式计算进行 web 调试

调试是开发过程中的关键步骤,也是为丰富 Flutter web 体验积极开发的领域之一。如果您使用 VS Code 来开发 Flutter 应用的话,那么您可能会期待其拥有完整的 debug 功能,包括在调试窗口中使用表达式计算 (Expression Evaluation),使用观察 (watch) 功能,或将鼠标悬停在变量上查看其数值。

但直到最近,这些功能只能在调试移动端 Flutter 应用时使用。在过去的几个月,我们一直在努力让 Flutter web 支持计算表达式 (Evaluate Expression),现在已经完成了实验性的支持,可以在 VS Code 里试用。针对其他 IDE (如 IntelliJ) 的支持则还在开发中。

  • IntelliJ 支持

    https://github.com/flutter/flutter-intellij/issues/4519

这个功能在 Flutter dev 或 master 渠道提供。请按照如下步骤在 VSCode 中设置该功能:

为您的项目加入"web 运行" 的配置。在 VSCode 中修改 launch.json 为 web 开启表达式计算。

  • 使用 Flutter 构建 web 应用

    https://flutter.cn/docs/get-started/web

设置断点并开始调试。在调试控制台 (debug console) 窗口中通过表达式验证窗口 (如下图所示) 试试表达式计算功能。另外,您也可以使用观察 (watch) 窗口,或者将鼠标悬停在变量上来通过表达式验证您的代码。

您也可以试试设置使用表达式的条件断点:

测试

Flutter 的最新版本现在支持对 Flutter web 应用运行自动 Flutter Driver UI 测试,其运作方式与移动应用相同。请阅读 Flutter wiki 上的说明了解如何启用这个实验性功能。

  • 在 web 上运行 Flutter Driver 测试

    https://github.com/flutter/flutter/wiki/Running-Flutter-Driver-tests-with-Web

测试、品质以及性能

在过去的几个月里,我们的工作重点是改善 Flutter web 支持的基础设施、品质和渲染。虽然我们还有很多工作要做,但在这三个方面都取得了重大进展。

测试的基础设施和基准

构建测试基础设施是 Flutter 开发者不一定能看到的改进之一,但对于构建 Flutter web 支持的稳定版本来说却非常重要。

在过去的这个季度,我们增加了自动化测试,以确保 web 引擎和框架的正确性。我们增加了 Chrome 中的屏幕截图测试,以确保我们在修改代码的过程中保持渲染的一致性和正确性。我们现在还在 Chrome、Firefox 和 Safari 中运行单元和集成测试,这些测试也即将覆盖移动浏览器以及 Internet Explorer/Edge。我们还增加了性能基准测试,使我们能够在不造成回退的情况下快速迭代。

品质

我们一直在忙于解决各种问题,并通过优化和修正来稳步提升品质。

最近,我们在 Flutter web 支持中优化了静态内容的滚动,也就是说,内容不是延迟加载 (lazily loaded),而是全部在同一帧中呈现。这应该会使滚动性能更符合传统的 web 体验。

我们还修复了几个文本渲染问题,如文本在 canvas 后面消失,或多行文本的光标问题。这些文本问题的修正目前可以通过 FLUTTER_WEB_USE_EXPERIMENTAL_CANVAS_TEXT 来启用,我们计划尽快在平台上默认实现这些修正。

在去年的 Flutter Interact 大会上,我们宣布新的 Gallery 范例应用可以在 web 上通过 Flutter 运行。从那时起,我们就对 web 支持和该应用进行了大幅的性能优化,使其速度更快、运行更流畅。现在初始加载速度提升至 3 倍,下载的代码文件体积则减少了 62%。

△ Flutter Gallery 应用,在 Windows 作为 PWA 运行

请大家持续关注 Flutter 的更新,我们将分享更多经验,以及优化 Flutter 应用性能的最佳实践。在那之前,请大家亲自上手体验一下更新后的 Gallery 应用。

  • Gallery 应用

    https://gallery.flutter.dev

使用 CanvasKit 改进渲染

开始探索 web 的时候,我们考虑了各种渲染 UI 的方法。我们知道,最终的选择将决定我们在 web 上构建、布局和绘制 Flutter widget 的能力。

我们最初选择了基于 HTML DOM 的模型,结合了 HTML、CSS 和 Canvas API 来绘制 Flutter 框架输出的内容。我们将这个实现称为 DomCanvas 渲染系统。

  • Canvas API

    https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API

在过去的一年里,我们对 web 上各种渲染技术的性能和特征有了更多的了解,并尝试使用第二种方法,即 CanvasKit。CanvasKit 通过 WebAssembly 和 WebGL 将 Skia 带到了 web 上,实现了硬件加速的界面绘制,提升了高效渲染复杂密集图形的能力。

  • CanvasKit

    https://skia.org/user/modules/canvaskit

  • WebAssembly

    https://webassembly.org/

  • WebGL

    https://get.webgl.org/

  • Skia

    https://skia.org/

我们认为,DomCanvas 和 CanvasKit 在不同场景下各有优势,所以我们同时支持这两种渲染模型。

  • DomCanvas 提供了与各种浏览器的最大兼容性,且代码尺寸紧凑。但是,它的重绘性能较差,所以不太适合图形密集型应用;

  • CanvasKit 后端提供了卓越的性能、保真度和正确性,但由于代码文件体积较大,其初始启动时间会相对较长。

在默认情况下,Flutter web 支持使用 DomCanvas,但您可以通过这个命令启用 CanvasKit 渲染引擎:

flutter run -d chrome --release --dart-define=FLUTTER_WEB_USE_SKIA=true

有一点要注意: CanvasKit 引擎仍然存在一些打磨不周全的地方。对于正在将 Flutter 引入生产的早期采用者来说,DomCanvas 引擎是最稳定的。

已知的问题

我们相信我们正在打下良好的基础,此外我们还计划在其他几个方面继续努力,以夯实 web 支持的体验。

  • 桌面级的用户体验。在桌面浏览器上支持 Flutter 需要的不仅仅是 web 支持: 移动和桌面体验之间通常存在着明显的 UI 差异。因此,我们正在添加支持桌面级体验的功能,比如响应式 widget、滚动的物理效果等,这些功能仍然有待实现;

  • 自动补全 (autofill) 是大多数平台都支持的一个功能,对于 web 来说,它意味着允许浏览器存储数据,并在适当的地方补完填写。我们最近在核心框架中添加了初步的自动补全支持,现在我们正在努力将这个功能添加到 web 平台。这项工作包括解决浏览器差异问题,为将来的自动补全保存信息,将可自动补全的元素成组传递给引擎,等等;

  • URL 路由。也许这是个小问题: Flutter web 应用中都包含一个用于路由的 # 字符,即便是在首页。我们正在着手消除这个问题,并为 URL 路由提供更多的控制能力,已经有来自社区贡献的代码正在审核;

  • 代码体积仍然是需要积极研究的课题。今天,每个 Flutter web 应用都会下载它所需要的引擎代码。我们正在研究如何缓存其中的部分逻辑,以减少启动时间和下载量。

  • 响应式 widget

    https://material.io/components/navigation-rail/

  • 初步的自动补全支持

    https://github.com/flutter/flutter/pull/52126

  • 支持 web 平台的自动补全

    https://github.com/flutter/engine/pull/17986

  • 为将来的自动补全保存信息

    https://github.com/flutter/flutter/issues/55613

  • Flutter web 应用的所有 url 中都存在 # 字符

    https://github.com/flutter/flutter/issues/33245

  • 来自社区的贡献

    https://github.com/flutter/engine/pull/17829

行动起来

去年 12 月更新以来,我们取得了很多进展,希望这篇文章可以为您带来惊喜。也请您依然注意,Flutter web 支持依然处于 beta 阶段,性能和浏览器兼容工作仍在进行,请您在生产环境中谨慎部署。

如果您是第一次使用 Flutter 在 web 平台进行开发,请访问 flutter.cn/web 了解更多信息,并在 dartpad.cn 或 codepen.io/flutter 上试着编写代码。

最后,致正在开发 Flutter web 应用的开发者们,衷心感谢你们的支持和贡献。请大家不断尝试开发、提交问题并更新插件,让 Flutter 在 web 平台上熠熠生辉!

  • 提交问题

    https://github.com/flutter/flutter/issues/new?title=[web]:+%3Cdescribe+issue+here%3E&labels=%E2%98%B8+platform-web&body=Describe+your+issue+and+include+the+command+you%27re+running,+flutter_web%20version,+browser+version

  • 更新插件 

    https://medium.com/flutter/how-to-write-a-flutter-web-plugin-part-2-afdddb69ece6

鸣谢: Tim Sneath & Chris Sells

你可能感兴趣的:(Flutter web 最新进展: 发掘更多可能!)