The performance benefits of progressive enhancement
Progressive enhancement focuses on providing a core ‘device-agnostic’ experience for all users. By starting with a solid foundation that works everywhere – HTML – we ensure our applications are usable for as wide an audience as possible. This encourages us to pare down our applications to their essential features, be it reading the news or sending and receiving messages. Once we’re confident this core experience is functional for everyone, we can start to layer on styling and interaction to provide a better experience for devices which support it.
Although progressive enhancement is a popular technique for content-driven sites, it’s often ignored on modern web apps since it de-prioritises more ‘dynamic’ features that likely wouldn’t work on older devices. However, while the main advantages of progressive enhancement are traditionally seen as reliability and compatibility, there are also many performance benefits that come from adopting a PE-friendly mindset that make it more than worth considering for your next application.
Faster time-to-interactive
Many modern apps utilise client-side frameworks (such as Angular and React) to provide their ‘core’ experience. These often require downloading the full application to the device before becoming usable, resulting in a long delay for users on slower connections.
While client-side rendering can be great for repeat visitors or dynamic features, serving simple HTML is still the fastest way to get your application in the hands of your users. There’s no waiting for large files to download and execute — you get instantly-usable HTML without any dependencies. By starting with simple HTML/CSS, you let your users interact with your app as soon as possible.
Non-blocking font loading
Web fonts have become extremely popular in recent years, but the best way of loading them is still a contentious issue. Serving them to everyone immediately can lead to the infamous ‘flash of invisible text’ while the browser downloads the font, which on some browsers (such as iOS Safari) leads to invisible content for as long as the font takes to download.
Instead, we can use an already available ‘system’ font (such as Arial) and then only swap it out when we’re sure our custom font is ready and supported. This means the content will always be visible, regardless of the device or network capabilities. This may be distracting on the first visit, as the font will visibly change after a few seconds, but is preferable to hiding content.
This is the basic principle of progressive enhancement — starting with a reliable and fast experience, then ‘layering’ on enhancements when we can.
Conditional loading
Some of the most impressive features on the web mimic native apps, such as real-time chat and ‘WYSIWYG’ editors. Unfortunately, these can often be very large and complex files, usually JavaScript, that result in slower sites and larger downloads.
Taking a PE-friendly approach means ensuring the core functions behind these actions (e.g. typing content, sending a form) don’t rely on external files or JavaScript. Then, in the background, we can ‘progressively’ load the enhanced versions of these features and swap them out when ready. Better still, we can load these assets only when relevant and not (for instance) if there is no WYSIWYG editor on the page.
A simple text area, becoming a WYSIWYG editor when clicked
This means that users don’t need to wait for core functionality within your application. If they’re on a slow device or network connection they can still use a simple version of a feature without waiting.
Being selective
We can take our conditional loading of ‘enhanced’ features one step further by being even more selective about who receives them.
Many older browsers have poor support for modern features, often necessitating the addition of large helper libraries (known as ‘polyfills’) to fill in the gaps. This usually means serving visitors larger files than they need, just to cater to the lowest common denominator.
Instead, we can employ a technique the BBC has referred to as ‘cutting the mustard’. We can run a simple test when our website loads that will check for the existence of ‘modern’ features and then load the appropriate file based on the result. Modern browsers get the modern code, older browsers get the larger backwards-compatible code, and very old browsers don’t get any of the enhancements.
By checking up front, we can ensure users only download and run appropriate code. Even better, since the basic functionality is usable without the enhancements, users can still interact with the page while this is going on in the background.
One more thing
Of course, there are a bunch of other benefits of a progressively-enhanced application. Your app will be far more error tolerant — if something goes wrong with a fancy new feature, there’s a good chance your users will still be able to complete their task with the ‘basic’ version.
Progressive enhancement also helps save time when it comes to cross-device testing since you can be safe in the knowledge that your app will only layer on features when they’re supported. Practically everyone is guaranteed a functional experience, regardless of browser or device.
Although everyone appreciates better performance and resiliency, progressive enhancement remains a contentious issue. Some developers feel the approach limits their ability to provide dynamic experiences, especially those that mimic native applications. Many modern tools and frameworks, such as React and Angular, are written entirely in JavaScript. While these provide a fast, ‘app-like’ experience, they also won’t (usually) work for customers who have JavaScript disabled, or if there is a problem with parsing the script. Others consider the future of progressive enhancement to be in network resiliency, ensuring that pages work ‘offline’ thanks to new technology such as PWAs based on service workers.
Like all techniques and methodologies, progressive enhancement doesn’t need to be followed dogmatically and is more a guideline than a rule. However, it’s a valuable mindset that can help improve your application for all users, not just those on slower or less capable devices.