技术经验谈 技术经验谈
首页
  • 最佳实践

    • 抓包
    • 数据库操作
  • ui

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 总纲
  • 整体开发框架
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

hss01248

一号线程序员
首页
  • 最佳实践

    • 抓包
    • 数据库操作
  • ui

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 总纲
  • 整体开发框架
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 学习资料

  • 技术选型

  • 要点

    • dart语言核心要点
    • 工程化

      • flutter依赖管理
      • flutter代码模板优化和禁用.android文件夹刷新
      • flutter客户端项目适配web做的一些工作
      • web跨域问题终结者
      • flutter编译流程修改
      • flutter工程的模块化架构
      • flutter web编译瘦身
        • 美团的 图标字体精简
          • 使用
        • 报错
        • 解决方式: 编译Android,然后替换调web编译里的字体文件:
          • 一键打包和替换脚本:
      • webview_flutter官方插件的增强-对inputfile和权限请求的支持
    • flutter异步
    • flutter工程化
    • flutter存储相关
    • flutter状态管理
    • flutter网络框架以及相关要点
    • flutter图片相关
    • flutter可观测性和调试
    • flutter插件开发
    • flutter路由管理
    • 遇到的问题
  • 经验

  • flutter
  • 要点
  • 工程化
hss01248
2023-06-07
目录

flutter web编译瘦身

# flutter web编译瘦身

# 缩减字体文件

# 美团的 图标字体精简

当访问 FlutterWeb 页面时,即使在业务代码中并未使用 Icon 图标,也会加载一个 920KB 的图标字体文件:MaterialIcons-Regular.woff。通过探究,我们发现是 Flutter Framework 中一些系统 UI 组件(如:CalendarDatePicker、PaginatedDataTable、PopupMenuButton 等)使用到了 Icon 图标导致,且 Flutter 为了便于开发者使用,提供了全量的 Icon 图标字体文件。

Flutter 官方提供的 --tree-shake-icons 命令选项是将业务使用到的 Icon 与 Flutter 内部维护的一个缩小版字体文件(大约 690KB)进行合并,能一定程度上减小字体文件大小。而我们需要的是只打包业务使用的 Icon,所以我们对官方 tree-shake-icons 进行了优化,设计了 Icon 的按需打包方案:

img

图23 图标字体精简

  1. 扫描全部业务代码以及依赖的 Plugins、Packages、Flutter Framework,分析出所有用到的 Icon;
  2. 把扫描到的所有 Icon 与 material/icons.dart(该文件包含 Flutter Icon 的 unicode 编码集合)进行对比,得到精简后的图标编码列表:iconStrList;
  3. 使用 FontTools 工具把 iconStrList 生成字体文件 .woff,此时的字体文件仅包含真正使用到的 Icon。

# 使用

flutter build web --web-renderer html --tree-shake-icons
1

# 报错

This application cannot tree shake icons fonts. It has non-constant instances of IconData at the following locations:
  - file:///Users/hss/dev/flutter-3.7.0/packages/flutter/lib/src/widgets/icon_data.dart:20:9
  - file:///Users/hss/.pub-cache/hosted/pub.dev/font_awesome_flutter-10.4.0/lib/src/icon_data.dart:9:9
  - file:///Users/hss/.pub-cache/hosted/pub.dev/font_awesome_flutter-10.4.0/lib/src/icon_data.dart:21:9
  - file:///Users/hss/.pub-cache/hosted/pub.dev/font_awesome_flutter-10.4.0/lib/src/icon_data.dart:33:9
  - file:///Users/hss/.pub-cache/hosted/pub.dev/font_awesome_flutter-10.4.0/lib/src/icon_data.dart:46:9
  - file:///Users/hss/.pub-cache/hosted/pub.dev/font_awesome_flutter-10.4.0/lib/src/icon_data.dart:66:9
  - file:///Users/hss/.pub-cache/hosted/pub.dev/font_awesome_flutter-10.4.0/lib/src/icon_data.dart:79:9
Target web_release_bundle failed: Exception: Avoid non-constant invocations of IconData or try to build again with --no-tree-shake-icons.

1
2
3
4
5
6
7
8
9
10

官方issuse: https://github.com/flutter/flutter/issues/57181

# 解决方式: 编译Android,然后替换调web编译里的字体文件:

For those who are looking for a quick fix can try this (opens new window) approach.

Step 1: Release an apk file with tree shake by using flutter build apk --release --tree-shake-icons Step 2: Go to /build/app/intermediates/assets/release/mergeReleaseAssets/flutter_assets/fonts/MaterialIcons-Regular.otf Step 3: Make sure it's size is in KBs Step 4: Copy that file and keep it on your desktop Step 5: Build your web app and replace the large file web/assets/fonts/MaterialIcons-Regular.otf

_This droped my icon size from 1.6MB to 2KB I used only 10 icons in the whole project

Tips: For a quick action, try to automate this process using makefile (opens new window)

Hope this helps someone.

image-20230607100931291

# 一键打包和替换脚本:

import 'dart:io';

import 'package:process_run/shell.dart';
/// 终极形态: 一键发布所有包,不用手动发布
main()  async {
  //buildAndroid();

  //packMacos();
  packWeb();

}


Future<void> packWeb() async {
  String fontPath = "${Directory.current.path}/build/app/intermediates/assets/release/mergeReleaseAssets/flutter_assets/fonts/MaterialIcons-Regular.otf";

  File file = File(fontPath);
  if(!file.existsSync()){
    print("android 打包treeshake的字体文件不存在,重新打包Android");
    await buildAndroid();
    print("android 打包成功,开始继续打包web");
    packWeb();
  }else{
    print("android 打包treeshake的字体文件存在,直接打包web,打包后拷贝字体");
    await buildWeb();
    //web/assets/fonts/MaterialIcons-Regular.otf
    File target = File("${Directory.current.path}/build/web/assets/fonts/MaterialIcons-Regular.otf");
    file.copySync(target.path);
    print("拷贝字体文件成功: ${target.path}");
    //todo  windows上,将web文件夹打包成zip,然后部署到服务器上

  }

}

Future<void>  buildWeb(){
 return exeShell("flutter build web --web-renderer html");
  //--tree-shake-icons: 会报错. 解决方式: 先编译Android,然后编译web,将Android里的字体icon覆盖掉web里
}



Future<void> buildAndroid(){
 return exeShell("flutter build apk --release --tree-shake-icons");
}




Future<void> buildMacReal() async {
  await buildMacOs();
  packMacos();
}

Future<void> buildMacOs(){
  return exeShell("flutter build macos --release --tree-shake-icons");

}

Future<void> packMacos(){
  return exeShell("hdiutil create -volname chatgpt -srcfolder ${Directory.current.path}/build/macos/Build/Products/Release/MyChatAI.app"
      " -ov -format UDZO ${getPCUserPath()}/Downloads/MyChatAI-release.dmg");
}

String getPCUserPath() {
  //var platform = Platform.isWindows ? 'win32' : 'linux';
  var homeDir = Platform.environment['HOME'];
  //var userDir = Platform.environment['USERPROFILE'] ?? '$homeDir\\AppData\\Local';

 // return Directory('$userDir\\$platform\\flutter').path; // 此处以 Flutter 为例
  return homeDir??"/";
}


Future<void> exeShell(String cmd) async {
  var shell = Shell(runInShell: true);

  try{
      await shell.run(cmd);
  }catch(e,s){
    //print("error1:"+e.toString());
    throw e;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
编辑 (opens new window)
上次更新: 2023/06/07, 19:50:10
flutter工程的模块化架构
webview_flutter官方插件的增强-对inputfile和权限请求的支持

← flutter工程的模块化架构 webview_flutter官方插件的增强-对inputfile和权限请求的支持→

最近更新
01
截图后的自动压缩工具
12-27
02
图片视频文件根据exif批量重命名
12-27
03
chatgpt图片识别描述功能
02-20
更多文章>
Theme by Vdoing | Copyright © 2020-2025 | 粤ICP备20041795号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式