Skip to content

Performance

This is an overview of all the steps we take to improve performance in the site.

There will be links to the sections with more in-depth information in case it’s needed, this is meant to be only a do’s and dont’s that summarises our work philosophy.

We try to keep our initial bundle size to a minimum. For that, we import only essential libraries on page load, and those can be:

  • The ones we need for the project to function
  • The ones that are in the viewport when the user opens the page

The rest of them get imported on user’s first scroll.

We also make sure to destroy and wipe all of our instances whenever the user changes from one page to another, and we use the “curtain” to hide moments where some libraries are still loading and the layout of the page changes while the user is looking at it.

All of this process is handled by our framework, which checks if the element we need the library for is in the viewport or not and loads the libraries accordingly.

Ideally, when planning a page, we would want for resources that make use of libraries to be outside of the initial viewport of the user, so all of those heavier assets can be imported on scroll after the initial page load.

  • ✅ Use handlers to import libraries
  • ✅ Use destroy methods in all your classes
  • ✅ Use libraries outside of the initial viewport of the user when possible
  • ❌ Do not import a library directly in a file
  • ❌ Do not use a class that does not contain a destroy method
  • ❌ Do not use heavy libraries in a hero or the most upper module of the page

We use Boostify to make sure our libraries are imported when we want. We use this tool to load our libraries on user scroll as mentioned above.

We also use all of our scripts as text/boostify to make them load with a bit of delay from the page load and we make use of the onload method to inject code whenever our boostify scripts have finished loading.

We do not load almost any videos in the page, we use modals paired with Boostify to load the videos when the user opens the modal instead of when the page is loaded, to prevent big streams of data at page load.

video load

Example:

src/scripts/handler/modal/Handler.js
case "video":
u_addClass(modalEl, "c--modal-a--second");
if (contentData.videoType == "url") {
const embedUrl = UrlToEmbed(contentData.videoUrl);
modalContent.innerHTML = `
<div class="c--media-a c--media-a--second">
</div>
`;
this.boostify.videoEmbed({
url: embedUrl,
autoplay: true,
appendTo: modalEl.querySelector(".c--media-a"),
});
} else {
this.boostify.videoPlayer({
url: {
mp4: contentData.videoFile,
},
attributes: {
class: "c--media-a",
loop: false,
muted: false,
controls: true,
autoplay: true,
},
appendTo: modalContent,
});
}
break;
  • ✅ Load videos inside modals
  • ✅ Load videos using Boostify instead of embedding directly
  • ❌ Load videos directly in the page (unless it’s strictly necessary)

To introduce new Marketo forms, make use of the handler that is already present in the site. Do not introduce the full script from scratch, as we use the handler to control when the script is loaded and add some data attributes that make it possible for us to destroy and clean up remnants left by it when closing a modal or changing a page.


This checklist covers all the performance and best practices we implement across our frontend projects. All items marked as ✅ are completed, and this serves as both documentation and verification of our standards.

Performance ItemStatusNotes
Charset DeclarationUTF-8 is declared correctly in Layout.astro to ensure proper character encoding across all pages
H1 Tag UsageAll pages have a unique H1 that describes the page content (not the website title) for SEO and accessibility
Terra HTML ReferenceAll components follow Terra HTML reference standards for consistent markup structure
Image Alt TextAll images include descriptive alt text using the astro-core package for improved accessibility and SEO
Clean CodeUnnecessary comments and code are removed before production deployment to reduce file size

Declaring UTF-8 encoding ensures that all characters (including special characters, emojis, and international text) render correctly across all browsers and devices. This prevents character corruption issues and improves compatibility.

Each page should have a unique H1 tag that:

  • Helps search engines understand the main topic of the page
  • Improves accessibility for screen reader users
  • Provides clear hierarchical structure to the content
  • Should describe the page content, not repeat the site name

Performance ItemStatusNotes
Non-blocking CSSCSS files are loaded in a non-blocking manner to prevent DOM rendering delays
No Inline StylesAll styles are externalized to CSS files for better caching and maintainability
CSS ValidationCSS is validated using W3C CSS Validator to catch errors
BEM MethodologyMaximum 3-4 nesting levels within a block to maintain readability and specificity control

Non-blocking CSS prevents the browser from delaying page rendering while CSS files are being downloaded. We achieve this by:

<!-- CSS is loaded without blocking render -->
<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'">

This technique allows the browser to:

  • Parse HTML immediately
  • Display content faster
  • Load CSS asynchronously
  • Apply styles once available

We enforce a maximum of 3-4 nesting levels in our BEM structure to:

  • Prevent specificity wars
  • Improve CSS maintainability
  • Reduce selector complexity
  • Make styles easier to override when needed

Example of proper nesting:

.block {
&__element {
&--modifier {
// Maximum 3 levels deep
}
}
}

Performance ItemStatusNotes
Keyboard NavigationAll interactive elements are reachable and usable via keyboard in a predictable order

Keyboard navigation is tested to ensure:

  • All interactive elements can be reached using Tab key
  • Focus indicators are visible and clear
  • Tab order follows logical reading flow
  • All functionality is accessible without a mouse
  • Escape key closes modals/dropdowns
  • Enter/Space activates buttons and links

This improves:

  • Accessibility for users with motor disabilities
  • Power user efficiency
  • Screen reader compatibility
  • Overall usability standards
  • ✅ Declare UTF-8 charset in all HTML documents
  • ✅ Use non-blocking CSS loading techniques
  • ✅ Remove all inline styles and move to external CSS files
  • ✅ Validate CSS before production deployment
  • ✅ Limit BEM nesting to maximum 3-4 levels
  • ✅ Use async/await for all asynchronous operations
  • ✅ Implement dynamic imports with Boostify
  • ✅ Provide meaningful alt text for all images
  • ✅ Use unique H1 tags on every page
  • ✅ Test keyboard navigation thoroughly
  • ❌ Don’t use inline styles (use external CSS files)
  • ❌ Don’t nest BEM selectors more than 4 levels deep
  • ❌ Don’t forget to validate CSS before deploying
  • ❌ Don’t skip alt text on images
  • ❌ Don’t use the same H1 across multiple pages
  • ❌ Don’t leave console errors or unused code in production
  • ❌ Don’t block rendering with synchronous JavaScript
  • ❌ Don’t make interactive elements inaccessible via keyboard