Making your website more sustainable

tagged with Backend Content Developer Frontend Media SEO Sustainability

After seeing a fantastic talk from Andy Eva-Dale about "10 Do’s and Don’ts of Sustainable Systems" at Codegarden, I got inspired to be more aware of the impact we make as developers on the carbon footprint of our projects. Since I work on a lot of existing projects with smaller budgets, it sometimes felt like a challenge.

According to a report by The Shift Project, the digital sector's energy consumption is growing by 9% per year. The carbon footprint of our digital devices, the internet, and the systems supporting them account for about 3.7% of global greenhouse emissions (in 2019). That's comparable to the airline industry's carbon footprint. It's expected that by 2025, the ICT ecosystem, which includes personal digital devices, data centers, and networks, could account for 20% of the world's electricity consumption and up to 5.5% of the world's carbon emissions.

In this article we explore how we can reduce this impact with some 'small' changes. The small changes we can make to an existing project, that seemingly have a small impact, but a lot of smalls hopefully make a big impression. Let's delve into how we can make our corner of the internet greener and more sustainable.

Picture it all

There are several ways to make an existing website more sustainable. One thing that can have a big impact on your websites are images. There are several best practices to improve performance, and thus the footprint. Let's see what we can do by changing some 'small things'.

Reducing image size

A good way to handle image sizes is by using the <picture> element. Using this HTML element you can set different image sizes for different media queries. The image is only loaded when a media query is matched. So no unnecessary images will be loaded. 

Optimize Images with Umbraco's Image Cropper

Using Umbraco's Image Cropper allows you to serve appropriately sized images for the different src-set for the picture element. So make sure you use the correct crops / parameters when using the Image Cropper. With the Image Cropper you can also optimize your images to modern formats like webp to improve performance.


<picture data-v-60ac7c92="" data-image-source="" class="bw-card__picture">
    <source
        srcset="
            /media/bhqptmy0/example.png?anchor=center&mode=crop&width=420&height=270&format=webp
        "
        media="(max-width: 420px)"
    />
    <source
        srcset="
            /media/bhqptmy0/example.png?anchor=center&mode=crop&width=400&height=250&format=webp
        "
        media="(max-width: 840px)"
    />
    <img src="/media/bhqptmy0/example.png?anchor=center&mode=crop&width=400&height=250&format=webp
    loading="lazy" alt="" class="lazyload" />
</picture>

<picture> element

Take it easy, make it lazy

Another way to save resources is using lazy loading. Lazy loading is a design pattern commonly used to defer initialization of an item until the point at which it is needed. It can improve performance by delaying the loading of resources until they are actually necessary. While initially this technique was widely used for images, it has evolved to cover a wider range of content types including scripts, videos, and even entire sections of a webpage.

In the past, implementing lazy loading required JavaScript, but these days it can be dealt with by using native lazy loading, a feature now supported by most modern browsers. You can lazy load several different types of resources. 

Images and iframes

Webpages can contain a lot of images, which can cause a sizeable data-usage. And since most images are non-critical (eg. off-screen), it's not needed to load them all on pageload.

By using the loading attribute on the <img> or <iframe> element we can tell the browser to wait with the loading of the images. When the user scrolls near them, that is the time to load them.

The loading attribute on an <img> or <iframe> element will let the browser know to defer loading of the images/iframes until needed.


<img
    src="/media/bhqptmy0/example.png?anchor=center&mode=crop&width=400&height=250&format=webp"
    alt="..."
    loading="lazy"
/>

<iframe src="/landingpage/media-player.html" title="..." loading="lazy"></iframe>

Lazy loading image

Scripts

Deferring loading of JavaScript modules is another optimization technique that can improve the performance of your web pages. In the context of JavaScript modules, the defer attribute is used. When defer is present, it specifies that the script is executed when the page has finished parsing. 

Any script tag with type="module" is treated as a JavaScript module and is deferred by default. Most modern browsers have started to support module functionality natively, it prevents it from blocking the document parsing and delays its execution until the HTML document has been fully parsed.


<script src="script.js" defer></script>

<script type="module" src="main.js"></script>

/* you can also use it directly inline in HTML */
<script type="module">
    /* JavaScript module code here */
</script>

Defer scripts

CSS

CSS is treated by browsers as a blocking resource. By default the browser won't render any content until the CSS Object Model is constructed. So by specifying when the CSS is needed we can prevent loading unused stylesheets. To prevent the CSS from being blocking we can use media queries.


<link href="style.css" rel="stylesheet" media="all" />
<link href="print.css" rel="stylesheet" media="print" />
<link href="style-landscape.css" rel="stylesheet" media="(orientation:landscape)" />

CSS media-query

Fonts

Font requests are delayed by default, until the construction of the render tree is completed. This can lead to a delay in the rendering of text. However, this default behavior can be overridden. By using <link rel="preload">, the CSS font-display property, or the Font Loading API.

For instance, to preload a font using the <link rel="preload"> tag, you can add the following code to the head of you HTML


<link rel="preload" href="/fonts/my-font.woff2" as="font" type="font/woff2" crossorigin />

Font preload

Elementary, my dear DOM

In the quest for a sustainable, efficient, and high-performance web, native HTML elements play an important role. These elements, deeply embedded in HTML, help us reduce the DOM's size, lessen server requests, and in turn, reduce the energy consumption of our websites. 

Using Native HTML Elements

Often, we overlook the power of native HTML elements, instead opting for complex JavaScript libraries or CSS frameworks. However, these native elements come with built-in functionality that could save us from adding unnecessary weight to our web pages.

Consider the <details> and <summary> HTML elements. These elements allow us to create an interactive accordion without the need for additional JavaScript or CSS.


<details>
  <summary>Click to expand</summary>
  <p>This is additional hidden content that will be revealed when the summary is clicked.</p>
</details>

<detail> <summary> elements

With just a few lines of code, we've created an interactive, accessible, and lightweight accordion. No extra HTTP requests, no bloated DOM, just simple and efficient HTML.

Avoiding Excessive DOM Size

By using native HTML elements, we're keeping our DOM lean and clean. A smaller DOM means faster parsing and less memory usage. This speed increase leads to a better user experience, but also reduces the energy needed to render and interact with the site.

An example can be to use the <nav> element. The <nav> element is used to define a block of navigation links. It's semantic, accessible and can significantly simplify our markup compared to creating custom navigation structures. Navigation menus often were constructed with a combination of div tags, span tags, additional classes and JavaScript for interactivity. This approach not only adds to the DOM's weight but also increases the complexity of the website.

Using the <nav> element, we can create a simple, semantic navigation menu:


<nav>
    <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/about">About</a></li>
        <li><a href="/contact">Contact</a></li>
    </ul>
</nav>

<nav> element

This approach is simple, efficient and accessible. It reduces the number of elements in the DOM, which makes the page lighter and faster, and thus more sustainable.

Reducing Server Requests

Using native HTML elements can also reduce the amount of server request. As seen in the examples above we no longer need (a lot of) JavaScript. Each of these requests consumes energy, and by minimizing these requests we lower our carbon footprint. 

Another example, instead of using a JavaScript library to create a modal, we could utilize the <dialog> HTML element.


<dialog id="myDialog">
    <p>This is a dialog window</p>
    <button id="closeButton">Close</button>
</dialog>

<script>
    const dialog = document.getElementById("myDialog");
    const closeButton = document.getElementById("closeButton");

    closeButton.addEventListener("click", () => {
        dialog.close();
    });
</script>

<dialog> element

By embracing native HTML elements, we're not just being efficient coders; we're being responsible stewards of our digital world. 

Lean and mean; sustainable design

The last tip we will explore is a more simple and efficient design to improve the sustainability. We can achieve this by looking into a few options.

Low footprint mode

Animations and complex visuals can have a hefty influence on the performance. By offering the visitor to switch to a low footprint mode, to reduce animations and complex visuals or even switch to dark theme can have a great effect. Dark theme can save energy particularly on OLED displays.

An added bonus to reducing the energy consumption as less data needs to be processed and rendered, the accessibility will also increase for users with slower internet speeds or older devices.

Limit usage of colors, fonts and script

As said before, reducing the amount of data needed to be transferred over the network, will help make your site more sustainable. By limiting the number of fonts and scripts needed can have a significant impact. Reducing colors and fonts will also lower the computational resources needed to render the pages. So always make a well thought out choice when using colors and fonts in your design. And don't forget to optimize and minify your scripts and stylesheets to ensure that they take as little bandwidth as possible.

Reduce navigation flows and page counts

Apart from resource like fonts and script, you can also limit the amount of pages and navigation flows needed for your website. The bigger the website, the more requests the servers need to process. Use analytics to identify pages that are barely visited; these can be candidates for elimination or merging into other pages. 

The same goes for navigation flows. The more steps a visitor has to take, the more pages need to be rendered. By streamlining your navigation flows a user can reach their destination quicker. Not only is this a better experience for the user, but it will save resources and therefore energy.

The final thoughts towards a greener web

The digital world is not as intangible as it seems; it has a real impact on our environment, and it's a responsibility we as developers share. However, the road towards a more sustainable web does not always require large-scale changes. Often, it's the small, thoughtful decisions we make in our projects that can make a significant difference.

Optimizing images, adopting lazy loading, harnessing the power of native HTML elements, and embracing lean, efficient design principles - these are small but effective steps that help reduce our carbon footprint. They not only make our websites faster and more accessible but also contribute to a greener, more sustainable web.

In our quest for sustainability, it's important to remember that every byte saved, every server request reduced, and every renewable energy source used for powering our servers matter. All these efforts, however small they seem, add up to a big difference.

So as we continue to build and innovate in the digital sphere, let's strive to do so with an eye on sustainability. With every line of code we write, let's aim to make our corner of the internet a little greener and more sustainable. After all, the future of our planet depends on the choices we make today.