As was announced earlier today, Firefox 57 will be merged to the Beta channel on September 21, which is two weeks from today. That wraps up the long development cycle that has gone on for maybe about a year now. We had a lot of ambitious plans when we started this effort, and a significant part of what we set out to deliver is either already shipped or landed on Nightly. It is now a good time to focus on making sure that what we have which isn't shipped yet is as high quality possible, by ensuring the crash rates are low, regressions are triaged and fixed in time, and remaining rough edges are smoothed out before the release. There are still a lot of ongoing projects in flight, and of course many of open Quantum Flow bugs that have already been triaged which aren't fixed yet. I'll write more about what we plan to do about those later.
Let's now have a quick look at where we are on the battle on the synchronous IPC performance bottlenecks. The TL;DR is: things are looking great, and we have solved most of this issue by now! This worked has happened in 50+ bugs over the course of the past 8 months. The current telemetry data shows a very different picture on the synchronous IPC messages between our processes compared to how things looked back when we started. These graphs show where things are now on the C++ side and on the JS side. For comparison, you can see the latest graphs I posted about four weeks ago.
Things are looking a lot different now compared to a month ago. On the C++ side, the highest item on the list now is PAPZCTreeManager::Msg_ReceiveMouseInputEvent, which is an IPC message with a mean time of 0.6ms, so not all that bad. The reason this appears as #1 on the list is that it occurs a lot. This is followed by PBrowser::Msg_SyncMessage and PBrowser::Msg_RpcMessage, which are the C++ versions of JS initiated synchronous IPCs, followed by PDocAccessible::Msg_SyncTextChangeEvent which is a super rare IPC message. After that we have PContent::Msg_ClassifyLocal, which will probably be helped by a fix landed two days ago, followed by PCompositorBridge::Msg_FlushRendering (with a mean time of 2.2ms), PAPZCTreeManager::Msg_ReceiveScrollWheelInputEvent (with a mean time of 0.6ms), PAPZCTreeManager::Msg_ReceiveKeyboardInputEvent (with a mean time of 1.3ms) and PAPZCTreeManager::Msg_ProcessUnhandledEvent (with a mean time of 2.8ms).
On the JavaScript side, the messages in the top ten list that are coming from Firefox are contextmenu, Findbar:Keypress, RemoteLogins:findRecipes (which was recently almost completely fixed), Addons:Event:Run (which is a shim for legacy extensions which we will remove later but has no impact on our release population as of Firefox 57) and WebRequest:ShouldLoad (which was recently fixed).
As you'll note, there is still the long tail of these messages to go through and keep on top of, and we need to keep watching our telemetry data to make sure that we catch other existing synchronous IPC messages if they turn into performance problems. But I think at this point we can safely call the large umbrella effort under Quantum Flow to address this aspect of the performance problems we've had in Firefox done! This couldn't have been done in such a short amount of time without the help of so many people in digging through each one of these bugs, analyzing them, figuring out how to rework the code to avoid the need for the synchronous messaging between our processes, helping with reviews, etc. I'd like to thank everyone who helped us get to this point.
In other exciting performance news, Stylo is now our default CSS engine and is riding the trains. It's hard to capture the impact of this project in terms of Talos improvements only, but we had some nonetheless! Hopefully all the remaining issues will be addressed in time, to make Stylo part of the Firefox 57 release. A big congrats to the Stylo team for hitting this milestone.
With this, I'd like to take a moment to thank the hard work of everyone who helped make Firefox faster during the past week. I hope I'm not forgetting any names.
- Ryan Hunt enabled asynchronous keyboard scrolling by default on desktop.
- Botond Ballo enabled asynchronous autoscrolling by default.
- Ming-Chou Shih enabled coalescing mousemoves events to happen once per refresh driver cycle for further testing on the Nightly channel.
- Jon Coppeard removed waiting for incremental GCs to finish when merging compartments.
- Kris Maglione made the webRequest extension API use a WebIDL wrapper to access Necko channels in order to improve the performance of extensions that use this API to inspect network connections. As part of that, he avoided some XPConnect overhead for URI parsing from JavaScript. He also avoided loading ext-contextualIdentities.js at startup needlessly. Last but not made us preload files needed during startup on a background thread.
- Mike Conley fixed a regression in the performance of scrolling the tabbar when clicking and holding the scroll buttons.
- Ben Kelly avoided dirtying the image cache queue in a couple of cases where we would do so needlessly in the past.
- Jan de Mooij avoided excessive loop restarts in IonBuilder in some cases.
- Olli Pettay triggered GC/CC slices when triggering an iframe load or starting to parse an iframe if the user isn’t actively using the browser in order to disturb executing the page JavaScript code less when the load has happened.
- Daniel Holbert made nsTextFrame::CharacterDataChanged() return early if a reflow has already been requested by the function.
- Perry Jiang finished a project for avoiding the RemoteLogins:findRecipes synchronous IPC in all but some small edge cases.
- Luke Chang avoided creating a live NodeList in the form autofill code using the getElementsByTagName() API.
- Andrew McCreight made QueryInterface() for some cycle-collectible objects faster.
- Thomas Nguyen avoided the usage of a synchronous IPC to decide whether to make a Flash document should be blocked using click-to-play.
- Kirk Steuber ensured that thumbnail generation only happens in idle periods.