跳到主内容

Web 常见问题

在 Flutter 中编写或运行 Web 应用时的一些注意事项和区别。

常见问题

#

哪些场景最适合使用 Flutter Web?

#

并非所有的网页都适合用 Flutter 开发,但我们认为 Flutter 特别适合以应用为中心的体验:

  • 渐进式 Web 应用 (PWA)
  • 单页应用 (SPA)
  • 现有的 Flutter 移动应用

目前,Flutter 不适合用于内容丰富、基于流式布局的静态网站。例如,博客文章更受益于 Web 原生的文档中心模型,而不是像 Flutter 这样的 UI 框架所能提供的以应用为中心的服务。不过,你可以使用 Flutter 将交互式体验嵌入到这些网站中。

有关如何使用 Flutter Web 的更多信息,请参阅 Flutter 的 Web 支持

搜索引擎优化 (SEO)

#

总体而言,Flutter 面向的是动态应用体验。Flutter 的 Web 支持也不例外。Flutter Web 优先考虑性能、保真度和一致性。这意味着应用输出的内容与搜索引擎正确索引所需的内容并不一致。

不过,由社区发布的 Dart 包 Jaspr 确实支持静态网站。事实上,Dart 文档Flutter 文档Flutter 营销 网站都已经迁移到使用 Jaspr 包。

总结一下,对于静态或文档类 Web 内容,我们建议使用:

  1. Jaspr:如果你想使用 Dart,但想要一个传统的基于 DOM 的网站。另请注意,Jaspr 的 SEO 工作方式与传统网站相同。
  2. HTML:在这种情况下,请考虑将你的主要应用体验(使用 Flutter 创建)与落地页、营销内容和帮助内容(使用搜索引擎优化的 HTML 创建)分开。

热重载 (Hot reload) 在 Web 应用中可以使用吗?

#

可以!有关更多信息,请查看 Web 上的热重载

Flutter 支持哪些 Web 浏览器?

#

Flutter Web 应用可以在以下浏览器上运行:

  • Chrome (移动端和桌面端)
  • Safari (移动端和桌面端)
  • Edge (移动端和桌面端)
  • Firefox (移动端和桌面端)

在开发过程中,Chrome (在 macOS、Windows 和 Linux 上) 和 Edge (在 Windows 上) 是调试应用时支持的默认浏览器。

我可以在任何 IDE 中构建、运行和部署 Web 应用吗?

#

你可以在 Android Studio/IntelliJ 和 VS Code 中选择 ChromeEdge 作为目标设备。

设备下拉菜单现在应该包含所有渠道的 Chrome (web) 选项。

如何构建适配 Web 的响应式应用?

#

请参阅 创建响应式应用

我可以在 Web 应用中使用 dart:io 吗?

#

不能。在浏览器中无法访问文件系统。对于网络功能,请使用 http 包。请注意,安全性的工作方式有所不同,因为是浏览器(而不是应用)控制 HTTP 请求的标头。

如何处理 Web 特有的导入?

#

某些插件需要平台特有的导入,特别是如果它们使用了浏览器无法访问的文件系统时。要在应用中使用这些插件,请参阅 dart.dev 上关于 条件导入的文档

Flutter Web 支持并发吗?

#

Dart 对使用 Isolate 的并发支持目前在 Flutter Web 中尚不支持。

Flutter Web 应用可以通过使用 Web Workers 来绕过此限制,尽管这种支持并非内置的。

如何部署 Web 应用?

#

请参阅 准备 Web 应用以进行发布

Platform.is 在 Web 上可以使用吗?

#

不能。虽然在为 Web 编译时从技术上可以导入 dart:io,但调用任何 Platform.isXYZ 方法都会抛出 UnsupportedError。此外,在包中导入 dart:io(除非通过条件导入)会导致 pub.dev 将该包评定为不支持 Web。

  • 如果你正在开发 Flutter 应用,请考虑使用 kIsWeb
  • 如果你正在开发包(特别是没有 Flutter 依赖的包),请考虑使用 os_detect 包。

为什么我的应用在部署后没有立即更新?

#

你可能需要配置 Web 服务器返回的 Cache-Control 标头。例如,如果该标头设置为 3600,则浏览器和 CDN 会将资源缓存 1 小时,这意味着在你部署新版本后,用户可能会在长达 1 小时内看到旧版本的应用。有关 Web 缓存的更多信息,请查看 使用 HTTP 缓存防止不必要的网络请求

了解这种行为很有必要,以避免产生糟糕的用户体验。在你部署应用后,用户可能会在缓存标头定义的持续时间内使用应用的缓存版本(由浏览器或 CDN 缓存)。这可能导致用户使用的版本与已部署到后端服务的更改不兼容。

如何在部署后清除 Web 缓存并强制重新下载应用?

#

如果你希望在每次部署后突破这些缓存标头,一种常见的技术是在静态资源的链接后面附加某种构建 ID,或者直接更新文件名。例如,logo.png 可以改为 logo.v123.png

html
<!-- Option 1, append build ID as a query parameter in your links -->
<script src="flutter_bootstrap.js?v=123" async></script>

<!-- Option 2, update the filename and update your links -->
<script src="flutter_bootstrap.v123.js" async></script>

Flutter 目前不支持自动在资源后面附加构建 ID。

如何配置我的缓存标头?

#

如果你使用的是 Firebase Hosting,共享缓存 (CDN) 会在你部署应用新版本时失效。但是,为了确保浏览器不缓存应用脚本而共享缓存可以缓存,你可以按如下方式配置缓存标头:

json
{
  "hosting": {
    "headers": [
      {
        "source":
          "**/*.@(jpg|jpeg|gif|png|svg|webp|css|eot|otf|ttf|ttc|woff|woff2|font.css)",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "max-age=3600,s-maxage=604800"
          }
        ]
      },
      {
        "source":
          "**/*.@(mjs|js|wasm|json)",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "max-age=0,s-maxage=604800"
          }
        ]
      }
    ]
  }
}

如何配置 Service Worker?

#

flutter build web 生成的 Service Worker 已被弃用,你可以通过在运行 flutter build web 命令时将 --pwa-strategy 标志设置为 none 来禁用它。

flutter build web --pwa-strategy=none

如果你想继续使用 Service Worker,可以自行构建或尝试第三方工具,例如 Workbox

如果你的 Service Worker 没有刷新,请通过将 Cache-Control 标头设置为较小的值(例如 0 或 60 秒)来配置你的 CDN 和浏览器缓存。