GNOME Shell Performance Improvements in Ubuntu 20.04
The release of Ubuntu 20.04 brings GNOME Shell 3.36 and improved performance in some areas. In this article we will describe the improvements that were contributed by Canonical.
As most Ubuntu users tend to stick to LTS releases they mostly will be upgrading from 18.04. If that’s you then you will also notice a larger set of performance improvements introduced in 19.04 and especially in 19.10. So you might like to read what those are first.
New in 20.04
All animations are slightly smoother, and some have lower latency
An animation is just when something moves through both time and space. But even animations that didn’t skip frames (were smooth in time) weren’t looking as smooth as they could be. This occurs when an animation uses an irregular series of positions on screen. Now we sync those positions to the strict interval your screen will emit the photons on, so there’s a slight improvement in visible smoothness.
And since we’re now being very specific about when photons get emitted we can synchronise the screen contents more closely to the mouse pointer (which is actually separate to the screen contents). So when you drag windows around in Ubuntu 20.04 they will stick to the mouse pointer more closely.
Display scaling was wasting megabytes of memory
It was just trying to store more detail than actually exists in the original wallpaper image. It doesn’t now, but there’s a chance similar mistakes are still lingering elsewhere in the code. So this is the beginning of an ongoing effort to find places where display scaling above 100% might impact performance.
Moving the mouse no longer involves JavaScript
Executing JavaScript isn’t objectively slow, but it is much slower than not executing JavaScript. Since we can avoid it, we now do. So CPU usage and battery usage will be a little lower while you whisk the mouse (or touchpad) around.
Opening or closing the icon grid is now quicker to respond
GNOME Shell is a complex system, kept as simple as possible through JavaScript. But sometimes changing one thing has unexpected side effects for another thing. What’s slightly mind bending is that JavaScript can execute concurrently across multiple frames and it’s not immediately obvious how many frames your JavaScript function is taking to execute. You hope it’s less than one, but sometimes it’s not.
Window sliding animations are now more efficient, smoother
GNOME Shell is built on Mutter via the Clutter toolkit. The Clutter toolkit started as a separate project but is now maintained inside Mutter.
One of the most performance sensitive parts of Clutter is when any GUI element gets “reallocated” through a “relayout” cycle. This involves walking through all the GUI elements and figuring out their size and position. Once that is known you can redraw individual elements more efficiently without involving their relatives. The problem is when GNOME Shell joins the party it adds some allocation functions written entirely in JavaScript, and that’s slower than the same kind of functions written in C (like Clutter/Mutter is). And we can’t easily change that because GNOME Shell GUI itself is written in JavaScript, so its allocation functions must be too.
What we can change is how often these allocations happen. And that’s what changing some animations from using x
/y
properties to translation-x
and translation-y
properties does. The latter means no reallocations need to happen so all that executing of JavaScript doesn’t need to happen, at least not in the middle of animations. So they’re now more CPU-efficient and should appear smoother. Just tap your Super key (the Windows key) to find out.
The icon spring/swarm animation is now more efficient, smoother
Even better than it was in Ubuntu 19.10. This was done using the same approach as in the above paragraph.
Relayouts are now more efficient
If an ancestor doesn’t want to be involved in relayouts, now it isn’t. This doesn’t directly improve performance noticeably, yet, but the new API will make it easier to solve more performance issues in future.
When multiple separate things are changing on screen, performance is now better (sometimes)
In 3.36, upstream Mutter introduced a new feature to draw multiple parts of the screen separately instead of merging them all into a single draw. The problem was this actually performed slower than 3.34 when the number of things increased. So we introduced a fix to make it perform comparatively to 3.34.
GJS is significantly more efficient now
GJS is the glue between GNOME Shell and the (Mozilla) JavaScript engine. It was found to contain a bug that would repeatedly execute the same code during some animations. That’s now fixed for all GNOME 3.36 systems.
Although Canonical found the bug and prototyped the first fixes, the final fix was provided by Philip Chimento. Thanks!
“But I still have performance issues”
We know some issues are still not solved. GNOME Shell’s performance will continue to improve in future releases. But don’t assume anyone else sees the same problems as you do. If you find something that’s not quite fast enough then please let us know by running this command to open a bug:
ubuntu-bug gnome-shell
We look forward to making you even happier in future releases.