Skip to content

Tree shake icon fonts with 0 icons retained #190902

Closed

Description

@dcharkes

The icon tree shaker skips tree shaking fonts that have 0 IconData const instances:

if (!families.contains(familyKey)) {
continue;
}

With the migration to @RecordUse() in #190225 the compiler got smarter and figured out more unreachable const instances than const_finder did, leading to some fonts now having 0 IconData instances instead of a small number of const instances.

So, we need to somehow signal to the icon tree shaker that something is an icon font instead of a normal font.

Context: #190225 (comment)

Thanks @gaaclarke for the report! 🙏

FYI @goderbauer @natebiggs @bkonyi

Activity

  1. dcharkes commented on Aug 11, 2026

    @dcharkes
    ContributorAuthor

    One issue is that the asset declaration in the pubspec.yaml does not specify if a font is an icon font or a normal font.

    flutter:
      fonts:
        - family: CupertinoIcons
          fonts:
            - asset: assets/CupertinoIcons.ttf

    and

    /// The effect of adding `uses-material-design: true` to the pubspec is to insert
    /// the following snippet into the asset manifest:
    ///
    /// ```yaml
    /// material:
    /// - family: MaterialIcons
    /// fonts:
    /// - asset: fonts/MaterialIcons-Regular.otf
    /// ```
    const kMaterialFonts = <Map<String, Object>>[
    <String, Object>{
    'family': 'MaterialIcons',
    'fonts': <Map<String, String>>[
    <String, String>{'asset': 'fonts/MaterialIcons-Regular.otf'},
    ],
    },
    ];

    If we move the icon fonts to DataAssets reported from the hook/build.dart as theorized in #174860 (comment), then we would know in those hooks which fonts are intended to be tree-shaken or not.

    We do have @staticIconProvider annotations, which were used by const_finder (but also didn't prevent 0-icon fonts). We could theoretically try to use these to identify the fonts, but it would require a complete extra pass over the codebase.

    We cannot do the following unfortunately:

    @RecordUse()
    class StaticIconProvider {
      final String fontFamily;
    }
    
    @StaticIconProvider(CupertinoIcons.iconFont)
    abstract final class CupertinoIcons { }

    Because @RecordUse() does not record annotations that are not runtime objects in the final program. (dart2js does not represent annotations as const instances.)

    A short-term workaround for the two built-in fonts is to hardcode the font names in the icon_tree_shaker.dart. That doesn't work for user-defined icon fonts (but it is probably less likely users transitively depends on a user-defined icon font and not use it all).

  2. added
    in triagePresently being triaged by the triage team
    toolAffects the "flutter" command-line tool. See also t: labels.
    team-toolOwned by Flutter Tool team
    and removed
    in triagePresently being triaged by the triage team
    on Aug 11, 2026
  3. added
    P1High-priority issues at the top of the work list
    triaged-toolTriaged by Flutter Tool team
    on Aug 11, 2026
  4. bkonyi commented on Aug 18, 2026

    @bkonyi
    Contributor

    Fixed by #190905.

  5. github-actions commented on Sep 1, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  6. locked as resolved and limited conversation to collaborators on Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority issues at the top of the work listteam-toolOwned by Flutter Tool teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-toolTriaged by Flutter Tool team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions