103 pro tips to improve your site’s performance

Eroan Boyer

17 minutes

At the beginning of April 2022, I noticed that on LinkedIn, numerous posts on web performance were spreading misconceptions, “gossip” and “magic” methods to get a site up and running fast. Annoyed and saddened by the volume of likes, shares and comments on these posts, I decided to share some of my knowledge and experience on LinkedIn.

Below, reorganized by major theme, I’ve listed the concrete, verifiable and proven information I’ve shared over the weeks. It may seem technical at times, but the concise format of each point makes it easy to understand what needs to be done in concrete terms to improve a website’s performance. I hope you enjoy this compilation and wish you an excellent read.

Browser rendering

  • For a site to be fast to display (typically the LCP metric), html must be loaded as soon as possible (after server-side rendering), followed by CSS (in sync if less than 50kb), fonts, images and then Javascript (in async or defer). JS comes LAST!
  • The heavier the structure of a page, the lower its performance: browser rendering times become longer. This is reflected in the DOM, which must be as light as possible (less than 1,500 nodes) and with as few nesting levels as possible (less than 32). This is a shortcoming of most Page Builders for WordPress.
  • Preloading resources such as fonts or certain scripts is a good practice. But beware of side effects: overdoing it can have the opposite effect, sometimes with a major impact. It’s often better to let browsers manage priorities, which they’re doing better and better.
  • The new fetchpriority html attribute lets you modify the download priority of resources. It can be useful for modifying the browser’s default behavior, by de-prioritizing third-party scripts or re-prioritizing an image that constitutes the LCP, for example.
  • Would you like to speed up the download of resources hosted on a third-party server? Choose the “preconnect” resource hint rather than “dns-prefetch”: the latter will not only perform dns resolution, but also the initial connection and SSL negotiation.
  • You’re using Resource Hints like dns-prefetch or preconnect? Make sure to keep their number to a minimum and prioritize them (the most important ones first). As these tools offer no guarantee of execution, the last ones are often simply ignored.
  • Web browsers can now instantly display a page when navigating via their Back and Forward buttons. Check that your site doesn’t block the use of this “Back/Forward cache” feature, which guarantees top-notch Core Web Vitals (DevTools > Application > Enhanced Cache).
  • If your site is “Responsive”, the switching mechanism must be based entirely on CSS Media Queries and defined breakpoints. You should never use JavaScript, and certainly not User Agent detection, to adapt rendering to different devices.
  • If your pages include animations, especially on user action (hover, click…), implementing CSS containment can help improve smoothness. Containment reduces unnecessary repaints and reflows, resulting in improved interactivity (INP metric).
  • Never animate the main elements of the initial viewport, such as titles or headline images. Apart from the additional CPU load due to rendering, a late-appearance effect artificially delays visual performance-oriented metrics (LCP and Speed Index).
  • If your pages integrate embeds (YouTube, TikTok, Instagram…), be sure to set up native lazy-loading on their <iframe> via the loading="lazy" attribute. This will greatly improve performance, as these third-party tools execute a large volume of JavaScript, among other things.

Core Web Vitals

  • Page Speed Insights is NOT what Google takes into account! It’s a test tool (called synthetic) whose mobile component is heavily biased. Some third-party tools (GTmetrix, Webpagetest…) offer a more accurate view of real performance on mobile.
  • What Google does consider is ACTUAL visitor data, especially under Google Chrome. It’s this data that can be found in Search Console (CrUX) and is used in its algorithm (Page Experience section).
  • The Core Web Vitals area of Google Search Console is ideal for understanding the performance issues affecting a site. It shows which sets of pages are experiencing LCP, CLS and FID problems on desktop and mobile. It’s a handy way to get started on performance optimization.
  • Time To First Byte (TTFB) is useful for identifying server response time and/or caching problems. It is an essential 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 reflects Google’s desire to better assess the quality of the user experience throughout the browsing experience, and not just when the page loads.
  • The “load time” provided by Google Analytics is not a relevant performance indicator: it is neither reliable, exhaustive nor representative of the real user experience. For web performance management, use metrics such as Core Web Vitals from CrUX.
  • If you have to choose a single KPI for webperf, LCP (Largest Contentful Paint) is the most relevant. It’s easy to obtain for real users (CrUX field data) and via synthetic tools, while reflecting the overall page loading experience fairly well.
  • Official metrics don’t match your site’s specific needs? Use the Performance Element Timing API: it lets you define your own performance indicators with a simple elementtiming=”name” html attribute, then retrieve them with a RUM tool.

Web hosting

  • Combining several CSS or JS files offers interesting weight savings: 2 files of 10 kB will only weigh 17 kB if grouped together. This is due to compression mechanisms (Gzip and Brotli), which are very effective with these languages and their recurring code.
  • If a site is optimized with a cache + minification / combination / defer system (such as WordPress + WP Rocket), a CDN like Cloudflare won’t do much, and may even generate page-side latencies if the server is located in the target country.
  • Deploying a cdn improves the overall performance of international sites. However, a global cdn in proxy mode is preferable to a cdn that only targets images and/or static resources. This reduces the impact and may even have negative effects on FCP and LCP.
  • Any Apache, Nginx or other server must serve http/2 resources. This protocol offers considerable scope for improvement over http/1.1 in terms of web performance (especially in terms of simultaneous downloads). However, many sites still use the old http/1.1 protocol.
  • If your web hosting provider or cdn offers HTTP3, turn it on! Compared with HTTP2, this protocol significantly improves server response times (TTFB), thanks in particular to multiplexing of requests and better compression of http headers.
  • Systematically define a Content-Security-Policy header. This approach not only improves security for your visitors, but also allows you to establish an inventory of the resources used by a site. Knowing what is loaded in JS, CSS, images or fonts is essential for performance!
  • Activate the latest version of TLS on your server (currently 1.3). The secure communication protocol evolves regularly to ensure ever-faster exchanges between browser and server. This helps improve FCP, LCP and Speed Index.
  • Static resources (images, webfonts, JavaScript, CSS…) must be served with a header defining a browser cache policy. The best practice is to set an expiration time of one year (31536000 seconds) to avoid unnecessary re-downloads.
  • Always test your site against the latest version of php. If it’s working properly (no 500 errors), keep it: each new evolution of the server language offers performance gains, which help reduce response times (TTFB metric).
  • Are your pages taking a long time to load without a cache system activated (high TTFB)? Then your server is undersized for your needs (processor and ram). Switch to a higher-performance hosting package or reduce the volume / optimize the quality of your code.
  • Enabling OCSP Stapling on a server can improve TTFB on first connection for some users. The browser no longer needs to check the validity of the TLS certificate served with the issuing authority, eliminating costly network round-trips.
  • Avoid multiplying 301 redirects within your .htaccess file: this slows down Apache and therefore increases server response times (TTFB). If the number of redirects exceeds 500, use a php script or a dedicated extension if available for your CMS.
  • Does your web host or cdn support “103 Early Hints”? Activate this feature: properly configured, it allows you to start downloading critical resources (CSS, webfonts) before the pages themselves. The gains in FCP and LCP can be substantial.
  • Text-encoded resources (CSS, JavaScript, HTML…) should be compressed using Gzip or, better still, Brotli. This considerably reduces their weight, with a major impact on load time metrics such as FCP, LCP and Speed Index.
  • If you’re using a CMS like WordPress or Prestashop and your hosting provider offers object caching technology like Redis or Memcached, activate it. An object cache 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 efficient when managed on the hosting side than through a plugin or a script written in PHP. The impact on the TTFB can be significant.

CSS (styles)

  • The larger the CSS file, the poorer the performance. The penalty is twofold: a larger file takes longer to download, and the browser rendering engine takes longer to execute. This has an impact on FCP and LCP.
  • CSS offers several very useful properties from a web performance perspective. These include aspect-ratio, which can be used as a last resort to reduce CLS. But also content-visibility, which, when set to auto and combined with contain-intrinsic-size, reduces rendering times. Or contain: content, which reduces the risk of repaint/reflow.
  • Any advertising insert whose content is loaded via JavaScript (such as Google Ads or Taboola) must have a minimum height defined in CSS. Without this “space reservation”, it will generate Layout Shifts when loaded. This is often the primary cause of CLS on editorial/publisher sites.
  • If your site uses animations, especially looping animations, make sure they are based on the CSS properties transform and opacity. These are the only ones that can take advantage of the highest level of graphic performance available in modern browsers.
  • NEVER embed images or base64-encoded webfonts in your CSS files. This causes file sizes to explode, which is a serious disadvantage for FCP and LCP. CSS files should only contain CSS.
  • The mobile-first approach should always be favored when targeting a device type via CSS. With this in mind, use Media Queries based on min-width rather than max-width: the original behavior is small screen, which is completed on tablet and then computer.
  • The popular hack for downloading stylesheets asynchronously (preconnect with onload event) can have negative effects on performance. It can generate Layout Shifts as well as repaint and reflows that increase page rendering time.
  • Avoid modifying the order of vertical elements via CSS Flexbox’s “flex-direction” and “order” properties: this can generate Layout Shifts (CLS metric) and Blocking Time (TBT metric). For optimum rendering, it’s best to modify the order directly in the html code.
  • Limit the use of CSS declarations incorporating the universal selector (*): browsers must evaluate them for each DOM element. This consumes a lot of CPU resources, lengthening rendering times and impacting the NPI during interaction.
  • Are you using CSS pre-processors to create your stylesheets? Limit nesting levels: this generates very specific CSS selectors that weigh down resources and slow down the browser rendering engine. This has a particular impact on TTI and LCP.

JavaScript

  • The greater the volume of JavaScript, the poorer the performance. In particular, third-party scripts such as Google Analytics, Google Ads or Recaptcha consume a lot of CPU processing time to execute, generating latency and jitter in the browser (TBT and FID on the metrics side).
  • Some tools, such as WP Rocket, allow you to delay JavaScript execution while waiting for the first interaction (click, scroll or hover). Don’t use it on your theme’s scripts, otherwise your mobile menu may not function properly, or even generate CLS on poorly coded themes.
  • Need to highlight reassurance inserts such as your Trustpilot or Trusted Reviews customer rating? Don’t use the non-optimized widgets provided by your partners. A simple image with a link will have the same effect and considerably improve loading times.
  • CMPs / RGPD cookie managers offer interesting performance gains for new users and synthetic testing tools such as Page Speed Insights. This is because third-party scripts are only loaded at a later stage, after the consent of the user has been granted.
  • Never modify the initial style of a page via JavaScript or jQuery. Any visual modification must be made directly in CSS, not by dynamically adding classes or styles. This practice leads to CPU-intensive repaints and reflows, 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 a defer attribute rather than async: this is the only solution to avoid blocking page rendering.
  • A/B testing tools such as Kameleoon and AB Tasty should be used very punctually, and deactivated at the end of each test campaign. They have a major impact in terms of Blocking Time, which helps to increase FID and LCP metrics.
  • Does a third-party script only run when a button is hovered over? Setting up a “facade” can reduce its impact on page loading (TBT, FID…) by making its loading conditional on hovering over this zone. VOC tools like Zendesk are especially well-suited to this game.
  • Need to display social sharing buttons? Don’t use third-party tools like AddThis or ShareThis, which load tens of kilobytes of JavaScript resources and generate Blocking Time. Go for self-hosted tools with a minimum of JavaScript and CSS.
  • If your site offers interactive functionality that requires significant user-side computation, use a Service Worker or a Web Worker. These browser APIs can execute JavaScript with their own CPU resources, significantly reducing TBT, FID and INP metrics.

Images

  • All images called up via an html <img> tag must always be associated with width and height attributes. This allows the browser to know their display ratio before downloading them, eliminating any risk of Layout Shift when loading pages.
  • Make sure your content includes images whose intrinsic dimensions are close to those displayed on the screen. In WordPress, as with other CMS, page builders allow you to choose an image size for both mobile and desktop.
  • 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, which must be offered with a fallback in PNG or JPG: use a plugin or CDN tool (like Cloudflare).
  • If you use a lazy-loading mechanism, do not apply it to images visible in the viewport. This applies in particular to the header logo, but also sometimes to the front-page images on article pages. Disabling lazy-loading on these elements can significantly improve the LCP.
  • Whenever possible, prefer native lazy-loading (attribute html loading=”lazy”) to JavaScript-based solutions (Lazysizes, Lozad…). This will deliver better performance, particularly for interactivity, where TBT and INP suffer from scripts running in the main thread.
  • If your site only displays a few icons, don’t use Font-Awesome icon-font, which contains more than 700 characters. Instead, use SVG inline images, which also render vectorially, but are much lighter. Or, as an alternative, a custom icon-font created using Icomoon.
  • Displaying images can block the rendering of other elements, impacting display time and fluidity. To avoid this, all images called up via an <img> html tag must have the decoding="async" attribute. Once decoded, they will then be displayed independently of the rest of the page.
  • SVG is ideal for logos and pictograms. Please note, however, that to be vector-based, the file must be based on paths, and must never include base64-encoded PNG or JPEG images. Such use is totally counterproductive.
  • If a photo image is to be displayed with transparent areas, don’t use PNG. Instead, opt for the classic JPEG with border-radius CSS formatting or an SVG mask. This will always be much lighter.
  • Do you use SVG vector images for your icons, logos or illustrations? Excellent, but make sure you optimize their paths before putting them online. Most of the files available for download online or supplied by graphic designers include useless elements that increase their weight.

Videos

  • NEVER load a YouTube video onto your pages, and even less in auto-play mode (bad UX practice), as the iframe requires a great deal of JavaScript, as well as CSS and a font. Defer loading with native lazy-loading (attribute loading) or a front-end library like LazyTube.
  • Never offer video in MP4 by default: prefer Webm, which supports more modern codecs and is therefore lighter. However, MP4 should always be offered as a fallback, thanks to a <video> tag associated with the appropriate sources.
  • Does your site embed videos hosted on your own server? Always provide a preview image using the “poster” attribute of the <video> tag. In addition to being shown on mobile by default, this image will be the LCP element if the video is in the initial viewport.

Webfonts

  • Beware of fonts! Use one family if possible, possibly 2, but no more. Limit the number of variations: Regular (400) and Bold (700) versions are often sufficient. Many themes and Page Builders load all the variations of styles and weights, and thus weigh down performance.
  • Fonts should always be loaded locally. Google Fonts and Adobe Typekit are convenient, but they are pitfalls in terms of performance. The negative effect is twofold: extended download time due to network latencies and inability to preload the fonts.
  • If you’re using a typeface available as a Variable Font, you’ll want to use this format rather than the classic variations of individual weights. You’ll only need to download and preload a single Woff2 file, while having access to more font weights.
  • If you self-host variable font files, congratulations. However, make sure they only include what’s necessary: they often contain unused “axis”: weight (Regular, Bold…), strand (more or less italic) or width (more or less condensed). Their weight will decrease.
  • 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). Choose lightweight webfonts such as Poppins, Jost, Albert Sans or Oswald, all around 10 kB in Woff2 version.
  • Locally hosted text fonts should be preloaded via a <link rel="preload"> tag to ensure faster text rendering and reduce CLS. Please note, however, that 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 the LCP. For English and/or French sites, the “Basic Latin” and “Latin-1 Supplement” subsets are generally sufficient to display all texts.
  • When you declare a font-stack via the CSS font-family property, only the first font should be of custom type; subsequent fonts should be system fonts. Declaring multiple custom fonts can lead to the downloading of multiple unused files, negatively impacting LCP and Speed Index.
  • Many third-party tools and front-end extensions (CMP, VOC, marketing popups…) use their own font sets. As soon as possible, modify their behavior so that they inherit your pages’ default font (“inherit” value).

UX/UI

  • Limit the number of animations: they are generally as costly in terms of performance as they are disruptive in terms of UX. If you must integrate them, they should ideally be based on the CSS transform and opacity properties. Avoid JavaScript frameworks such as animate.js, Lottie…
  • Full-page “spinner” or “loading bar” loaders are strongly discouraged. They harm the User Experience by masking all content for several seconds. In terms of metrics, this translates into a significant increase in LCP and Speed Index.
  • Limit the use of sliders and other carousels. They make part of the content invisible to visitors, while imposing a less natural navigation interface than scrolling. What’s more, they often rely on large volumes of JavaScript, significantly increasing TBT and INP.
  • If you use sliders, carousels or automatic horizontal scrolling zones, be sure to integrate content of the same height. Many plugins adapt the height of the zone to its visible content, so that the entire page is constantly subject to Layout Shifts.
  • Don’t modify browsers’ native scrolling behavior with JavaScript. This is justified for fullpage sites that function like slideshows, but 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, opt for JavaScript with base64 encoding. This way, text remains selectable and clickable by (real) visitors.
  • Is a text “too long” to be displayed on your mobile site? Never hide it via CSS (with text-overflow: ellipsis, for example). In a mobile-first approach, all text must be legible, whatever the resolution of the viewing terminal.
  • If a page template has a limited width, never use an option to extend zones horizontally outside this width via JavaScript: this is very costly in terms of CPU resources and generates Layout Shifts. Prefer full-width native templates.
  • If your site offers push notifications, never activate a subscription invitation dialog on first display: this behavior is intrusive in terms of User Experience and generates Blocking Time. Instead, place a button on the page, ideally after the content.
  • It’s not recommended to provide a specific mobile version of your site, including AMP. Native browser APIs and tools provide everything you need for 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 results pages remains unknown: there are no studies to prove its effects on SEO. Optimization does, however, improve user experience, and therefore conversions.
  • Contrary to popular belief, obfuscating links to optimize a site’s crawl is easy to set up with just a dozen lines of JS. There’s nothing complex about it, and it can have very beneficial effects for both SEO and crawl-budget control.
  • Google Search Console offers a detailed overview of how Googlebot crawls sites. This little-known feature can be accessed via the menu Settings > Crawl statistics > Open report. It shows average response times and daily crawl volume, providing insight into indexing issues.
  • Some tools in the Alphabet ecosystem, such as Google Discover, are particularly sensitive to site web performance. To integrate the tool and remain visible over time, it is essential to pass the Core Web Vitals at site level (origin).

WordPress

  • On WordPress, revisions and auto drafts of publications can quickly swell the size of the database. It’s important to regularly clean up these elements to reduce the execution time of SQL queries. This improves TTFB.
  • Gutenberg is good. WordPress’ native editor has evolved enormously over the last 2 years, and can now be used as an alternative to historical page builders. Combined with block libraries (GenerateBlocks, Ultimate Blocks…), it allows you to create any complex layout with a minimum amount of DOM and CSS.
  • If you’re not using the Gutenberg block editor as a Page Builder, disable its style sheets on your site. This is not automatic, and may unnecessarily increase the volume of CSS, thus contributing to higher FCP and LCP.
  • As a WordPress site evolves, the theme and extensions may change. When deactivated, these usually leave traces in the wp_options table. Deleting them manually reduces the size of this critical SQL table, improving TTFB.
  • By default, WordPress runs tasks in the background on page opening, which can lead to load surges and slowdowns. Instead, run crons on the server side every 2 to 5 minutes. This will improve the TTFB of dynamic pages.

Themes

  • If you want a fast WordPress, don’t buy a big, popular theme from Themeforest. The right logic is to start with something lightweight and adapt it to your needs via plugins. The opposite approach (disabling lots of features) often comes at a high price in terms of CSS and JS loads.
  • Beware of certain “responsive” themes whose header is in fact based on the presence of 2 distinct headers: one for mobile, the other for desktop. All the header links, and in particular the main menu, are present twice, which makes the DOM heavier and is not optimal for SEO.
  • When creating or redesigning a WordPress site, always use a child theme. This will enable you to integrate modifications, for web performance among other things, while continuing to benefit from updates to the base theme.

Plugins

  • There’s no such thing as a miracle plugin to improve WordPress performance. Even the excellent WP Rocket needs to be configured and its options finely tested to maximize its impact on Core Web Vitals. Configuration is different for every site.
  • On WordPress, caching plugins drastically improve FPC and LCP for visitors and robots. They also relieve the server of processor and memory resources, reducing response times for logged-in users.
  • When a WordPress plugin requires a database update (WooCommerce, Yoast SEO…), do it quickly. Otherwise, SQL queries won’t be optimized, which can slow down loading times in administration and for non-cached pages.
  • When installing a WordPress extension, always check the weight of CSS and JS resources loaded on the public site. Extensions 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 take things further? Don’t hesitate to contact Agence Web Performance – it’s what we do!

React to this article

You would like us to accompany you on your project?
Contact us now
You're interested in being accompanied by Agence Web Performance?