Howdy folks! Another Firefox Performance Update coming at you. Buckle up.
But first a word from our sponsor: Talos!
Talos is a framework that we use to measure various aspects of Firefox performance as part of our continuous integration pipeline.
There are a number of Talos “suites”, where each suite contains some number of tests. These tests, in turn, report some set of numbers that are then stored and graphable via our graph viewer here.
Here’s a full list of the Talos tests, including their purpose, the sorts of measurements they take, and who’s currently a good person to ask about them if you have questions.
A lot of work has been done to reduce the amount of noise in our Talos tests, but they’re still quite sensitive and noisy. This is why it’s often necessary to do 5-10 retriggers of Talos test runs in order to do meaningful comparisons.
Sometimes Talos detects regressions that aren’t actually real regressions1, and that can be a pain. However, for the times where real regressions are caught, Talos usually lets us know much faster than Telemetry or user reports.
Did you know that you can get profiles from Try for Talos runs? This makes it much simpler to diagnose Talos regressions. Also, we now have Talos profiles being generated on our Nightly builds for added convenience!
And now for some Performance Project updates!
Early first blank paint (lead by Florian Quèze)
No new bugs have been filed against the feature yet from our beta population, and we are seeing an unsurprising drop in the time-to-first-paint probe on that channel. User Research is in the process of getting a (very!) quick study launched to verify our assumption that users will perceive the first blank paint as the browser having started more quickly.
Faster content process start-up time (lead by Felipe Gomes)
Felipe has some patches up for review to make our frame scripts as lazy as possible. To support that, he’s added some neat infrastructure using Proxy and Reflect to make it possible to create an object that can be registered as an event handler or observer, and only load the associated script when the events / observer notifications actually fire.
We’re excited to see how this work impacts our memory and content process start-up graphs!
LRU cache for tab layers (lead by Doug Thayer)
The patch to introduce the LRU cache landed and bounced a few times. There appears to be an invalidation bug with the approach that needs to be ironed out first. dthayer has a plan to address this (forcing re-paints when switching to a tab that’s already rendered in the background), and is just waiting for review.
ClientStorageTextureSource for macOS (lead by Doug Thayer)
Doug is working on finishing a project that should allow us to be more efficient when uploading things to the compositor on macOS (by handing memory over to the GPU rather than copying it). He’s currently dealing with strange crashes that he can only reproduce on Try. Somehow, Doug seems to always run into the weird bugs that only appear in automation, and the whole team is crossing our fingers for him on this one.
Swapping DataURLs for Blobs in Activity Stream (lead by Jay Lim)
Our new intern Jay Lim is diving right into performance work, and already has his first patch up. This patch makes it so that Activity Stream no longer uses DataURLs to serialize images down to the content process, and instead uses Blobs and Blob URLs. This should allow the underlying infrastructure to make better use of memory, as well as avoiding the cost of converting images to and from DataURLs.
Caching Activity Stream JS in the JS Bytecode Cache (lead by Jay Lim)
This project is still in the research phase. Jay is trying to determine if it’s possible to stash the parsed Activity Stream JS code in the JS bytecode cache that we normally use for webpages. We’re still evaluating how much this would save us on page load, and we’re also still evaluating the cost of modifying the underlying infrastructure to allow this. Stay tuned for updates.
AwesomeBar improvements (led by Gijs Kruitbosch)
Gijs has started this work by making it much cheaper to display long URLs in the AwesomeBar. This is particularly useful for DataURLs that might happen to be in your browsing history for some reason!
This is a long-pull effort, so expect this work to be spread out over a bunch of bugs.
Tab warming (lead by Mike Conley)
I’ve been focusing on determining why warming tabs seems to result in two consecutive paints. My findings are here, and I suspect that in the warming case, the second paint is avoidable. I suspect that this, coupled with dthayer’s work on ClientStorageTextureSource will greatly improve tab warming’s performance on macOS, and allow us to ship on that OS.
Firefox’s Most Wanted: Performance Wins (lead by YOU!)
Before we go into the grab-bag list of performance-related fixes – have you seen any patches landing that should positively impact Firefox’s performance? Let me know about it so I can include it in the list, and give appropriate shout-outs to all of the great work going on! That link again!
Grab-bag time
And now, without further ado, a list of performance work that took place in the tree:
(🌟 indicates a volunteer contributor)
- Emilio Cobos Álvarez made it so that we do less work dealing with fonts in Stylo code. This appears to impact YouTube pages, so that’s a nice win!
- Marco Bonardo made it so that our Windows Jump Lists code no longer uses synchronous Places APIs to determine if browser history is empty.
- Andrew Swan made it so that background pages for WebExtensions can have their loading deferred. It’s quite a clever optimization and has resulted in nice improvements on a number of our start-up performance benchmarks! Great work!
- Andrew McCreight made it so that we can do less work when cycle collecting sometimes! This appears to fix some multi-second hangs that some of our users have been seeing on popular sites like Google Inbox.
- Matt Woodrow made it so that we schedule paints in a more intelligent way, especially when painting is recovering from falling behind vsync.
Thanks, folks!
Sometimes, for example, the test is just measuring the wrong thing. ↩