Summary:
Let’s journey together from facing challenges to achieving success in optimizing Core Web Vitals (CWV) and enhancing user experiences. With a nod to Massimo Villa for insightful guidance, here’s what you need to know:
- Accessing CWV Reports: Learn how to access CWV reports and understand the differences between tools like Page Speed Insights (PSI) and Chrome User Experience Report (CrUX).
- Identifying CWV Issues: Discover common CWV issues like First Contentful Paint (FCP), Cumulative Layout Shift (CLS), and Largest Contentful Paint (LCP), along with effective solutions to address them.
- Harnessing Real User Monitoring (RUM): Explore the power of Real User Monitoring (RUM) for gaining insights from real-world data and refining CWV tracking with advanced solutions.
- Prioritizing User Experience: Above all, prioritize user experience and CWV optimization to ensure your website excels in the digital realm.
With these insights, you’ll be better equipped to navigate CWV optimization and elevate your website’s performance.
I was taken aback to witness a significant drop in my Core Web Vitals (CWV) metrics back in June. Despite diligently implementing all the optimization techniques I had acquired over the years, it seemed insufficient. However, this setback transformed into a profound learning experience, and I’m enthusiastic about sharing my journey with you.
Are you intrigued to discover how I successfully navigated the Core Web Vitals assessment? Join me as I delve into the ups and downs of my journey, providing actionable steps you can implement while steering clear of the obstacles I faced. Together, let’s fortify your website’s CWV performance to ensure it remains consistently exceptional!
CrUX Insights and Google Search Console CWV Report:
Chrome UX Report (CrUX)–
The Chrome User Experience Report (CrUX) provides user experience metrics for how real-world Chrome users experience popular destinations on the web.
You can find my latest website Chrome User Experience (CrUX) report.
Search Console: Core Web Vitals Report
Page Experience Report
While Google Search Console reports good Core Web Vitals and page experience, Page Speed Insights’ field data suggests otherwise. This is because PSI’s field data updates regularly, capturing real-world user experiences that may differ from Search Console’s broader dataset.
The difference between Field Data in Page Speed Insights (PSI) and the CrUX dataset on BigQuery is that PSI’s data is updated daily, while the BigQuery dataset is updated monthly and limited to origin-level data. Both data sources represent trailing 28-day periods.
Page Speed Insights – Field data
If you want to access your CrUX data/field data. You can do it in multiple ways – Keep in mind, that to access the data you must have the field data otherwise you can’t.
(Before) Navigating Page Speed Insights Discrepancies:
Problems
First Contentful Paint (FCP):
- Initially, moving the web-vitals JS initiator and lite-YouTube JS to the footer seemed to improve my FCP and LCP by giving priority to loading the main image. However, over time, these changes led to declining scores. It appears that the early execution of these Javascript might be negatively impacting performance in other areas.
Cumulative Layout Shift (CLS):
- When I activated maintenance mode to redesign the blog page, it unexpectedly caused a spike in CLS.
- Visitors were directed to a non-optimized version of the page, lacking critical CSS or using CSS that resulted in Flash Of Unstyled Content (FOUC), causing elements to briefly jump around before styling fully loaded.
- As a result, the CLS score, which measures visual stability, significantly increased, signaling a poor user experience.
Largest Contentful Paint (LCP):
- Initially, I thought optimizing by offloading images and videos and serving images from an image CDN (Cloudinary) would be beneficial. Cloudinary automatically optimizes and serves images in .avif format for faster performance, seeming like a win-win. However, after a few days, my LCP score dropped from 1.8 seconds to 2.7 seconds, highlighting the unintended consequences of this approach. This can be solved if you’re on Advanced Plan because it supports Custom Domain.
Solution
To identify the real issues, I started using the Real User Monitoring (RUM) analytics service to monitor my Core Web Vitals performance daily.
First, I used Web Vitals JS libraries but turns out it is very expensive for me (maybe I used too many BigQuery free available quotas) so I switched to Cloudflare Web analytics which is free to pinpoint the issues that Lab data could not.
Harnessing Real User Monitoring (RUM):
Real user monitoring (RUM) tracks and measures the end-user experience in an application, including how long it takes for elements on a web page to load, whether a page has errors, and how long AJAX and HTTP requests take.You can also use RUM to better understand how your users interact with your websites, giving you valuable insights on how to improve your sites and deliver value to your customers.
You can learn why RUM is so important from the New Relic article.
Many 3rd parties services also offer RUM analytics solutions to help you gather real data from real users and these are the 3 services I use.
Watch the video above on how to set up web vitals JS (Tutorial I use previously to monitor).
When I start collecting the RUM data. I know exactly the issues I have, & opportunities to improve my web performance like-
- Which selectors cause the layout shift,
- Whether an image or heading is the Largest Contentful Paint element.
Largest Contentful Paint
Cumulative Layout shift
Web Vitals JS Libraries:
Having access to real-world user data through web vitals JS libraries has been a game-changer for optimizing my website’s performance. Compared to relying solely on lab data, identifying, analyzing, and fixing performance issues is significantly easier and more accurate.
Previously, I used web vitals libraries that lacked support for crucial metrics like Time To First Byte (TTFB), First Contentful Paint (FCP), and Interaction Next Paint (INP). This limited my ability to gain a comprehensive picture of user experience.
If you’re looking for a more advanced solution that tracks all these metrics, I highly recommend checking out Tony McCreath’s article on “Web Site Advantage Core Web Vitals Tracking.” It offers a detailed guide on setting up a comprehensive RUM (Real User Monitoring) solution using web vitals libraries.
If you’re a Cloudflare user, you can leverage its built-in Browser Insights feature to collect RUM (Real User Monitoring) data seamlessly.
After removing separate web vitals JS libraries, I switched to this solution, and I’ve been consistently getting similar results for over a week now. Browser Insights offers both automatic JavaScript injection and manual setup options, providing a more convenient and streamlined experience compared to the previous libraries I used.
Largest Contentful Paint
You can see which posts have bad LCP performance
Cumulative Layout Shift
After you gather all the data from real users, what can we do? The best thing to do is to fix the issues and later we can compare them with the old data.
I have been using it for more than 20 days and I love their UI. They offer a free plan to check your RUM but it is quite limited.
Dashboard
Page Path Analysis
Largest Contentful Paint
Cumulative Layout Shift
Interaction To Next Paint
Long Animation Frames (LoAF)
The Long Animation Frames API (LoAF-pronounced Lo-Af) is an update to the Long Tasks API to provide a better understanding of slow user interface (UI) updates. This can be useful to identify slow animation frames which are likely to affect the Interaction to Next Paint (INP) Core Web Vital metric which measures responsiveness, or to identify other UI jank which affects smoothness.
A large amount of 3rd parties JavaScripts can significantly impact your performance, using LoAF metrics you can identify which JS is responsible and you can either remove it or defer the scripts.
(After) How I Fix the Issues & its Comparisons-
You can also see the latest version of my Page Speed Insights’ Field-data
Largest Contentful Paint (LCP)
Fixes
To improve the LCP metric:
- I use the Webp Express plugin to optimize and serve my images in .webp image format.
- I exclude the feature images or “Above the fold” or critical images from the Autoptimize lazyloading mechanism.
Comparisons of Lab data and PSI-field data
Webpagetest result (Lab test)- Ignore the response time
- Before (Cloudinary/ image CDN) add an unnecessary connection time (around 600ms) to the image (number 6).
- After: (self-hosted) no unnecessary connection is added to the image.
Page Speed Insights (Field-data) –
We can see the improvement of PSI field data daily.
Cumulative Layout Shift
Fixes:
To fix the CLS issues:
- I included the latest CSS in the critical CSS process.
- I preloaded my web font.
Page Speed Insights (field-data)
First Contentful Paint
Fixes
To improve my FCP performance:
- I remove most of the redundant CSS rules like the !important CSS, and duplicate style.
- Remove the unnecessary preconnect call by the Lite-YouTube embedded JS because I never load my YouTube video above-the-fold content.
- I started Removing unused CSS from all my posts and inline small CSS using Asset cleanUp Plugins which reduce unnecessary HTTP requests
//Before
//Lite-YouTube JS add the preconnect hint to "https://i.ytimg.com" which is good, if the poster image are loading earlier in the viewport
initImagePlaceholder() {
LiteYTEmbed.addPrefetch('preconnect', 'https://i.ytimg.com/');
const posterUrlWebp = `https://i.ytimg.com/vi_webp/${this.videoId}/${this.posterQuality}.webp`;
const posterUrlJpeg = `https://i.ytimg.com/vi/${this.videoId}/${this.posterQuality}.jpg`;
this.domRefImg.fallback.loading = this.posterLoading;
this.domRefImg.webp.srcset = posterUrlWebp;
this.domRefImg.jpeg.srcset = posterUrlJpeg;
this.domRefImg.fallback.src = posterUrlJpeg;
this.domRefImg.fallback.setAttribute('aria-label', `${this.videoPlay}: ${this.videoTitle}`);
this.domRefImg?.fallback?.setAttribute('alt', `${this.videoPlay}: ${this.videoTitle}`);
}
// After
initImagePlaceholder() {
const posterUrlWebp = `https://i.ytimg.com/vi_webp/${this.videoId}/${this.posterQuality}.webp`;
const posterUrlJpeg = `https://i.ytimg.com/vi/${this.videoId}/${this.posterQuality}.jpg`;
this.domRefImg.fallback.loading = this.posterLoading;
this.domRefImg.webp.srcset = posterUrlWebp;
this.domRefImg.jpeg.srcset = posterUrlJpeg;
this.domRefImg.fallback.src = posterUrlJpeg;
this.domRefImg.fallback.setAttribute('aria-label', `${this.videoPlay}: ${this.videoTitle}`);
this.domRefImg?.fallback?.setAttribute('alt', `${this.videoPlay}: ${this.videoTitle}`);
}
This does not happen once, it happens more than twice, from there I learned a lot, here are the tips and caution you need.
- If your featured image is a background image, consider preloading the image so browsers discover it earlier.
- Use an image tag instead of a background image because the browsers put the background image in lower priority.
- Reduce your inline CSS size. Unnecessary inlining of CSS can increase Document/ HTML size which can affect your Mobile users because inline assets (CSS, JS, and images) cannot be cached.
- Use rel preload and preconnect hints sparingly.
- The often-overlooked TTFB: A Crucial Player in Core Web Vitals. While many focus on Largest Contentful Paint (LCP) and First Contentful Paint (FCP) for Core Web Vitals, Time to First Byte (TTFB) often gets overlooked. This critical metric, representing the time it takes for the first byte of data to be received from the server, plays a crucial role.
- If your response time/ TTFB is 3 seconds, you can’t expect your LCP will be under 2 seconds.
- Fluctuating TTFB can significantly impact LCP and FCP, as they rely on receiving data from the server first.
- Here’s a valuable tutorial on optimizing TTFB from web.dev
- Serve LCP Images from the Same Origin: Serving LCP images or viewport images from different origins is a performance pitfall. Downloading from different sources adds unnecessary time impacting the LCP score and overall user experience. Always self-host LCP images or use an image CDN that supports custom domain or sub-domain functionalities. This ensures faster loading times and a smoother user experience.
- Image CDN:
- Image CDN that supports sub-domain:
- Self-host or Proxy
- Critical CSS or used CSS Regeneration: Updating your website’s style brings the need for critical CSS or used CSS regeneration. This ensures your pages use the most relevant styles, preventing performance issues.
- If changing a specific page’s style, regenerate critical or used CSS for that page only.
- For site-wide updates, consider regenerating critical CSS or regenerating used CSS for all pages to avoid old styles slowing down the loading process.
- Inline JavaScript and CSS: Many tutorials advocate inlining CSS and JS for improved page speed scores. However, this approach can be detrimental.
- Inlined resources can significantly increase page size, leading to slower loading times.
- Focus on efficient code optimization and resource management instead of inlining.
- If you’re using Elementor, avoid setting the “CSS Print Method” to “Internal Embedding.”This unnecessarily inlines your frontend CSS, impacting performance.
- Inline critical JS like the navigation.
By following these recommendations and continuously monitoring your Core Web Vitals metrics, you can ensure a fast and smooth user experience for your website visitors.
When I requested Massimo Villa from the altsetup to review my article. He raised an interesting question
Since you use Elementor on your site, why do you use Lite-YouTube embeded instead of the Native Facade (“overlay”) feature replacing YouTube player with local image placeholder?
The answer is quite simple-
- No dependencies
- Super Lightweight only less than 4KB.
What are the alternatives?
If my blog design has lots of features like motion effects ( sticky header, parallax effects, Table of Contents, etc) then there is no point in using the alternative solution.
As you can see from my article, my design is basic and there is no point in adding all the bells and whistles (features) that can only slow down my performance.
Lite-YouTube vs Elementor’s Video widget
My website is built with Elementor and it has a video widget that supports YouTube, Vimeo, Dailymotion & Self-Hosted Video, and other features like Lazy-loading & facade (“image overlay”) as Massimo Villa suggested but the problems when you load the video widget it automatically add all the unnecessary scripts.
Image overlay (Facade)
To load “video.1234444….bundle.min.js“, the scripts have to be called webpack.runtime.min.js which depends on frontend-modules and depend on frontend then jQuery.
└── jquery.min.js
├── frontend.min.js
├── frontend-modules.min.js
└── webpack.runtime.min.js
└── /video.fea4f8dfdf17262f23e8.bundle.min.js
To use all the features I will end up loading over 80KB of JS which sometimes is unnecessary for me whereas lite-youtube JS only loads 3.3KB which is substantially lower and has zero dependencies on jQuery.
If you want to use lite-youtube embed on your website, you can download the widget from my store.
Image CDN
Here are some of the 3rd parties image CDN services that offer custom Domain/sub-domain functionalities like-
- Shortpixel Adaptive AI
- Bunny Optimizer
- Imgix
- Optimole
- Cloudflare images with Offload, Store, Resize & Optimize with Cloudflare Images (You don’t have to use the sub-domain functionalities)
LuckyWP Table of Contents
Elementor has a Table of Content widget which is super flexible compared to the one I am using right now.
For an alternative solution, I use the LuckyWP Table of Contents and set it up to automatically insert headings not via the shortcode method. This plugin is not dependent on jQuery. If you use their shortcode then jQuery will be used to load the table of content items.
Plugin Recommendations:
All the plugins I recommend below have the feature for generating critical CSS, removing unused CSS, the ability to compress images, CSS, and JS, and serving the images in Next-Gen image format automatically such as
- FlyingPress
- WP Rocket
- Swift Performance
- Perfmatters
- Autoptimize + RapidLoad + Critical CSS API + Shortpixel Adaptive AI combined (This is great if you already have Server-side caching & CDN that handle your page level caching & you don’t want any conflict).
Reference
- Optimizing Largest Contentful Paint- CSSWizardry
- A deep dive into optimizing LCP – Google Chrome Developers. (Video)
- Web-Vitals JS libraries – Github
- Measure and debug performance with Google Analytics 4 and BigQuery- web.dev.
- Web Almanac – Performance chapter
Deep dive:
- Pagespeed Insights – Field Data report vs CrUX
- RUM & CrUX difference
- Chrome UX report update
Dear WordPress Plugin/Theme Devs, You Don’t Need jQuery by WP Speed Matters.
- Do you use Cookie Banner on your site? follow the best practices for cookie notice
Highly recommend reading Massimo Villa’s article on how to get 100% in speed tests.
Conclusions
Do you think your site’s flying in the lab? Wait until you see what real users experience! Yeah, that was me… twice. Trust me, a RUM solution is like a superhero for your website. It reveals the hidden villains (performance issues) that you and your visitors need to avoid. So, don’t be like me. Embrace the RUM, protect your users, and watch your website shine!