Tips For Building Faster Websites with Efficient CSS Optimisation
DrPrime01
Posted on August 14, 2023
Cascading Style Sheet, or CSS, is a language that adds appealing visual designs to HTML elements on the web. In small web applications, CSS doesn't pose any problems. However, performance and load time issues can arise as the application becomes more complex. As the size of web applications increases, the number of CSS files and the lines of CSS codes in a file also increase. This can result in poor user experience and coding experience for the user and developer, respectively, both during and after production. This article provides eight tips for optimising CSS in large applications, resulting in faster page load speeds and other benefits.
Minifying CSS Files
As a web developer, you must write readable, understandable, and well-commented code. Nevertheless, writing CSS in that style results in significant whitespaces in your CSS files that are irrelevant to the web browser engine decoding the code, even though the tip above makes your code stand out as a developer. These CSS codes are clear to developers but are clustered with many whitespaces:
h1 {
color: red;
font-size: 36px;
font-weight: 700;
}
However, the browser engine only needs the code below to apply the same styles appropriately to the selected HTML element:
h1{color: red; font: 36px 700;}
Whitespaces significantly increase the size of CSS files, which results in slower page loads and poorer online performance.
Importing fonts and icons into CSS files is another popular web development approach that results in larger CSS files. Web applications such as Google Fonts that provide these fonts to designers and developers outline two methods for incorporating these assets into web projects, linking them in an HTML file or importing them into CSS files. The latter approach, viewed as bad practice, is frequently used by developers. Rather than importing these assets into the CSS file, you can link them in the head tag of your HTML file and still have them function properly without causing any problems to the HTML file and simultaneously reduce the space used in the CSS file.
Minimising and compressing CSS files can improve page load times and optimise a website. Some best practices for reducing CSS file includes:
- Always use CSS shorthand property notations
- Remove whitespaces, line breaks, and comments before deployment
- Use compression tools such as Gzip or minifying tools such as CSSNano, CleanCSS, and UglifyCSS to reduce your CSS file sizes.
It is important to note that while writing CSS codes in a browser engine-appreciable pattern, balancing it with code maintainability is crucial. The minified versions can be challenging to read and understand, so keeping a readable version of the code for development purposes and only minifying the CSS file when it's production-ready is advisable.
Using CSS Sprites For Image Optimisation
A web application with multiple image files and folders can take time to load, making multiple server requests concurrently. To reduce load time and HTTP requests, CSS sprites were introduced. CSS sprites are a web technique for combining many images into a single large image. To use an image from the sprite, you use the background-position
to specify the dimensions of the image in the sprite.
<div class="icon sprite"></div>
.sprite {
display: inline-block;
background: url("sprite.png") no-repeat;
width: 32px;
height: 32px;
}
The CSS background-position
property locates the x and y coordinates of the image you want to use from the sprite and only makes it visible.
CSS image sprites are ideal for icons that change on hover, large and small images. However, if you're on an HTTP/2 protocol, making multiple HTTP requests for small images is better because using image sprites may not be bandwidth-friendly.
CSS image sprites can be created using available online tools. These online sprite programmes combine several images into a single one. Some could even specify the coordinates of each image in the sprite. They include spritegen, codeshack.io, spritecow, cssspritetool, and others.
Due to their limitation of HTTP requests and bandwidth usage, CSS sprites effectively improve online performance. However, they need careful supervision and preparation, as any HTML element that references a sprite image may need to update its CSS if it is changed.
Implementing Lazyloading For Images And Videos
Among web developers, lazyloading is a rapidly expanding optimisation approach. It makes HTML elements like iframes, images, and videos take longer to load. Each component is represented as a low bandwidth image until all or part of the element is displayed in the observer's device viewport. Since the user has not yet reviewed the element on the webpage, lazyloading speeds up page loads and reduces the amount of data transferred upfront. It saves user network data by only loading resources when necessary.
There are many methods to apply lazy loading to images and videos on a website, but the article will explain two in detail, listing others toward the end. The first approach to lazyloading is setting the loading
attribute to elements you want to lazy load with a value of lazy
.
<img src="bigCow.jpg" alt="big cow" loading="lazy" />
However, because not all web browsers support the loading
attribute yet, a better method which utilises the Intersection Observer API was introduced. The Intersection Observer API method uses JavaScript to monitor the elements you apply it to and check if they are within the user's device viewport. Once the elements are in the viewport, the API triggers a callback function that sets the src with the image URL from the data-srcset where it was initially stored. Then, it stops detaches from the element to stop observing it to prevent unnecessary callbacks.
Here is a sample code illustrating lazyloading for images and videos using the Intersection Observer API:
<!DOCTYPE html>
<html>
<head>
<title>Lazy Loading Example</title>
<style>
/* Set the dimensions of the image and video elements */
img, video {
width: 100%;
height: auto;
}
</style>
</head>
<body>
<!-- Create an image element with a placeholder image -->
<img src="placeholder.jpg" data-src="image.jpg">
<!-- Create a video element with a placeholder image -->
<div>
<video poster="placeholder.jpg" data-src="video.mp4" controls></video>
</div>
<script>
const options = {
root: null, // use the viewport as the root element
rootMargin: '0px',
threshold: 0.1 // trigger the loading when 10% of the element is visible
};
const handleIntersection = (entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// load the image or video by setting the "src" attribute from the "data-src" attribute
if (entry.target.tagName === 'IMG') {
entry.target.src = entry.target.dataset.src;
} else if (entry.target.tagName === 'VIDEO') {
entry.target.src = entry.target.dataset.src;
}
// stop observing the element once it has been loaded
observer.unobserve(entry.target);
}
});
};
const observer = new IntersectionObserver(handleIntersection, options);
// observe all the image and video elements with the "data-src" attribute
document.querySelectorAll('img[data-src], video[data-src]').forEach(element => {
observer.observe(element);
});
</script>
</body>
</html>
Developers also employ alternative methods for lazy loadings, such as the scroll event listener, besides the Intersection Observer API and the loading property. Unlike the Intersection Observer API, which only monitors the elements targeted for lazy loading, developers attach a scroll event listener to every element on the page. Once the element marked for lazy loading is within the visibility range of the user, a function is invoked to switch the image or video URL with the attribute previously holding it, just like with the Intersection Observer API. This approach is costly for a web project. As the developer seeks to optimise page load by integrating lazy loading to some elements on the webpage, the developer slows down the page's performance due to multiple firing of an event as the function meets each element.
Moreover, packages for JavaScript that deal with lazy loading exist. For instance, the LazyLoad library uses the Intersection Observer API, a lightweight JavaScript library. It supports many lazy loading features, such as preloading, responsive image loading, and custom loading animations. Additional lazyloading libraries include Yall.js, Lozad.js, LazyLoad XT for jQuery, and many more.
Using CSS Preprocessors And Frameworks
Experienced web developers have collaborated over the years to create preprocessors and frameworks that aid in writing clean CSS with fewer lines of code. You may create reusable, composable, and maintainable CSS scripts using preprocessors like SASS and LESS's various utilities and helper functions. Developers no longer need to create CSS files to write CSS thanks to frameworks like Bootstrap, TailwindCSS, ChakraUI, etc., because they can pass it as an attribute to HTML elements. In addition to offering built-in capabilities for responsive designs, these preprocessors and frameworks employ best practices for effective CSS delivery, such as minification, compression, and concatenating CSS files. By addressing the requirement for custom media queries, these built-in features lessen the amount of CSS and JS needed to manage various screen sizes.
Moreover, CSS frameworks, in particular, provide for speedier loading times by removing the need for CSS files in large projects while only using a tiny amount of space in smaller ones. The fact that some of these frameworks, like Bootstrap, have icons in their package means that installing or linking a separate package for icons is unnecessary, reducing HTTP requests. Lastly, after deployment, frameworks like TailwindCSS minify your project, deleting any CSS code that was never utilised in the project and shrinking the file size.
It is important to note that while these frameworks could help build responsive websites, they could reduce performance if they're only used in a small section of the website but fully installed in the project via a package manager. To be on the safe side, it's advisable to link them in the HTML head
tag for small projects.
Using Media Queries To Target Different Device Dimensions
If you're a web developer with no tolerance for CSS preprocessors and frameworks, you may decide to write your custom media queries. If you're curious about how media queries optimise page loads, they define styles specific to a set of devices with predetermined dimensions. The browser engine uses the styles in the main CSS and the ones in the media queries that fit the device dimensions, leaving out other styles without loading them, to describe the styles of a device instead of using the entire CSS file. As the browser neglects these styles, loading the website on the device is faster than loading all the styles in the CSS file.
Adopting Modern CSS Techniques Such As Flexbox and Grid
More CSS techniques are developed as the web becomes more complex to make life easier for developers. Flexbox and grids are two recently added CSS layout methods. Unlike other CSS layout properties like floats and positioning, both approaches are effective space managers and outstanding layout techniques. With the 12-column system, Grid and Flexbox are ideal for effectively using the available space on a page while requiring fewer extra items or intricate positioning in shorter lines of code. Both methods are essential for developing responsive websites because they reduce the CSS needed to accommodate various screen sizes.
Reducing HTTP Requests
Before showing up on the user's screen, a web application sends multiple calls to external servers that host images, fonts, icons, stylesheets, packages, and other web assets. These queries have negatively affected a website's page load time. Some valuable tips to minimise HTTP requests are combining multiple CSS and JavaScript files, using a Content Delivery Network, CDN, distributing your website's assets across a global server network, enabling browser caching and linking all your icons to your projects from the same server. Moreover, you could use a framework that includes the resources your project needs. This will improve the efficiency of your website and lower the number of requests it makes.
Avoid Inline CSS
Some developers have developed the habit of coding CSS using the inline style method to optimise websites for quick page loads or out of ignorance. Although this technique successfully lowers the load time for CSS pages, it dramatically expands the size of the HTML file, which raises the load time for that page. Also, since inline styles require the CSS to be parsed and rendered each time an element with them is loaded instead of merely loading it once from an external stylesheet and caching it, they may cause page loads to lag. Lastly, inline styles may be difficult to manage and update because they are scattered throughout the HTML code. Also, writing inline styles is poor coding practice for web developers. Inline styles are meant for specific styles on rare occasions and should not be used regularly.
Conclusion
Optimising CSS files can benefit websites and web applications by increasing page performance and improving page load times. This leads to a better user experience, higher website ratings, and increased patronage for e-commerce applications. Additionally, optimising CSS can help boost your web application's search engine ranking since browser engines can quickly and easily load your CSS and apply styles to HTML due to a small file size. Finally, knowing that your projects have good performance ratings can boost your confidence as a web developer.
Heyo! I'm Dr Prime a Software Developer who loves writing about different frontend technologies. Reach out to me on Twitter to talk.
Cover image by Chris Liverani on Unsplash
Posted on August 14, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.