In early April 2022, I noticed that on LinkedIn, many posts about web performance were spreading misconceptions, hearsay, and "magic" methods for a fast site. Annoyed and saddened by the number of likes, shares, and comments on these posts, I decided to share some of my knowledge and experience on LinkedIn in turn.
Below, I have reorganized by major themes the concrete, verifiable, and proven information that I shared there over the weeks. It may sometimes seem technical, but the concise format of each point allows you to understand what needs to be done concretely to improve a website's performance. I hope you will appreciate this compilation and wish you an excellent read.
Optimizing a website involves reducing the work the server and browser need to do to display a page, and then prioritizing what remains. The biggest gains come from the server and images, before JavaScript and CSS. The 117 tips below, grouped by theme, cover each of these areas.
Browser rendering
- For a site to load quickly (typically LCP metric), the HTML must be loaded as early as possible (after being rendered server-side), followed by CSS (synchronously if less than 50 KB), fonts, images, and then JavaScript (asynchronously or deferred). JS therefore comes LAST!
- The heavier the structure of a page, the less performant it will be: browser rendering times increase. This is materialized by the DOM, which should be as light as possible (less than 1500 nodes) and with a minimum of nesting levels (less than 32). This is an area where most WordPress Page Builders falter.
- Preloading resources like fonts or certain scripts (preload) is a good practice. But beware of side effects: overusing it can have the opposite effect, sometimes with a major impact. It is often better to let browsers manage priorities, which they are doing better and better.
- The new HTML attribute
fetchpriorityallows you to modify the download priority of resources. It can be useful for changing the browser's default behavior, by de-prioritizing third-party scripts or re-prioritizing an image that constitutes the LCP, for example. - Do you want to speed up the download of resources hosted on a third-party server? Prefer the resource hint
preconnectrather thandns-prefetch: the former will perform not only DNS resolution, but also the initial connection and SSL negotiation. - Are you using
dns-prefetchorpreconnectResource Hints? Be sure to limit their number and prioritize them (the most important ones first). As these tools offer no guarantee of execution, it often happens that the latter are simply ignored. - Browsers can now instantly display a page when navigating using their Back and Forward buttons. Check that your site does not block the use of this " Back/Forward cache " feature, which guarantees top Core Web Vitals (DevTools > App > Enhanced Cache).
- If your site is " Responsive ", the switching mechanism must be entirely based on CSS Media Queries and defined breakpoints. JavaScript should never be used, let alone User Agent detection, to adapt the rendering to different devices.
- If your pages include animations, especially on user action (hover, click...), implementing CSS containment can help improve their fluidity. Containment reduces unnecessary repaints and reflows, resulting in better interactivity (INP metric).
- If your pages include embeds (YouTube, TikTok, Instagram...), be sure to implement native lazy-loading on their
<iframe>via theloading="lazy"attribute. This will significantly improve performance, as these third-party tools execute a large volume of JavaScript, among other things. - Never animate the main elements of the initial viewport, such as titles or hero images. Beyond the additional CPU load due to rendering, a late appearance effect artificially delays visual performance-oriented metrics (LCP and Speed Index).
- Is your site multi-page? Deploy the Speculation Rules API, which considerably improves overall performance. It is deployed via a simple
<script type="speculationrules">tag, and should ideally be configured in pre-rendering mode with a moderate level of aggressiveness. - A broken resource (
404error, failed script) is a silent loss: wasted network time, broken functionality, and sometimes blocked rendering or interactivity. Regularly check the JavaScript console and the Network tab of your browser to track down and fix these errors. A healthy site is a site without dead requests.
Core Web Vitals
- PageSpeed Insights IS NOT what Google takes into account! It is a test tool (so-called synthetic) whose mobile section is heavily biased. Some third-party tools (GTmetrix, Webpagetest...) offer a more accurate overview of real mobile performance.
- What Google takes into account is data from REAL visitors, particularly under Google Chrome. This is the data found in Search Console (CrUX) and used in its algorithm (Page Experience section).
- The Core Web Vitals section of Google Search Console is ideal for understanding performance issues affecting a site. It shows which page groups are experiencing LCP, CLS, and INP issues on desktop and mobile. It's practical for starting a performance optimization project.
- Time To First Byte (TTFB) is useful for identifying server response time and/or caching issues. It is an essential and indispensable performance indicator as it mechanically impacts FCP, LCP, and Speed Index.
- The new INP metric introduced by Google aims to ensure that a page is fluid throughout its use. It demonstrates Google's desire to better estimate the quality of the user experience throughout their navigation, and not just during loading.
- The 'load time' provided by Google Analytics is not a relevant performance indicator: it is neither reliable, nor exhaustive, nor representative of the real user experience. For web performance management, favor metrics like Core Web Vitals from CrUX.
- If you have to choose a single KPI for web performance, LCP (Largest Contentful Paint) is the most relevant. It is easily obtained for real users (CrUX field data) and via synthetic tools, while fairly reflecting the overall loading experience of a page.
- The official metrics do not meet the specific needs of a site? Use the Performance Element Timing API: it allows you to define your own performance indicators with a simple HTML attribute
elementtiming="name", and then retrieve them with a RUM tool.
Hosting / server
- Combining multiple CSS or JS files offers a significant weight saving: 2 files of 10 KB will weigh only 17 KB if grouped together. This is related to compression mechanisms (Gzip and even more so Brotli), which are very effective with these repetitive code languages.
- Minifying HTML code does not provide significant performance gains, mainly due to Gzip and Brotli compression. The duration of the operation can even be longer than the gains in download time, negatively impacting TTFB and LCP metrics.
- If a site is optimized with a cache system + minification / combination / defer (e.g., WordPress + WP Rocket), a CDN like Cloudflare won't add much and can even create page latency if the server is located in the target country.
- Deploying a CDN improves the overall performance of international sites. However, opt for a global CDN, in proxy mode, rather than a CDN that only targets images and/or static resources. This effectively reduces the impact and can even have negative effects on FCP and LCP.
- Any Apache, Nginx, or other server must serve resources over HTTP/2. The protocol offers considerable room for improvement compared to HTTP/1.1 in terms of web performance (especially for simultaneous downloads). However, many sites still run on the old HTTP/1.1 protocol.
- If your host or CDN offers HTTP3 activation, enable it! Compared to HTTP2, the protocol allows for a significant improvement in server response times (TTFB), thanks in particular to the QUIC transport protocol, which speeds up connection establishment and eliminates head-of-line blocking.
- Always set a Content-Security-Policy header. This approach not only improves security for your visitors but also allows you to take stock of the resources used by a site. Knowing what is loaded in JS, CSS, images, or fonts is essential for performance!
- Enable the latest version of TLS on your server (currently 1.3). The secure communication protocol evolves regularly to ensure faster exchanges between the browser and the server. This helps improve FCP, LCP, and Speed Index.
- Static resources (images, webfonts, JavaScript, CSS, etc.) should be served with a header defining a browser cache policy. The best practice is to set an expiration time of one year (31,536,000 seconds) to avoid unnecessary re-downloads.
- Are your static resources versioned by fingerprint in their name (e.g., app.4f2a.css)? Add the
immutabledirective to theirCache-Controlheader, in addition to a longmax-age. The browser will stop unnecessarily revalidating these files when pages reload, whereas a simplemax-agesometimes triggers a superfluous conditional request. - Always test your site with the latest version of PHP. If it works correctly (no
500errors), keep it: each new evolution of the server language offers performance gains, which reduces response times (TTFB metric). - Do your pages take a long time to load without an active cache system (high TTFB)? This means your server is undersized for your needs (processor and RAM). Switch to more powerful hosting or reduce the volume / optimize the quality of your code.
- Enabling OCSP Stapling on a server can improve TTFB on the first connection for some users. The browser no longer needs to verify the validity of the TLS certificate served by the issuing authority, eliminating costly network round trips.
- Avoid multiplying
301redirects in your.htaccessfile: this slows down Apache and therefore increases server response times (TTFB). If their number exceeds500, opt for using a PHP script or a specialized extension if one exists for your CMS. - Does your host or CDN allow the use of "103 Early Hints"? Enable the feature: when configured correctly, it allows critical resources (CSS, webfonts) to start downloading before the pages themselves. Gains in FCP and LCP can be significant.
- Text-encoded resources (CSS, JavaScript, HTML, etc.) should be compressed using Gzip or, even better, Brotli. This considerably reduces their weight, with a major impact on loading time metrics like FCP, LCP, and Speed Index.
- If you use a CMS like WordPress or PrestaShop and your host offers an object caching technology like Redis, Memcached, or APCu, enable it. Object caching reduces the volume of SQL queries, significantly improving TTFB for dynamic pages.
- Always prioritize server-side security solutions. A Web Application Firewall (WAF) or malware scanner will always be significantly more performant when managed on the hosting side than through a PHP extension or script. The impact on TTFB can be significant.
- Does your CMS or page builder offer to display a selection of content (articles, products, etc.) randomly? Never opt for such a feature: it results in inefficient SQL queries that negatively impact response times (TTFB).
- Ensure that the DNS configuration of your subdomains, including www, does not use CNAME records. By not pointing directly to your server's IP address (A or AAAA records), this impacts response times (TTFB metric) by about 30%.
- If your web hosting has an IPv6 address, add the appropriate DNS records (AAAA records) for your root domain (key @) and its subdomains, including www. Gains in response time (TTFB metric) can be significant.
CSS (styles)
- The larger the CSS volume, the worse the performance. The penalty is twofold: a larger file takes longer to download, and its execution time by the browser's rendering engine is extended. This impacts FCP and LCP.
- CSS offers several very useful properties from a web performance perspective. This is the case for
aspect-ratio, which can be used as a last resort to reduce CLS. But also forcontent-visibilitywhich, set to auto and combined withcontain-intrinsic-size, reduces rendering times. Or even for contain: content, which reduces the risks of repaint/reflow. - Any ad unit whose content is loaded via JavaScript (like Google Ads or Taboola) must have a minimum height defined in CSS. Without this "space reservation", it will generate Layout Shifts when it loads. This is very often the primary cause of CLS on editorial/publisher sites.
- If your site uses animations, especially looping ones, make sure they are based on the CSS
transformandopacityproperties. These are the only ones that allow you to take advantage of the highest level of graphical performance available in modern browsers. - NEVER embed images, and even less so webfonts, encoded in base64 within your CSS files. This contributes to exploding file sizes, which heavily penalizes FCP and LCP. There should only be CSS in CSS files.
- The mobile-first approach should systematically be favored when targeting a device type via CSS. With this in mind, prefer Media Queries based on
min-widthrather thanmax-width: the default behavior is the small screen, which is then supplemented on tablets and computers. - The popular hack for downloading stylesheets asynchronously (preload with onload event) can have negative effects on performance. It can generate Layout Shifts as well as repaints and reflows that increase page rendering time.
- Avoid modifying the order of vertical elements via the "flex-direction" and "order" properties of CSS Flexbox: this can generate Layout Shifts (CLS metric) and Blocking Time (TBT metric). For optimal rendering, prefer modifying the order directly in the HTML code.
- Limit the use of CSS declarations that include the universal selector (*): browsers must evaluate them for every element in the DOM. This generates high CPU resource consumption, which extends rendering times and can impact INP during interactions.
- CSS functional pseudo-classes like
:is(),:has(),:where(), and:not()offer great flexibility in DOM targeting. However, this comes at the cost of increased CPU usage, potentially impacting Blocking Time and the INP metric. Therefore, limit their use. - Do you use CSS preprocessors to create your stylesheets? Limit nesting levels: this generates highly specific CSS selectors that bloat resources and slow down browser rendering engines. This particularly impacts TTI and LCP.
- With rare exceptions like
font-smooth,text-stroke, orbox-reflect, vendor prefixes targeting webkit (-webkit), Firefox (-moz), Opera (-o), and IE/Edge (-ms) browsers are unnecessary. Using them unnecessarily increases stylesheet weight and CSSOM generation times.
Is your site as fast as your visitors expect?
JavaScript
- The larger the JavaScript volume, the worse the performance. Third-party scripts like Google Analytics, Google Ads, or Recaptcha notably consume a lot of processor time to execute, generating latency and stuttering in the browser (TBT and INP metrics).
- Some tools like WP Rocket allow delaying JavaScript execution until the first interaction (click, scroll, or hover). Do not use it on your theme's scripts, or you risk making your mobile menu non-functional, or even generating CLS on poorly coded themes.
- Need to highlight trust badges like your customer ratings from Trustpilot or Avis Vérifiés? Do not use the widgets provided by your partners, as they are not optimized. A simple image with a link will have the same effect and considerably improve loading times.
- GDPR cookie managers / CMPs offer a significant performance gain for new users and synthetic testing tools like PageSpeed Insights. Third-party scripts are indeed only loaded later, after the user has consented.
- Never modify a page's initial style via JavaScript or jQuery. Any visual modification should be done directly in CSS and not through dynamic addition of classes or styles. This practice leads to resource-intensive CPU repaint and reflow operations and can generate CLS.
- The asynchronous loading tags provided by most third-party tools, including Google Tag Manager, have a major impact on performance. Prefer a native call via a
<script>tag with adeferattribute rather thanasync: this is the only solution to avoid blocking page rendering. - A/B testing tools like Kameleone and AB Tasty should be used very sporadically and deactivated at the end of each test campaign. Their impact is indeed major in terms of Blocking Time, which contributes to increasing INP and LCP metrics.
- A third-party script only runs when hovering over a button? Implementing a "facade" can reduce its impact on page load (TBT, INP...) by conditioning its loading to hovering over that area. VOC tools like Zendesk are particularly well-suited for this.
- Need to display social sharing buttons? Do not use third-party tools like AddThis or ShareThis, which load tens of kilobytes of JavaScript resources and generate Blocking Time. Prefer self-hosted tools with minimal JavaScript and CSS.
- If your site offers an interactive feature requiring significant user-side calculations, use a Service Worker or Web Worker. These browser APIs can execute JavaScript with their own CPU resources, significantly reducing TBT and INP metrics.
- Need to secure a registration, contact, or newsletter subscription form? Avoid JavaScript-based Captchas at all costs, especially Google ReCaptcha. Prefer a Honeypot or server-side verification after submission.
- Are your pages loading a large volume of JavaScript, increasing Blocking Time and harming INP? Use the
requestIdleCallback()API to intelligently defer their execution until the browser has sufficient CPU resources. - Are your pages listening for scroll or touch events (scroll, touchstart, wheel)? Declare these listeners as passive with
{ passive: true }. Otherwise, the browser must wait for your handler to finish to know if it intends to cancel the scroll, which causes scroll jank and degrades INP. In passive mode, it scrolls immediately.
Images
- All images called via an HTML
<img>tag must systematically be associated withwidthandheightattributes. This allows the browser to know their display ratio before downloading them, eliminating any risk of Layout Shift when pages load. - Be sure to integrate images into your content whose intrinsic dimensions are close to the dimensions displayed on the screen. In WordPress, as with other CMSs, page builders allow you to choose an image size, for both mobile and desktop.
- Sizing the image as close as possible to its display is good; letting the browser choose the resolution based on the screen and pixel density is better. Serve multiple sizes via the
srcsetandsizesattributes: a mobile device will never download an image intended for a large Retina screen again. To change the framing or negotiate the format (AVIF, then WebP, then JPEG), use the<picture>element. A direct lever on LCP. (Images) - Use the right image formats: PNG or SVG for logos, icons, and pictograms, JPG for photos. Don't bother generating WEBP or AVIF images yourself, as they are now supported by all browsers: use a tool like an extension or CDN (like Cloudflare).
- If you use a lazy-loading mechanism, do not apply it to images visible in the viewport. This particularly concerns the logo in the header, but also sometimes the featured images on article pages. Disabling lazy-loading on these elements can significantly reduce LCP.
- Whenever possible, prefer native lazy-loading (
loading="lazy"HTML attribute) over solutions based on JavaScript (Lazysizes, Lozad…). This will indeed be more performant, especially in terms of interactivity where TBT and INP suffer from script execution in the main thread. - If your site only displays a few icons, do not use the Font-Awesome icon font which contains over 700 characters. Prefer using inline SVG images, which also ensure vector rendering but with a much lower weight. Or, failing that, a custom icon font created via Icomoon.
- Image display can block the rendering of other elements, impacting display time and fluidity. To avoid this, images called via an HTML
<img>tag must all have thedecoding="async"attribute. They will then be displayed once decoded independently of the rest of the page. - The use of SVG is optimal for logos and pictograms. Be careful, however: the file must be based on paths to be vector, and must never integrate PNG or JPEG images encoded in base64. Such use is totally counterproductive.
- If a photo-type image needs to be displayed with transparent areas, do not turn to the PNG format. Prefer classic JPEG combined with CSS styling like border-radius or an SVG mask. This will always be significantly lighter.
- Are you using SVG vector images for your icons, logos, or illustrations? Excellent, but make sure to optimize their paths before putting them online. Most files downloadable online or provided by graphic designers include unnecessary elements that make them heavier.
Videos
- NEVER load YouTube videos with your pages, let alone autoplay (bad UX practice) because the iframe calls a lot of JavaScript, but also CSS and a font. Defer its loading with native lazy-loading (
loadingattribute) or a facade library like LazyTube. - Never offer MP4 videos by default: prefer Webm, which supports more modern codecs and is therefore lighter. The MP4 format should still always be offered as a fallback using a
<video>tag with the appropriate sources. - Does your site integrate videos hosted on your own server? Always offer a preview image using the
posterattribute of the<video>tag. Not only will it display on mobile by default, but this image will constitute the LCP element if the video is in the initial viewport.
Fonts
- Beware of fonts! Use one family if possible, possibly 2 but no more. Limit the number of variations: a Regular (400) and Bold (700) version are often sufficient. Many themes and Page Builders load all style and weight variations, thus crippling performance.
- Fonts should always be loaded locally. Google Fonts and Adobe Typekit are convenient, but they are performance drains. The negative effect is twofold: longer download times due to network latency and inability to pre-load fonts.
- Not all fonts are equal in terms of web performance: depending on the complexity of their glyphs, files weigh more or less (for equivalent subsets). Prefer light webfonts like Poppins, Jost, Albert Sans, or Oswald, all around 10 KB in Woff2 format.
- If you use a font available in "Variable Font" format, prefer it over classic individual weight variations. There will only be one Woff2 file to download and pre-load, and you will have access to more weights.
- If you self-host variable font files, congratulations. However, make sure they only include what is necessary: they often contain unused "axes": weights (Regular, Bold...), slant (more or less italic), or width (more or less condensed). Their weight will decrease.
- Locally hosted text fonts should be preloaded using a
<link rel="preload">tag to ensure faster text rendering and reduce CLS. Be careful, however: only the woff2 version should be preloaded, with one file per weight variation. - Font files should never include unused subsets: this unnecessarily increases their weight, with a major impact on LCP. For French and/or English sites, the "Basic Latin" and "Latin-1 Supplement" subsets are generally sufficient to display all text.
- When declaring a font stack using the CSS
font-familyproperty, only the first font should be a custom type: the following ones should be system fonts. Declaring multiple custom fonts can lead to downloading multiple unused files, causing LCP and Speed Index to drop. - Many third-party tools and front-end extensions (CMP, VOC, marketing pop-ups, etc.) use their own font sets. Ensure, whenever possible, that you modify their behavior so that they inherit the default font of your pages (value "inherit").
- Are you calling fonts via a CSS
@font-facedeclaration? Optimizing the font stack by choosing visually similar fallback fonts in your font-family declarations can reduce CLS. A custom fallback font can even be created withsize-adjustandascent-override.
UX/UI
- Limit the number of animations: they are generally as costly for performance as they are disruptive in terms of UX. If you must include them, they should ideally rely on the CSS
transformandopacityproperties. Avoid JavaScript frameworks likeanimate.js, Lottie... - Full-page loaders like "spinner" or "loading bar" are strongly discouraged. They penalize the User Experience by hiding all content for several seconds. This translates, in terms of metrics, into a significant increase in LCP and Speed Index.
- Limit the use of sliders and other carousels. They make some content invisible to visitors while imposing a less natural navigation interface than scrolling. They also often rely on large amounts of JavaScript, significantly increasing TBT and INP (see our article on sliders).
- If you use sliders, carousels, or automatically scrolling areas, make sure to include content of the same height. Many extensions adapt the height of the area to its visible content, so that the entire page experiences constant Layout Shifts.
- Do not modify the native scrolling behavior of browsers with JavaScript. This is justified for "fullpage" type sites that function like slideshows, but it is unnecessarily costly for the browser and disruptive to the User Experience in any other context.
- Do you want to display sensitive data (phone number, email address...) while preventing it from being read by unscrupulous bots? Rather than using images, favor JavaScript with base64 encoding. This way, the text will remain selectable and clickable by (real) visitors.
- Is a text "too long" to display on your mobile site? Never hide it using CSS (with text-overflow: ellipsis, for example). In a mobile-first approach, all text must be readable regardless of the resolution of the viewing device.
- If a page template has a limited width, never use options to extend areas horizontally outside of it via JavaScript: this is very CPU-intensive and generates Layout Shifts. Favor native full-width templates.
- If your site offers push notifications, never activate a subscription invitation window on the first display: this behavior is intrusive in terms of User Experience and generates Blocking Time. Favor a button within the pages, ideally after the content.
- It is not recommended to provide a specific mobile version of your site, including AMP. Native browser APIs and tools include what is necessary to ensure optimal mobile performance. Simplify your stack with a single "Responsive" site based on CSS Media Queries.
SEO
- The impact of web performance on rankings in Google's results pages is unknown: no study proves its effects on SEO. However, optimizing improves user experience, and therefore conversions.
- Contrary to popular belief, obfuscating links to optimize site crawling is simple to implement with about ten lines of JS. There is nothing complex about it, and it can have very beneficial effects for both SEO and good control of the "crawl-budget".
- Google Search Console offers a detailed overview of how Googlebot crawls sites. This little-known feature is accessible via the Settings menu > Crawl Stats > Open Report. It shows the average response times and daily crawl volume, which helps understand indexing issues.
- Some tools in the Alphabet ecosystem, like Google Discover, are particularly sensitive to the web performance of sites. To integrate the tool and remain visible there sustainably over publications, it is essential to pass the Core Web Vitals at the site (origin) level.
WordPress
- On WordPress, post revisions and auto-drafts can quickly inflate the database size. It is important to regularly clean these elements to reduce SQL query execution time. This improves TTFB.
- Gutenberg is good. WordPress’s native editor has evolved enormously over the past 2 years and can now be used as an alternative to traditional page builders. Combined with block libraries (GenerateBlocks, Ultimate Blocks…), it allows you to create any complex layout while generating minimal DOM and CSS.
- If you are not using the Gutenberg block editor as a Page Builder, disable its stylesheets on your site. This is not automatic and can unnecessarily increase the CSS volume, thus contributing to a higher FCP and LCP.
- As a WordPress site evolves, the theme and plugins may change. However, when they are deactivated, they generally leave traces in the wp_options table. Manually deleting them reduces the size of this crucial SQL table, improving TTFB.
- By default, WordPress executes background tasks when pages are opened, which can lead to increased load and slowdowns. Prefer running cron jobs on the server every 2 to 5 minutes. This will improve the TTFB of dynamic pages.
Themes
- If you want a fast WordPress site, don’t buy a large popular theme from Themeforest. The best approach is to start with something lightweight and adapt it to your needs through plugins. The opposite approach (disabling many features) often comes at a high cost in terms of loaded CSS and JS.
- Beware of certain “responsive” themes whose header actually relies on the presence of 2 distinct headers: one for mobile, the other for desktop. All header links, especially the main menu, are present twice, which bloats the DOM and is not optimal for SEO.
- When creating or redesigning a WordPress site, always use a child theme. This will allow you to integrate modifications, for web performance among other things, while continuing to benefit from updates to the base theme.
Plugins
- There is no magic plugin to improve WordPress performance. Even the excellent WP Rocket requires configuration and its options must be carefully tested to maximize its impact on Core Web Vitals. The configuration differs for each site.
- On WordPress, caching plugins drastically improve FCP and LCP for visitors and bots. They also relieve the server in terms of processor and memory resources, which reduces response times for logged-in users.
- When a WordPress plugin requires a database update (WooCommerce, Yoast SEO…), do it quickly. Otherwise, SQL queries will not be optimized, which can slow down loading times in the administration area and for uncached pages.
- When installing a WordPress plugin, systematically check the weight of the CSS and JS resources loaded on the public site. Plugins often represent more than 2/3 of the CSS volume, which contributes to the increase in FCP and LCP.
Do you appreciate this sharing but need operational support to go further? Do not hesitate to contact Agence Web Performance, it's our job!