Google have recently announced it will be rolling out an update to search ranking based on “Core Web Vitals” starting May 2021.
It will use 3 signals for this new ranking bump:
LCP: Largest Contentful Paint
This metric is used to signal fast loading on a site, it is collected using the
largest-contentful-paint PerformanceEntry. The browser basically watches for the largest element on screen (in a particular allow list), once it is rendered it has the time.
FID: First Input Delay
This metric is used to measure how responsive a page is during loading. It watches for the delay between the time a user clicks / scrolls or types and the time the browser reacts.
requestAnimationFrame() calls you risk this number going high.
CLS: Cumulative Layout Shift
This metric searches for cases where layout “shifts” as a result without the user acting. Like, for example, an image in a topic where dimensions are not specified.
These 3 metrics LCP/FID/CLS are now going to become signals for Google. Meaning that if all things are equal content/PageRank wise LCP/FID/CLS will become tie-breakers leading to the poorer performing (according to Google) site ranking lower.
For those interested in the actual implementation see:
Tom Dale ominously blogged about this particular topic back in 2015 when design started on FastBoot.
Instead, client-side rendering and server-side rendering have always had performance tradeoffs. Ember’s FastBoot is about trying to bend the curve of those tradeoffs, giving you the best of both worlds.
Fast forward to 2021 and much has changed in the world.
Google have decided to double down on the push towards AMP and decided to give the world a minor concession on AMP by allowing web vitals to act as signal.
Some unfortunate collateral of this change are:
An enormous appeal for PWAs is that you accept a slightly slower initial page view and in return get spectacular low bandwidth performance and extremely fast page transitions. A JSON payload is usually a lot smaller than a fancy HTML page with fancy header and footer.
The penalty means that Ember PWAs look to Google significantly slower than what they really are.
This also biases Ember apps for inferior CLS scores, simply cause apps are significantly longer lived.
This heavily biases Android, which is woefully slower than iPhones. A top-end Android today is significantly slower browsing the web than a 2017 iPhone.
Further more, many Android phones sold today are significantly slower than the top end Android phones.
iPhones are absent from Web Vitals on mobile.
We started using Ember.JS at Discourse back at 2013, we have kept up with Ember releases. Recently @eviltrout completed a multi month project that upgraded us to Ember CLI.
Throughout the years we have been delighted to use a framework that offers the level of flexibility and maintainability that Ember does.
We have also accrued technical debt over the years including jQuery and 2 additional rendering engines that were introduced as performance hacks to work around issues older versions of Ember had.
Now that we are upgraded to Ember CLI we are poised to upgrade to Octane and Glimmer 2, both of which have very exciting performance profiles. We hope to shed some of our legacy (like alternative rendering engines) as we run through the next upgrades.
At Discourse we have been extremely good citizens when it comes to web performance. CDN support was always baked in, we introduced Brotli support way ahead of other platforms, we started using HTTP/2 back when it was SPDY, we have audited performance and tweaked performance countless times.
That said, Google have decided to push this particular grim picture to many of our customers:
Only 20% percent of the phone users of a Discourse site get a “green” mark according to Google. It is quite frustrating.
It is extremely hard to communicate the extreme amount of nuance to customers who simply see red and ask us “why?”.
A long and somewhat circular discussion happened at: Google May 4th Core Update impact on Discourse forums - community - Discourse Meta.
It is quite clear to me that, “Google will be Google”. It is very hard to move a giant ship. The picture of “you suck compared to a static HTML site and we will punish you”, is just hard to shake.
I would though like not to focus any discussion here on
“Not fair, Android sucks”
“Not fair, Google is not measuring right”
“Not fair, Google are comparing Elephants to Bananas”
Instead, I would like to focus the discussion on the future first render performance at Discourse and other large Ember applications.
Despite how unfair all of this may seem, it is hard to argue that it is delightful to click on a link in Google search results on a 2 year old phone and have it render sub 2 seconds.
Discourse is now extremely mature. We are done taking bets on hacked raw HBS to workaround issues. Instead we would like to focus on existing and upcoming tooling and technology the Ember ecosystem has on offer.
If you were going to work on improving the LCP metric, which Ember and Ember ecosystem technologies would you double down on?
Some directions that come to mind are:
FastBoot, this feels like a gigantic effort for Discourse. We reach out to the DOM quite a lot, operating without it would be an enormous effort. Is there a middle-ground FastBoot + DOM out there?
Embroider, this seems like a great area to explore given tree-shaking and code-splitting
Upgrade to latest Ember and start moving more and more stuff to lightweight Glimmer components where possible. Octane upgrades. Removal of legacy like jQuery and custom rendering engines
Ember Engines, though not particularly recommended at the moment it is important to mention that the entire LCP issue is isolated to topic and home pages, the majority of routes Discourse have are not a concern when it comes to LCP as the fast majority of entry traffic just hits a topic in a search.
Web workers which can introduce parallelization, even if only uses for a subset of functionality. An interesting thing about Android is that there are a lot of cores to play with.
What directions would you recommend Discourse and other large Ember code-bases take? Are there any other tools and ideas we should explore?