August 2020, I came across
Intersection Observer web API on a random tweet then checked out the MDN API document, I was so excited and wanting to integrate it to improve our page rendering performance. Luckily, there is a React Hook version of intersection observer already,
react-intersection-observer, so it took no times for us to integrate. Since that time
Intersection Observer is my favourite Web API 😍 whenever I need to toggle/animate/trigger components.
The same month, Google Dev Submit 2020 unveiled CSS
contain-intrinsic-size properties which supports from Chrome 85. It’s shamed I was buried by developing project features and only came across during Xmas holiday. However, this is like the best Xmas surprise 🎁 for me and it takes my excitement to the next level, just two lines of CSS then I can achieve lazy loading, OMG I freaking love it. You can deep dive content-visibility on Google web.dev, a great article to explain how it works.
But, life is not always easy,
content-visibility is still more like an experimental feature and not supporting the other two major browser Safari and Firefox. 😞
content-visibility CSS solution, why not combine these so we can provide a cross-browsers solution💡 Meanwhile, implement as a web component is the best choice coz it’s lightweight, high performance (shadow DOM) and great browsers compatibility. I spent 12 hours to digest web component and gave a birth of
<content-visibility> v1 🎉
lit-element base class to create this web component as it’s lightweight and great browser compatibility, especially their web component GitHub starter template is extremely handy makes the whole experience of creating web component zero-brainer.
content-visibility from NPM and start integrating with any JS frameworks (React, Vue, Preact, Angular, VanillaJS and etc).
npm i content-visibility --save
Alright, let’s see some results I tested on three major browsers, Chrome 87, Safari 14 and Firefox 84 and I used the exact same travel blog template (except I removed
iframe ) that is used in web.dev Codepen
Rendering frames, Safari comes with an interesting tool, Rendering Frames Timeline, helps you to measure page rendering performance. I want to start with this result to demonstrate how it reduces unnecessary rendering.
Time measurement, Chrome 87 uses CSS solution which completely handles by browser and you can see
Painting time are reduced around
50% and overall time reduced
Safari 14 fallbacks to use
Intersection Observer API to detect if component appears on the viewport. Layout & Rendering time down from
8s and you can easily see not many rendering chunks happening after applied
Firefox 84 also fallbacks to use
Intersection Observer API.
You probably wondering how many lines I changed for 👆 PageSpeed results, actually just 4 lines 👇
That’s it! Numbers are better than words to tell the story. I already integrated
<content-visibility> web component with my production web application in
Preact . This is just v1 and sure it can be extended and tweak from feedbacks. Give it a try and welcome to fork the source code and deep dive the implementation. I will find a time to write an article about the implementation but not urgent as logic is simple and straightforward.