Critical Rendering Path (CRP) and its Optimization, the PRPL pattern and Performance Budget.
Web performance is all about making web sites fast, including making slow processes seem fast. Good or bad website performance correlates powerfully to user experience, as well as the overall effectiveness of most sites. Websites and applications need to be fast and efficient for all users no matter what conditions the users are under. To make that happen we use performance optimizations. The MDN web docs breaks down performance optimization into four major areas.
Reducing overall load time
- Compressing and minifying all files.
- Reducing the number of file and other HTTP requests sent back and forth between the server and the user agent.
- Employing advanced loading and caching techniques and conditionally serving the user with only what they need when they actually need it.
Making the site usable as soon as possible
- This is done by loading critical components first to give the user initial content and functionality and then deferring less important features for later using lazy loading to request and display content only when the user gets to or interacts with it. And by pre-loading features, the user is likely to interact with next.
Smoothness and Interactivity
- Improving the perceived performance of a site through skeleton interfaces, visual loaders and clear indication that something is happening and things are going to work soon.
- Tools and metrics to monitor performance and validate up to station efforts. The thing to keep in mind here is that not every performance optimization will fit your solution and needs.
- Browser tools measuring performance include Lighthouse (Chrome), Network monitor, Performance monitor. There are also hosted third-party tools like PageSpeed Insights (Google), WebPage Test, GTMetrics(actually Lighthouse) which help measure performance.
- Key indicators that these tools use ro describe the performance are:
- First paint- The time it takes before the user sees changes happening in the browser. Largest Contentful Paint (LCP)- The time it takes before the user sees content, so text images, something else in the browser.
- First Meaningful Paint (FMP)- The time it takes before the user sees content that is actually meaningful. So when above the full content and web fonts are loaded and the user can derive meaning from what they are seeing.
- Time To Interactive- The time it takes before the content has finished loading and the UI can be interacted with so the user can actually click on buttons, fill forms or do whatever else is going to happen on the site.
The longer it takes for a site to hit each of these points, the higher the chance of the user either getting annoyed or abandoning the user experience altogether. So good performance is better for your visitors, better for you because you don't have to pay as much for your hosting, better for your Google rankings, and finally, better for the environment.
To understand performance optimization, you first need a solid understanding of how typing something into the address bar of a browser results in the page being rendered in the viewport.
To do away with some of this performance overhead, the domain name to IP address association will probably be cached at numerous different steps, your ISP will cached as information, it will also likely be cached in your router and on your computer. That way when you send a request to the same domain you requested before, instead of having to go through the whole DNS lookup again, we're just pulling a cache from somewhere closer to the computer, but that also means if the DNS has changed in the meantime, you'll get an incorrect address pointing and things won't work as expected.
Once the IP address is established, the browser and server now perform what's called a TCP handshake, where they exchange identity keys and other information to establish a temporary connection and working relationship. This is also where the type of connection is determined this is there's a regular HTTP connection or is it an encrypted HTTPS connection? If the latter, encryption keys are exchanged and if both the browser and the server support it, the transaction is updated from HTTP 1.1 to HTTP two, which provides substantial performance enhancements.
We now have a connection and everything is ready to go. At this point, the browser sends an HTTP GET request for the resource it's looking for. This initial GET request will be for whatever the default file on the server location is, typically index.html or index.php or index.js or something similar to that.
The time it takes for the browser to finally receive the first byte of the actual page it's looking for, is measured in time to first byte or TTFB. The first piece of data called the packet that the browser receives is always 14 kilobytes, then the packet size doubles with every new transfer. That means if you want something to happen right away, you need to cram it into those first 14 kilobytes.
The metric time to first Contentful paint refers to how long it takes for all of this to happen. What's important for our purposes is to remember what's actually happening, that way we can identify bottlenecks and add performance enhancements to get past them as quickly as possible.
To work around this obvious issue, browsers cheat by opening up to six parallel connections to the server to pull down data. However, this creates what's known as head of line blocking, where the first file, the HTML file, holds back the rest of the files from downloading. It also puts enormous strain on the internet connection and the infrastructure, both the browser and the server, because you're now operating with six connections instead of one single connection.
In HTTP/2, we have what's known as multiplexing. The browser can download many separate files at the same time over one connection, and each download is independent of the others. That means with HTTP/2, the browser can start downloading a new asset as soon as it's encountered, and the whole process happens significantly faster.
Now, for HTTP to work, a few key conditions need to be met. Number one, the server must support HTTP/2. Number two, the browser must also support HTTP/2. And number three, the connection must be encrypted over HTTPS. If any of these conditions are not met, the connection automatically falls back to HTTP/1.1. So bottom line, for instant performance improvements with minimal work, get an SSL certificate for your domain and ensure your server supports HTTP/2.
The next bottleneck is the connection made between the browser and the servers hosting the files necessary to render the page. For each of these connections, that whole DNS and TCP handshake loop needs to take place, which slows down the whole process.
Caching(or storing of assets) is also one of the methods for performance optimization. This can be done on the server, on the CDN or in the browser.
- Caching on the Server
If you're running a site relying on server-side rendering, meaning each page or view is generated on the fly by the server when it is requested, caching may provide a huge performance boost. By enabling caching, the server no longer has to render the page every time the page is requested.
Instead when the page is rendered, a snapshot of that page is created and then stored in the server cache. The next time a visitor then comes to the site, there'll be handed at this stored cached snapshot instead of a freshly rendered page. This is why static site generators have become so popular: they produce pre-rendered cacheable static pages and bypass the entire CMS service side rendering problem. The challenge with this type of caching is in dynamic features they have. Like every time a new comment is added, the cache needs to be cleared, and then the page has to be regenerated. Even so, caching should be enabled for all sites relying on server-side rendering because performance benefits are so significant.
- Caching on the CDN
- Caching in the browser
To achieve the best possible performance for your website or application always keep the PRPL pattern in mind.
This is an acronym that stands for:
Push or preload important resources to the browser using server push for the initial load and service workers in the next round, the application will run faster.
Pre-cache remaining assets so they are available when the browser needs them.
Lazy load all non-critical assets so they only load when they are actually needed, such that we reduce the time to initial load and save the visitor from wasting their bandwidth on assets they will never use.
The number one metric that determines the performance of your site or app is its weight.
Performance budget gives you a metric to measure every new feature against and a tool to use when hard decisions need to be made. A performance budget may include limits on the total page weight, total image weight, number of HTTP requests, maximum number of fonts or images or external assets, etc.
Some best practice metrics for Performance budget are:
- Make sure that your site meets a speed index under three seconds.
- Time to interactive is under five seconds.
- The largest contentful paint is under one second
- The max potential first input delay is under 130 microseconds.
- The total bundle size is under 250kb and that all of this happens on a low powered feature phone on 3G.
Now these performance budget metrics are severe and really difficult to hit. They're also the metrics being used by tools like Lighthouse to test for performance.
So the question here comes how to create a realistic Performance Budget?
- Build seperate performance budgets on slow networks and laptop/desktop devices on fast networks.
- Do performance audit.
- Set resonable goals based on audit.
- Test production version against perfomance budget.
- Do a competitor performance audit: make your performance goal better than your competitor.
- Test all work against Performance budget though Performance budget are unique to each project and will change overtime.