A lot of people have noticed that flatpak apps sometimes start very slowly. Upon closer inspection you notice this only happens the first time you run the application. Still, it gives a very poor first time impression.
So, what is causing this, and can we fix it?
The short answer to this is font-cache generation, and yes, I landed a fix today. For the longer version we have to take a detour into how flatpak and fontconfig works.
All flatpak applications use something called a runtime, which supplies the /usr that the application sees. This contains a copy of the fontconfig library, but also some basic fonts in /usr/share/fonts. However, since the /usr from the host is covered, the app cannot see the fonts installed on the host, which is not great.
To allow flatpak applications to use system fonts flatpak exposes a read-only copy of the host fonts in /run/host/fonts. The copy of fontconfig shipped in the runtime is configured to look for fonts in this location as well as /usr.
Loading font files scattered in a directory like this is very slow. You have to open each font file to get the details of it, like the name, so you can properly select fonts. To avoid this fontconfig has a font cache, which is generated each time a font is installed (using the fc-cache tool). Flatpak exposes these caches to the application too.
Unfortunately the format of the fontconfig cache is using the absolute filename as the cache key, which breaks when we relocate the font files from /usr/share/fonts to /run/host/fonts. This means that the first time an application starts it has to open all the file and generate its own cache (which is later reused, so it only affects the first launch).
It would be much better if the existing cache on the host could be re-used, even when the directory name is changed. I’ve been working on a fix for this which has recently landed in fontconfig (and is scheduled to be released as 2.13.0 soon).
Today I landed the fix for this in the standard flatpak runtimes, which, coupled with using the new fontconfig version on the host, dramatically reduce initial launch times. For example, launching gedit the first time on my machine goes from 2 seconds to 0.5 seconds.
All users should automatically get the runtime part of the the fix, but it will unfortunately take some time until all distributions have moved to the new fontconfig version. But once its there, this problem will be fixed for good.
If you need to touch font dir to write a .uuid file, why not just write the cache data into a .fc-cache file right there? That would remove the need to find an association with a cache file written somewhere else.
The design of fontconfig is that caches are in their own directory, I don’t want to change everything.
But, also thats not quite as generic. For instance, if a font is added but the cache is not updated, then an application will detect the out-of-date cache and write their own, and they still need a key to refer to the directory, so the uuid (or pathname, but then no relocation) needs to be there.