作者 / Mariam Hasnany, Product Manager, Flutter
咱们对 Flutter 的愿景是成为一个可移植的 UI 框架,在全平台上构建精美的利用体验。做为 Flutter 2 公布内容的一部分,Flutter 的 web 反对曾经到达稳定版里程碑。
Flutter 的首个版本反对 iOS 和 Android,开发者们曾经用它在挪动利用商店公布了超过 15 万个利用。当初,随着 web 反对的退出,这些利用能够触达更宽泛的受众,同时也开拓了在 web 上建设交互体验的新途径。
在此次初始版本的 web 反对中,咱们次要关注三个利用场景:
- 渐进式 web 利用 (Progressive web apps, PWA),兼具 web 的高覆盖面与桌面利用的弱小性能。
- 单页利用 (Single page apps, SPA),只需一次加载,并与互联网服务动静互传数据。
- 将现有 Flutter 挪动利用拓展到 web,在两个平台共享代码。
这篇文章介绍了咱们迄今为止的工作成绩,并分享了几个案例,意在帮忙开发者在本人的利用中活用 Flutter 对 web 的反对。
△ iRobot Education 应用 Flutter 开发了 iRobot Coding 利用,通过此 web 利用向公众提供编程学习体验
Web 之旅
现在的 web 平台比以往任何时候都要丰富多彩,开发者能够应用的工具包含: 硬件加速的 2D 和 3D 图形,离线性能和装置体验,以及 对底层操作系统和硬件的拜访 等。在 web 这个底层平台上曾经建设起了 品种繁多的框架,因而,开发者在创立 web 利用时领有极大的灵活性。
Flutter 是用 Dart 编写的,而 Dart 能编译成 JavaScript,所以咱们的下一步天然就是要探讨反对 web 平台的可能性。这合乎咱们的愿景,也就是提供一个可移植的框架,不便您在任何能描述像素的中央构建出精美的 UI。
咱们的办法是,建设一个在所有平台上都能应用的统一的工具包 (而不是建设两个有着各种奥妙差别的独立框架),以确保开发者的代码运行时不会出现意外。
Flutter 框架由 一系列层构造 组成,其中蕴含:
- 框架,用于为 widget、动画和手势等常见的习惯用法提供形象
- 引擎,应用公开的零碎 API 在指标设施上进行渲染
框架自身采纳 Dart 编写,大概 70 万行 Flutter 框架外围代码在所有平台上雷同: 包含挪动端、桌面端和当初的 web 端。对于您的代码来说也是这样,咱们应用 Dart 开发编译器 (dartdevc) 或 Dart 部署编译器 (dart2js) 将您的代码编译成 JavaScript,这些 JavaScript 代码能够托管在服务器上。
因为 Dart 领有将 Flutter 框架 (以及开发者的利用代码) 编译成 JavaScript 的能力,咱们对 web 的反对工作就变成了用映射 web 平台 API 的代码来取代挪动利用所应用的底层 C++ 渲染引擎。Flutter 并不会简略地将 widget 移植为 HTML 里的等价组件,Flutter 的 web 引擎为开发者提供了两种渲染器: 一个是针对尺寸和兼容性进行优化的 HTML 渲染器,另一个则是应用 WebAssembly 和 WebGL 通过 Skia 绘图命令向浏览器画布进行渲染的 CanvasKit 渲染器。
咱们对 Flutter 的要求是,提供一种针对 web 平台进行开发的新形式,在现有根底上提供新见解,为所有人提供更棒的 web 体验。
公布生产环境可用的稳固版本
自从 web 反对的测试版 在一年前公布以来,咱们曾经理解了很多晚期采纳者的应用状况,并已与局部客户单干,他们当初曾经将本人的 Flutter web 利用投入生产。
在此期间,咱们对架构进行了重大改良,减少了一些性能,以便扩大和优化 Flutter 的 web 反对,新增内容次要集中在四个方面: 性能 、web 专属性能、 桌面硬件适配 ,以及 插件。
性能
自推出晚期版本至今,性能是晋升最显著的。在开发过程中,咱们对 web 上各种渲染技术的性能和准确性特色有了更深刻的理解。
咱们最早的工作是基于 DOM 的 HTML。在这种渲染模式中,Flutter 的 web 引擎会将每个生成的 Flutter 场景转换为 HTML、CSS 或 Canvas,并以 HTML 元素树的模式在页面上渲染为一帧。尽管 HTML 渲染器可能最大限度地兼容各种浏览器,且其代码体积较小,但 HTML 渲染器的重绘性能不太适宜 Rive (应用 Flutter 构建而成,用于创立动静图像的合作工具) 这种图形密集型利用。
△ Rive 是一款创立自定义动画的工具,该团队已应用 web 版 Flutter 从新构建利用,并公布了测试版
为了提供高效渲染密集图形所需的保真度,咱们开始尝试应用 CanvasKit,它可应用 WebAssembly 和 WebGL 通过 Skia 绘制命令在浏览器中进行渲染。咱们发现 CanvasKit 渲染器的性能、保真度和准确度都更加现实,请看 Flutter 社区中才华横溢的德国开发者 Felix Blaschke 的 Flutter Plasma 演示——用 CanvasKit 发明的惊艳特效。
△ Flutter Plasma 是由 Felix Blaschke 创立的演示,可在 Safari、Firefox、Edge 和 Chrome 上运行
不同的渲染器在不同场景下各有劣势,因而 Flutter 同时反对以下两种渲染模式:
- HTML 渲染器: 联合了 HTML 元素、CSS、Canvas 和 SVG。该渲染模式的下载文件体积较小。
- CanvasKit 渲染器: 渲染成果与 Flutter 挪动和桌面端完全一致,性能更好,widget 密度更高,但减少了约 2MB 的下载文件体积。
为了针对每个设施的个性优化您的 Flutter web 利用,渲染模式默认设置为主动。这意味着您的利用将在挪动浏览器上应用 HTML 渲染器运行,在桌面浏览器上应用 CanvasKit 渲染器运行。
您还能够应用 –web-renderer html 或 –web-renderer canvaskit 来明确抉择应用何种渲染器。如需理解详细信息,请参阅 官网文档。
Web 专属性能
在浏览器中运行的 Flutter 利用给人的感觉应该像 web 利用一样。所以咱们为 Flutter 增加了一些性能,帮忙您施展 web 的劣势。
Web 有很多劣势,尤其是在寰球的覆盖率。将您现有的 Flutter 利用带到 web 上的起因之一就是接触利用商店以外的用户。为了做到这一点,咱们增加了 自定义 URL 策略,以确保您的用户只需点击 URL,就能够从任何中央拜访您的利用。有了这个性能,您就能够管制地址栏中显示的 URL,以及您的利用在 web 上的路由。
△ Flutter Plasma 演示的 Showroom 页面,实际上就是一个基于 Flutter 自定义 URL 策略的 url_strategy 插件示例
当用户在 web 上导航时,超链接也至关重要。url_launcher package 中的一个新的 link widget 使用户可能通过深链接中转您利用内的锚点或内部网站。您能够在相干的 widget 上应用 link,包含按钮、内联文本、图像,并指定链接是在同一个标签页还是新标签页中关上。
对于任何利用来说,文本渲染都是不可或缺的。开发文本布局零碎,是构建 Flutter web 反对所面临的重大挑战之一。因为 web 不足间接文本布局 API,Flutter 必须通过触发 layout() 来对 Parapraph 执行各种测量操作。有时,这些测量的代价相当昂扬,所以咱们增加了 基于 Canvas 的文本测量,此测量形式可同时反对纯文本与富文本。当初,Flutter 能够在 web 上高效地实现精密测量,进而实现正确的绘制工作,比方正确地高亮显示所选文本。
与文本进行交互同样重要,其重要性不亚于疾速精确地渲染文本。通过 SelectableText 和 EditableText widget,您不仅能够选中 Flutter web 利用中的文本,还能够执行复制粘贴操作。此外,表单文本字段现已反对 主动填充,浏览器可能存储数据以便未来填充应用。
Flutter 2 特地适宜实现渐进式 web 利用 (PWA)。咱们倡议开发者应用 PWA,通过 Chrome 的 Project Fugu,以平安和可信的形式,弥合挪动端和 web 端利用之间的差别。
△ 发票治理利用 Invoice Ninja 推出的 PWA 利用与他们现有的 Flutter 挪动利用应用雷同的代码库
在创立 Flutter Web 利用时,咱们会提供 PWA web 清单文件,以及用来设置 service worker (工作线程) 的代码。清单文件提供了对于利用应该如何运行的元数据,包含图标和利用题目等信息。Service workers 能够实现资源的缓存和利用的离线运行。当您在浏览器中以 PWA 的模式运行 Flutter 利用时,您能够将其作为挪动或桌面利用装置到您的设施上。
适配各类桌面设施
只管浏览器的状态大小各异,咱们都心愿提供美妙的 Flutter web 体验。因为 Flutter 最后是为挪动利用设计而成,因而 Flutter web 利用曾经对挪动浏览器的手势和滚动物理成果提供了很好的反对。但桌面浏览器 UI 的出现和应用有所不同,所以咱们对 Flutter 进行了相应的更新。
比方,用户心愿利用在桌面浏览器中运行时可能显示滚动条,以便通过鼠标或键盘进行管制。咱们为桌面设施增加了 可自定义的交互式滚动条.docx),这意味着咱们可为滚动条应用 主题,显示滚动条轨道,而且还能够拖动滑块。咱们还扩大了 PrimaryScrollController,便于用户 应用键盘快捷键进行滚动.docx),也省去了您应用自定义滚动视图的工作。
△ Spica Technologies 为 Zurich Insurance 构建的物业管理解决方案,这是用 Flutter web 为商务和桌面设施用户构建利用的卓越示例
此外,因为鼠标指针能进行互动的内容密度大于触摸设施,咱们晋升了 默认内容密度。咱们还在框架中增加了反对各种平台的 零碎鼠标光标 合集。
最初,为让 Flutter web 反对所有用户,咱们还扩大了 Flutter 的 web 语义性能来反对 Windows、macOS 和 chromeOS 零碎上的无障碍性能。为了在 web 上实现无障碍体验,咱们在 RenderObject DOM 树之外平行生成了一个相似的 DOM 树,叫 SemanticsNode 树。SemanticsNode 树可将标记、操作、标签和其余语义属性转换成 ARIA 属性。当初,您能够通过 Narrator、VoiceOver、TalkBack 或 ChromeVox 屏幕阅读器来应用 Flutter web 利用。
Flutter web 对插件的反对
最初,咱们为那些最罕用的插件带来了 web 反对,使您可能将本人的 Flutter 利用带到 web 平台。借助 Flutter 插件,您的代码可与所运行平台的原生开发库进行互操作。在 web 上运行 Flutter 利用时,您能够通过插件拜访现有的 JavaScript 库。
自测试版公布以来,咱们在社区的帮忙下为以下插件增加了 web 反对:
- image_picker
- google_maps
- firebase_analytics
- firebase_storage
- connectivity
- cloud_firestore
- cloud_functions
- cross_file
展望未来
几年前,咱们还没方法在 web 上以可承受的品质和性能提供 Flutter。然而,web 新技术的呈现和平台的不断进步,使咱们得以纵情开释底层设施的后劲。在反对 web 之后,Flutter 得以涵盖互联网上的每一台设施,让用户在所有古代浏览器和设施上都能取得统一的体验。
这个版本的相当一部分内容来自晚期 web 用户的反馈信息和社区提交的 issue,这里咱们要再次感激大家的奉献!今后,咱们的首要指标是疾速解决大家的反馈,并及时解决 issue,以便大家专一于在所有指标平台上公布高质量的 Flutter 利用。
△ Moi Mobiili 是一家古代挪动虚构网络运营商,最近应用 Flutter 推出了他们的 web 利用
性能的晋升永无止境。咱们的指标是缩小代码体积,进步帧率体现 (fps)。现在,每个 Flutter web 利用都只会下载它必须的引擎代码。咱们正在钻研缓存局部逻辑的可能性,以缩小启动工夫和下载文件体积。咱们最近在 Flutter Gallery 演示利用中尝试应用提早库来缩小代码体积,置信很快就能同大家分享咱们的停顿。
在将来几个月内,咱们还筹备持续欠缺下列畛域:
- 尽管 CanvasKit 很稳固,但还有一些边界用例存在问题,比方特殊字符的 字体回退,以及对 跨域资源共享 (CORS) 图像的相应反对等。
- PWA 目前 只缓存了资源的一个子集,齐全的离线反对依然须要 额定的手动步骤,能力失常适配 CanvasKit。
- 文本渲染和性能,比方对款式设置较为简单的文本的选取,仍是咱们要持续致力解决的性能之一。
- 咱们也会持续致力改善插件生态系统,让 Google 公布的 package 在挪动端和 web 端更加对立。
△ Simplebet 通过 Flutter 的 web 反对,在 Fanduel 现有的挪动利用套件中构建了高度互动的嵌入式 NFL 和 NBA 投注体验
即刻开始应用 Flutter web
借助 Dart 的可移植性、Web 平台的弱小性能,以及 Flutter 框架的灵活性,您当初能够用同一套代码库,构建用于 iOS、Android 以及浏览器的利用。
如果您曾经开发了 Flutter web 利用,当初就能够在 稳固渠道 中进行构建。如果您刚开始学习构建 Flutter web 利用,请移步官网文档拜访咱们的 入门 codelab 课程,以及 Flutter Engage 上的 web 演讲。构建 web 利用时,如果您发现了任何问题,请随时 返回 GitHub 提交给咱们。
咱们十分期待看到您应用 Flutter web 所构建的精彩利用!