question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Poor performance for `<Resource>` fonts

See original GitHub issue
  • .NET Version: 6.0
  • Windows version: Windows 10 21H2 (19044.1526)
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes

Problem description:

When using a font that is embedded as a <Resource> (see fonts as resource items), the performance of rendering text can be extremely poor.

This was first noted in a production .NET 4.8 WPF Application; a detailed writeup of the problem and a solution that was found is at https://faithlife.codes/blog/2019/06/improving-wpf-text-display-performance/.

Actual behavior:

dotTrace shows that very large amounts of time are spent in MS.Internal.Text.TextInterface.FontFileStream.ReadFileFragment. Additionally, large amounts of memory are allocated and the program spends a lot of time in GC.

image

Expected behavior:

Rendering a <Resource> font is extremely efficient because the resource is already mmap’ed into memory and returning its data could be as simple as a pointer addition.

Minimal repro:

An example repro is at https://github.com/bgrainger/EmbeddedFontPerformance. Clone the repo, build the code, and scroll the text box. You’ll notice that it can take several seconds to draw the next screen of text (depending on how large the window is).

The following text complements that repo and describes how it reproduces the problem:

This reproduces most easily with the Noto Sans CJK font (perhaps because of the large number of glyphs that have to be read?).

Embed the font:

  <ItemGroup>
    <Resource Include="NotoSansCJKtc-Regular.otf" />
  </ItemGroup>

Then create a text box that references the font and contains a large amount of Chinese text:

    <Grid>
        <ScrollViewer>
            <TextBlock FontFamily="./#Noto Sans CJK TC" TextWrapping="Wrap">
            <!-- place Chinese text here -->
            </TextBlock>
        </ScrollViewer>
    </Grid>

Run the app and scroll the ScrollViewer.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
kant2002commented, Mar 13, 2022

@bgrainger send PR to C++ part. I think that way we can hedge if DWrite rewrite in C# get stalled indefinitely. Also if you can measure improvements somehow that helps advocate for the fix

1reaction
bgraingercommented, Mar 10, 2022

That being said, the changes looks like a good idea but there is a risk with those changes, due to the fact that it would not copy in a new array.

As long as the array isn’t deallocated before ReleaseFileFragment is called, there is no risk. AFAIK, the UnmanagedMemoryStream returned for resources is a pointer to the resource within the DLL that’s loaded into the process’ address space, so this can’t happen.

As per the blog post in the OP, a “hack” that implements this solution has been shipping (with no problems) in Logos for years, so I feel confident in this solution.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Best practices for fonts - web.dev
There are a variety of ways in which web fonts impact performance: ... If you have slow servers, don't use a CDN, or...
Read more >
How to load web fonts to avoid performance issues and ...
This causes a lot of problems for page loading like performance issues, slow loading time, blocked rendering and swapped fonts during navigation.
Read more >
10 ways to speed up web font loading
Sadly, it is terrible for performance. Performance is bad because Google Fonts has a complicated string of requests to get a font, ...
Read more >
Understanding How to Minimize Web Fonts' Negative ...
Large font files lead to Total Blocking Time (TBT) issues, slow down the rendering process, and increase the web page paint time. Essentially, ......
Read more >
Preventing the Performance Hit from Custom Fonts
The issue is 1) custom fonts are awesome and we want to use them 2) custom fonts slow down our pages by being...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found