Karl Tomlinson

Thursday, December 11, 2008

I mentioned a couple of months ago that there was room to improve Firefox's memory use for font handling on Linux. With Firefox 3.1 Beta 2, you can now enjoy these improvements.

In the graph you can see how the memory use of Firefox on Linux has changed during development for Firefox 3.1. The y-axis represents the average resident physical memory in bytes used by the Firefox process while cycling through 400 or so pages 5 or 10 times.

There are six traces here. The three overlapping traces that are steady at 128 MB until 26 September, and then jump to a steady 132 MB, track the memory use of Firefox 3.0. The 4 MB jump is not actually a change in the application but a change to the test producing the data. The important thing is that the same test is also run on the development builds.

The other three overlapping traces track Minefield during its development for Firefox 3.1. At the end of August, memory use was very similar to Firefox 3.0.

The 10 MB wobbles in the first half of September were due to glibc's memory allocator accidentally being used instead of jemalloc, and it looks like there was a memory leak introduced on 9 September that took a couple of days to plug.

These changes add up to Firefox 3.1 Beta 2 using only 64% of the memory used by Firefox 3.0 (for this particular test).

Some of the memory savings from font selection redesign followed from performance improvements that meant that less caching was required to maintain responsiveness, but much of the savings came from taking more care in managing font data from fontconfig.

Fontconfig serves more than one purpose: it provides configuration that gives users excellent control over which fonts they prefer and how they like their fonts rendered, and it also provides an automatically updated database of properties of every font installed on the system.

The font property database is shared by applications so that its use can be memory efficient. However, sharing the data is only possible while using the data in a read-only manner. If data is modified from its format in the database, it must be copied.

Functions such as FcFontRenderPrepare, FcFontSetMatch, and FcFontSetList modify the data, and so return copies. It is best to avoid holding onto these copies for longer than necessary. On the other hand, functions such as FcConfigGetFonts and FcFontSetSort return references to shared data. Much of the memory savings mentioned above were achieved by keeping references to shared data instead of copies of modified data.

Wednesday, December 10, 2008

Firefox 3.1 Beta 2 includes several important performance improvements, but one improvement that is specific to platforms using GTK+ and fontconfig (such as Linux) can be noticed while zooming pages with a large number of fonts.

The difference is very clear if you run Firefox versions 3.0 and 3.1 Beta 2 concurrently and openhttp://wikipedia.org/ in each. If the number of fonts on your system is similar to the number on my system, you can type Ctrl-+ in version 3.0, then have time to switch focus to type Ctrl-+ in version 3.1 Beta 2, and 3.1 Beta 2 will be displaying the page larger before version 3.0.

The effect is very noticeable on Wikipedia due to the large number of fonts for the different languages, but the effect is also visible on pages that display text in a number of different sizes and styles.

There are several improvements contributing here, but one of the recent improvements comes from a change in the way fontconfig is used to perform font selection.

Typically applications using fontconfig construct an FcPattern *pattern containing a set of requested properties for the font. Next, user preferences and defaults are applied to the pattern using FcConfigSubstitute, and then either FcFontSetMatch or FcFontSetSort is used to find the font on the system that most closely matches the requested properties.

When all default font families have been included in the pattern, there are around 80 family names (as well as other properties), each of which is compared against names for every font on the system. For a system with 500 fonts (which is not unusual) that is about 40000 (case-insensitive) string comparisons.

Fontconfig uses a concept of strong and weak "bindings" for family names, which is important in the selection of default fonts for each language. There are currently no direct APIs to get the binding type of a family name from the pattern, so applications must use fontconfig match or sort functions if they are to pick up default fonts as intended.

However, you can imagine the speed improvement obtained by filtering the set of family names in the pattern to those that exist on the system, and filtering the set of all fonts to those that are in a requested or default family, before passing these sets to the fontconfig's match or sort functions.

Wednesday, October 8, 2008

Mozilla uses Pango for font handling on Linux because it is the best library in existence for international text-shaping with OpenType fonts.

Currently Pango's PangoFcFontMap is used for font selection via pango_itemize() . These APIs provide font-selection through fontconfig from fonts installed on the system, including fonts specific to each user.

When adding support for document-specified automatically-downloaded fonts to a web browser, it is important that font families created for one document do not change the behavior of other documents. However, these existing font-selection APIs currently only support application-specific fonts if they are added to fontconfig's application-global default configuration. In a web browser, adding document fonts in this way would lead to them sometimes being used in other documents, potentially leading to the rendering of completely inappropriate glyphs.

Text layout currently contributes to a large proportion of the resources used by the browser. The speed of text layout, including font selection, benefits from caching the data that is likely to be reused. This does come at a cost, however, as these caches can be memory-intensive.

Implementing font selection in Mozilla provides an opportunity to design and tune the caching for Mozilla's usage patterns. Work to-date has already reduced Firefox's memory use on Linux by 10%, but still something like 30% of memory is used for low-level font handling, so there's plenty of room for further improvements here.

Monday, October 6, 2008

What does the worker gain from his toil? I have seen the burden God has laid on men. He has made everything beautiful in its time. He has also set eternity in the hearts of men; yet they cannot fathom what God has done from beginning to end. I know that there is nothing better for men than to be happy and do good while they live. That everyone may eat and drink, and find satisfaction in all his toil—this is the gift of God. I know that everything God does will endure forever; nothing can be added to it and nothing taken from it. God does it so that men will revere him.