On most of the projects built with Front-Commerce, we perform an audit. Without surprise, these audits are conducted on the basis of a checklist. The first part is devoted to performance and the very first criterion is to evaluate the number of external requests necessary to build the most visited pages when everything is cached. The point is to target zero external request to generate those pages. Maybe you wonder why we check that or why we give it so much importance.
This Performance section is introduced with the following sentence:
Performance is essential to improve user experience, but also to reduce server load and thus increase the site's traffic capacity.
So the point of the whole section is not only to increase the performances i.e.
in that case, the time it takes to generate a page but also to increase the
scalability of the application i.e. according to
the property of [the
application] to handle a growing amount of work.
To measure the number of external requests, you can use one of our debug
flags. For instance, here
I'll use a very basic setup where Front-Commerce is connected only to a Magento2
instance, so I can add
DEBUG=axios in the environment to have some information
about external requests. Depending on your actual setup, you might need other
values to also count requests to Prismic or any other external service.
Also, we are mainly interested in the most popular pages of the site. Commonly, the homepage is most visited page. By default, we also check the category and the product pages. Depending on your project, this list can be slightly different.
Number of external API calls versus performance
Note: Performance is a very wide topic. By performance here, we are looking
at the time needed to generate a page server side. This is very easy to
measure with a
curl based command:
$ time curl -s http://example.com/my/url > /dev/null
On a Front-Commerce setup configured without cache and connected to a Magento2 instance, 27 requests to Magento2 APIs are needed to generate a category page. Each of these requests takes a significant amount of time, sometimes several hundred of milliseconds. While when caches are enabled, if everything is in cache, no external request is made.
Without surprise, the time needed to generate the page is completely different:
- without cache, on my local setup, it took between 5 and 6 seconds;
- with everything already cached, it took between 200 and 300 milliseconds.
It's 20 times faster! The example is a bit extreme, but I guess you get the point. Also, without external requests, the response time is somehow similar to any external API call. This means that if on a page you have one external API request left, getting rid of it might divide the response time by two. Worth a try, don't you think?
Number of external API calls versus scalability
Measuring the scalability is harder. It is done with load tests that involves running some scenarios to simulate traffic peaks (usually inspired by past events) in a production like environment. That's definitely not something you can do reliably on your local environment in 10 minutes. That being said, we always see a clear correlation between the number of external requests and the scalability of the application.
Commonly, the target of those external requests (the Magento2 instance in my
previous example) becomes the bottleneck of the application especially if some
popular pages requires several API requests to the same service i.e. one page
generated by Front-Commerce entails
n requests to one external service.
Depending on how Front-Commerce is hosted, it can also be the bottleneck because it will be busy waiting for some APIs to reply 😀.
The conclusion is simple: when it comes to external request, the less the better. After having said that, it remains the hard work of optimizing the application and the recipe is classic:
- is the external request strictly needed ? In some case, it might be an opportunity to discover useless code or to discuss feature;
- if it is strictly needed then you need to add more cache to the application either by leveraging the dataloader mechanism or by using the cache at resolver level if your project embeds content from Prismic.