Tips to Build Fast Web Applications
Introduction - The Need for Fast Web Applications
If you are a web developer building public web applications, it is very important to consider site performance as one of the primary requirements. A faster web application provides better customer experience and can lead to higher revenues. Site performance is also important for better visibility in Google search index. Google considers site performance as one of the parameters in deciding how high the web content should be in the search results. Hence performance is super important in publicly available websites such as eCommerce storefronts. In this article, I discuss some quick tips you can use while developing your web application for better performance.
Tips to Improve Speed of Web Applications
Here are some tips to improve the speed of your web application,
Tip 1: Use a fast hosting provider which supports hosting your site closer to your target audience. There is a wide range of hosting providers available, but if you use a shared hosting provider, you may not have the desired site speed. The best ones would be the public cloud providers such as Microsoft Azure, Google Cloud Platform or Amazon Web Services who provide cheap and fast servers. If your budget is low, look for a faster shared CPU provider such as Linode.
Tip 2: Use a content delivery network(CDN) for your static files such as images, CSS and JavaScript that rarely changes. This ensures very low latency for such resources since there are a large number of local servers closer to the user that can cache this content.
Tip 3: Minimise the size of files that are sent to the user. This can be achieved by removing anything that is not needed in specific pages/screens and by ensuring compression of the data and files sent to the browser. Most modern browsers natively decompress GZIP files before rendering. For web, the best image format for reduced size is WebP and you can either convert your images to this format or use front-end frameworks(NextJS etc.) that can automatically do this along with progressive enhancement of the image.
Tip 4: Use browser caching where possible using HTTP headers. This ensures that rarely changed files are loaded from the local browser and it will also reduce bandwidth requirements and load on your application server.
Tip 5: Use lazy loading techniques wherever possible. This approach only loads the content that is immediately required and then loads additional content when requested. In some Web applications, this may require doing a balancing act between Web performance and user requirements. This technique can also be used even in cases where full data is needed without intervention. For example, only loading the content as the user scrolls down.
Tip 6: Minimise blocking JavaScript in web pages. Use asynchronous JavaScript to avoid blocking the loading of other elements on the page.
Tip 7: Use server-side rendering. A lot of modern front-end applications are rendered using JavaScript and API response. This leads to highly composable user interfaces, but also leads to low performance since JavaScript needs to be downloaded and then executed on the client machine before content is visible to the user.
By pre-rendering the resulting HTML on the server side, it is possible to substantially improve the performance and responsiveness of a Web application. This is very useful in use cases such as eCommerce journeys where most of the product details page content is the same for all users. In such cases, a hybrid approach can also be taken by enhancing the pre-rendered content with dynamic content on the client side.
Tip 8: Optimise backend API performance - It is important to have all the real-time APIs used in a Web application as fast as possible. This requires careful design of the API, use of appropriate data structures and techniques such as query optimisations or data caching to ensure a fast API. It is also important to verify that API performance is not degraded when real data is loaded in the system or when multiple users are accessing the API. Use volume testing and load testing techniques to ensure API performance.
Tip 9: Minimise multiple HTTP calls wherever possible. Every additional API request requires HTTP handshaking time. Carefully design your API even sometimes creating composite ones to minimise a large number of HTTP calls before the web page is loaded.
Tip 10: Use an appropriate front-end framework. For consumer facing web applications, you can now pick from a large list of front-end frameworks with focus on rendering performance. Some of the popular technologies/frameworks include ReactJS, NextJS and GatsbyJS. These frameworks provide out of the box image optimizations, ability to pre-render a full web page or parts of a web page as needed for the web application. Choose your front-end framework wisely!
Tip 11: Use data caching on the backend. This is closely related to backend API performance. Caching API output or database query results in memory can substantially improve the web application performance. However, you need to be careful that users are not shown stale data.
Tip 12: Use a frontend performance monitoring tool such as Google pagespeed insights. These tools can provide specific inputs or bottleneck areas which you can then prioritise and optimise. Encourage your front-end teams to use browser developer tools and Google pagespeed insights to optimise the application screens during the development itself. Remember any optimizations after site build can be 10x costly than doing it during the development phase!
Tip 13: Use a backend performance profiling tool such as VisualVM for Java. Use an appropriate profiling tool for your backend language to identify possible bottlenecks and optimization opportunities. For example, VisualVM or JProfiler for Java can provide granular performance metrics of your code. Nowadays cloud platforms also provide out of the box profiling tools for cloud native services and language specific workloads (Java, JavaScript, Python etc.). Use them!
Tip 14: Minimise number of page redirects. Use a mobile first page design approach for our application so that there is no longer any need for page redirects. Use browser developer tools or command-line tools to verify that there are no unnecessary redirects for pages.
Tip 15: Minify your site scripts. Most front-end frameworks such as NextJS provide script minimization automatically. Ensure that you also use only the required dependencies in front-end apps.
Tip 16: Avoid third party domain lookups for scripts. You may be using plenty of third party scripts for your application. Usually these scripts are available on third party CDNs and if people are using them in other apps, potentially your site can use the cached one. However, I recommend keeping all scripts including third party scripts on your own server.
Tip 17: Ensure web application has no broken links. Broken links can lead to poor user experience and non-existent file imports unnecessarily increase load on the server. Use browser developer tools to identify and eliminate broken urls or links.
Tip 18: Reduce third party scripts. Many complex web applications contain a large number of third party scripts for various application features. For example, a typical application may include loyalty scripts, analytics scripts, social media scripts etc. Minimise the use of these unless there is a clear business benefit for each of them. Also ensure they are loaded only on pages that require them.
Metrics Used by Google Page Insights to Quantify Site Performance
Following are the metrics used by Google to evaluate web page performance. Use of the above tips appropriately will improve these metrics. Please also note that when Google gives an overall score, the following metrics are given different weights. For example, total blocking time has a much bigger weightage than speed index.
First Contentful Paint(FCP) - This is the time taken for the user to see any content on the browser screen after navigating to the web page. Seeing any content assures the user that something is happening and he can access the full content soon. The lower this time, the better and we should aim to keep this number less than 2 seconds.
Speed Index(SI) - This time metric that shows you how quickly the contents of a page are visibly populated. It is the average time at which visible parts of the page are displayed. It is important to note that this is a mathematically computed time value which represents how the user perceives full visible rendering of the page. Note that since this is measured in terms of the visible view, it is viewport dependent. Try to keep this value under 3.5 seconds.
Largest Contentful Paint(LCP) - This metric reports the render time of the largest image or text block visible within the viewport, relative to when the page first started loading. It is used to measure the user perception on the site speed. Obviously using the load time of the largest image or text block may not always accurately reflect user perception. But Google claims that their research shows for most use cases it does work. Try to keep this value under 2.5 seconds.
Time to Interactive(TTI) - This measures how fast the webpage is ready to accept user input or ready to respond to events. It is measured by looking at when the site is interactive with long running JavaScript events or loading events are finished. Hence this measure can identify issues such as long running JavaScript or large JavaScript file sizes. Try to keep this value under 5 seconds.
Total Blocking Time(TBT) - This is closely related to TTI, but measures the actual blocking time between FCP and TTI. A large value shows the severity of the blocking nature of the website. Try to keep this value under 200 milliseconds.
Cumulative Layout Shift(CLS) - This metric measures the visual stability of the web page as perceived by the user. The intent is to prevent unexpected layout changes which can be confusing to the user and can lead to unintended clicks etc. The recommended value is 0.1 or less. Practically CLS can be minimised by specifying size attributes for media and by ensuring that content is not abruptly introduced above existing content.
Note that Google Page Insights also provides a set of tips in the form of optimisation opportunities. See this page for more details.
Adding Web Performance Requirements in Your Engineering Processes
Please note that for each of the tips above, there are multiple optimization techniques that can be used. I suggest creating these tips as high level technical stories and then adding individual optimization tasks as sub-stories as part of your agile project (for example, in JIRA).
Before starting development on a Web application, it is very important to select appropriate tech stack based on the use case scenario. For example, if you are building an eCommerce storefront where the site performance is super important both for customer experience and SEO, choose a front-end framework such as NextJS or GatsbyJS that supports server side rendering and Google page insight based optimisations. This goes a long way in implementing the tips mentioned above.
Also note that web application performance improvement should be part of the application development cycle and a continuous activity. Initially look for the activities that take only 20% of your effort in achieving 80% improvement. Then gradually address the remaining tips. Also add measurement of site performance as part of your continuous integration and continuous deployment pipeline so that any future changes are immediately optimised if a performance hit is detected. Cloud providers such as Microsoft Azure are now providing cloud native load testing services which you can now integrate within your software release process.