content-visibility enables the user agent to skip an element’s rendering work, including layout and painting, until it is needed. Because rendering is skipped, if a large portion of your content is off-screen, leveraging the content-visibility property makes the initial user load much faster. It also allows for faster interactions with the on-screen content. Pretty neat.
You see that correct in the image above: rendering went from 232ms down to 30ms … that’s a 7x improvement!
Now don’t go plastering this all over your site, but use it carefully. As Una noted:
😊 I wrote a blog post w/Vlad about this that just went live (see ⬆️ link)
Some notes: – Don't apply this to everything! Chunk content that you are applying this to – The scrollbar will shift when new content gets rendered, so use `contain-intrinsic-size` w/a placeholder size
UPDATE 2020-04-28: Good news everyone! A workaround for this bug has landed in Canary (Chromium 84) and will be merged into the M83 release! The workaround described here still applies for Chromium 81.
The Chromium bug itself is marked as a blocker for Chromium M83 – the next Chromium version – but as far as I can tell there’s no real progress being made on it. Above that the M83-based build of Google Chrome won’t start shipping until May 19, so we’re stuck for at least another month with this issue. Other browsers (such as Edge, Brave, etc.) might ship their M83-based build even later.
As a workaround, some users have suggested to simply not use SF Pro (which is the outcome of using BlinkMacSystemFont) but that’s quite a hard measure I must say. Thankfully there’s a better solution. Thanks to Twitter I’ve come to known that the Inter font family is practically a drop-in replacement for SF Pro.
Here on bram.us I’ve adjusted my font stack to no longer use BlinkMacSystemFont and load Inter – served by Google Fonts – instead. To preserve other platforms to load their own system font, I’ve added Inter somewhere at the back of the line.
💡 Note that in the snippet above I’m loading all available font-weight Inter supports. It’s recommended to limit this and only load the font-weights you actually need. You can do this via the Google Fonts website
With this adjustment in place my website looks quite decent again. Let’s hope the Chromium team can fix this issue soon. In the mean time we can use Inter as workaround.
Did this help you out? Like what you see? Thank me with a coffee.
I don't do this for profit but a small one-time donation would surely put a smile on my face. Thanks!
Today I noticed here on bram.us that the titles suddenly have gotten thinner in Chrome on macOS. Was this due to a recent WordPress Theme Update? Was it caused by a recent macOS update? Or was it the update to Chrome version 81 that broke my site?
I’m running WordPress here with (a slightly modified version of) the default Twenty Nineteen theme. The theme uses a so called system font stack for its titles:
While the font stack itself was applied correctly – the font eventually used is BlinkMacSystemFont here on my Mac – the font-weight seems to be ignored by Chrome.
After some experimenting I’ve narrowed down the problem to its core, and have come to conclude that the issue is:
Not WordPress-related. The issue is present on any site with elements that use the BlinkMacSystemFont font (which is only available on recent macOS installs).
Only occurs when larger font-sizes (> 20px) are used.
Chromium related: Latest Firefox and Safari still show the bold titles. Google Chrome and Edge Beta show the thin versions.
Chromium 81+ related: Edge (based on Chromium version 80) works fine, Edge Beta (based on Chromium version 81) doesn’t. Chrome Canary (based on Chromium version 84) also has this issue.
Here’s a pen with a standalone test case. No matter what you set the font-weight to, the title always remains thin (on macOS, in a Chromium 81+ browser).
To be complete: I’m running the latest macOS Catalina, version 10.15.4 (19E266).
I’ve created a bug on the Chromium Bug Tracker for this, which by now has been confirmed. The problem indeed got introduced in Chrome 81 and is reproducible. If I understand things correctly, work is being done to have it fixed by Chrome 83, which is the next version of Chrome (there is no Chrome 82 as the release schedule got thrown around due to #coronavirus).
Currently there’s no workaround that you as a developer can implement, other than simply not using BlinkMacSystemFont.
The main goal of CSS Containment standard is to improve the rendering performance of web pages, allowing the isolation of a subtree from the rest of the document. This specification only introduces one new CSS property called contain with different possible values.
layout: The internal layout of the element is totally isolated from the rest of the page, it’s not affected by anything outside and its contents cannot have any effect on the ancestors.
paint: Descendants of the element cannot be displayed outside its bounds, nothing will overflow this element (or if it does it won’t be visible).
size: The size of the element can be computed without checking its children, the element dimensions are independent of its contents.
style: The effects of counters and quotes cannot escape this element, so they are isolated from the rest of the page.
Browser engines can use that information to implement optimizations and avoid doing extra work when they know which subtrees are independent of the rest of the page.
Insightful post by the folks over at LogRocket on the rendering pipeline:
If your site takes forever to load, chances are your users aren’t gonna wait for it to finish, even if there’s valuable content to be found there. Some studies have shown that up to 50% of users leave a page after 3 seconds of waiting.
With users expecting those types of load times, it’s our responsibility as web developers to not bloat the amount of stuff we’re sending to the user. Sadly, CSS is often the culprit of increased load times, so having a nuanced understanding of how the CSS you send is transformed into beautiful pixels will help you optimize that crucial seconds where users are most likely to bounce.
Talk by Jake Archibald, as brought at JSConf.Asia 2018, taking a close look into the browser’s Event Loop:
Hopefully you’ll never have to use setTimeout hacks again!”
And yeah, I’ve also used getComputedStyle() in the middle of some JS code before, in order to force layout/re-rendering 😬
Once saw an interactie version of the visuals as shown in Alexander Zlatkov’s post. I think it was in a talk, yet can’t seem to find it back anywhere … if someone could point me to it, feel free to comment 😉
UPDATE: Found it! The tool is named Loupe, and I saw it in this talk by Philip Roberts:
Great writeup on how Firefox’s new CSS Engine “Quantum CSS” works. Also sports a clear and in-depth explanation of the rendering pipeline, with some nice illustrations to go along.
You may have heard of Project Quantum… it’s a major rewrite of Firefox’s internals to make Firefox fast. We’re swapping in parts from our experimental browser, Servo, and making massive improvements to other parts of the engine.
The first major component from Servo – a new CSS engine called Quantum CSS (previously known as Stylo) – is now available for testing in our Nightly version.
When a browser receives the HTML response for a page from the server, there are a lot of steps to be taken before pixels are drawn on the screen. This sequence the browsers needs to run through for the initial paint of the page is called the “Critical Rendering Path”.
Good and short writeup on how the pixel/rendering pipeline works – something that every developer should now – perfect for those new to the subject.
“Is Houdini ready yet‽” is a dedicated page to tracking the status of Houdini.
But what is Houdini? Here’s a snippet from Smashing Magazine:
Imagine how much nicer your development life would be if you could use any CSS property and know for sure it was going to work, exactly the same, in every browser. And think about all of the new features you read of in blog posts or hear about at conferences and meetups — things like CSS grids, CSS snap points and sticky positioning. Imagine if you could use all of them today and in a way that was as performant as native CSS features. And all you’d need to do is grab the code from GitHub.
This is the dream of Houdini.
The Houdini task force has introduced several new specifications that will give developers access to all parts – instead of just the DOM/CSSOM part – of the rendering pipeline. The chart below shows the pipeline and which new specifications can be used to modify which steps.
With Houdini’s APIs one could – for example – implement the Masonry or Grid Layouts, running them at native speed instead of as a script/polyfill: