You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter Web发布版本中排除默认字体优化页面加载速度

Flutter Web 冗余默认字体移除与加载优化方案

问题现状

  • Flutter Web应用平均加载时长达20秒,加载耗时占比详情:
    加载耗时占比详情截图
  • 排查定位到FontManifest.json配置文件、MaterialIcons-Regular.otf、CupertinoIcons.ttf两个默认字体文件拉取平均耗时达10秒。项目已接入Google Fonts,未使用上述默认字体,该部分资源加载属于无效流量与时间开销。
  • 已尝试以下方案均未生效:
    • 直接编辑FontManifest.json删除.otf、.ttf字体相关条目,该文件为构建自动生成,每次Flutter构建时都会被重写
    • 无法接受设置use-material-design: false的方案,需要保留Material Design其他组件能力
    • 修改pubspec.yaml中的fonts字段配置,未生效
    • 查阅公开技术资料,内容大多围绕字体显示异常问题,无对应加载优化方案

可落地解决方案

方案1:构建后自动裁剪冗余资源(推荐,无侵入、不影响框架功能)

该方案不修改Flutter SDK源码,在构建完成后自动删除无效字体、重写字体清单,从根源上取消这两个资源的加载请求。
操作步骤:

  • 在项目根目录新建后置构建脚本post_build.dart,代码如下:
import 'dart:io';
import 'dart:convert';

void main() async {
  final webBuildDir = Directory('build/web');
  // 删除冗余字体文件
  const redundantFontPaths = [
    'assets/fonts/MaterialIcons-Regular.otf',
    'assets/fonts/CupertinoIcons.ttf'
  ];
  for (final path in redundantFontPaths) {
    final file = File('${webBuildDir.path}/$path');
    if (await file.exists()) {
      await file.delete();
    }
  }
  // 重写FontManifest.json,移除冗余字体条目
  final manifestFile = File('${webBuildDir.path}/FontManifest.json');
  if (await manifestFile.exists()) {
    final List manifest = jsonDecode(await manifestFile.readAsString());
    manifest.removeWhere((fontConfig) {
      final family = fontConfig['family'].toString();
      return family == 'MaterialIcons' || family == 'CupertinoIcons';
    });
    await manifestFile.writeAsString(jsonEncode(manifest));
  }
}
  • 替换原有构建命令,将构建与后置裁剪逻辑绑定执行:
flutter build web --release --tree-shake-icons && dart run post_build.dart

如果项目中用到少量Material/Cupertino图标,不要直接全量删除字体,可替换为SVG图标或图标字体分片加载方案,避免加载完整的大体积图标字体。


方案2:静态资源配置优化(不删除资源的前提下降低加载耗时)

如果暂时不想移除默认字体,可通过部署层配置大幅降低TTFB与资源下载耗时:

  • 开启压缩:在Nginx/CDN层开启gzip、brotli压缩,上述两个字体文件原始体积合计约3MB,压缩后可降至1.2MB以内,下载耗时降低60%以上。Nginx配置参考:
gzip on;
gzip_min_length 1k;
gzip_types font/otf font/ttf application/json application/javascript text/css;
brotli on;
brotli_types font/otf font/ttf application/json application/javascript text/css;
  • 配置强缓存:给字体文件、FontManifest.json这类带hash的静态资源设置7天以上的强缓存规则,用户二次访问时直接从本地缓存读取,不会重新发起请求。
  • 调整资源加载优先级:在web/index.html的head标签中,给实际使用的Google Fonts添加预加载标签,将非关键的默认字体加载优先级调低,避免阻塞首屏渲染。
  • 构建时开启图标树摇:Flutter 3.0及以上版本支持--tree-shake-icons构建参数,构建时会自动剔除代码中未引用的图标数据,最终打包生成的字体文件体积可缩小70%以上。

方案3:修改SDK源码永久移除默认字体引用(适合固定Flutter版本的项目)

如果不想每次构建都执行后置脚本,可直接修改本地Flutter SDK的默认字体配置:

  1. 进入本地Flutter SDK目录,打开packages/flutter/lib/src/material/icons.dart文件,删除文件头部@FontManifest注解中指向MaterialIcons-Regular.otf的配置项
  2. 打开packages/flutter/lib/src/cupertino/icons.dart文件,删除文件头部@FontManifest注解中指向CupertinoIcons.ttf的配置项
  3. 执行flutter clean清理缓存后重新构建,生成的FontManifest.json将不再包含这两个字体条目,也不会自动打包对应字体文件
    注意:该修改会在Flutter SDK升级后被覆盖,升级后需要重新操作。

内容的提问来源于stack exchange,提问作者Drewena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 08:03:28