Pages - Menu

Performance Tuning - nopCommerce Category Page by Caching


In eCommerce, perhaps the most heavily viewed page is the product listing page (category page). It is the page that draws shoppers attraction, quick glance at the products and prices. We are trying to minimize the load time of the page as the scope of the article.


It is very important for the fact that when it comes to performance tuning, we need to know where we are at and what we want to achieve. During my career, I have seen enough people and including myself that we are trying to optimize the system by modifying a bunch of codes, and the system just 'feels' like running faster without any scientific numbers on the paper.

In our load testing, ignore the first request for the fact that we are initializing the app pool and other bunch of crap that we need to prep for IIS, the average response time is currently at around 8 seconds. Not very impressive!

Another important fact about benchmarking is that we need to set a goal for our performance tuning. I have a goal to take it down to under 2 seconds. Some of my previous big named projects were doing pretty good during Christmas when the local benchmark is at around the 1.5 second mark.

nopCommerce 3.4

nopCommerce 3.4 recently did a performance tuning that boosted the system. Since it is open source, there is no harm for me to have a peek at what they are doing.

I merged some of the code for the CatalogController.Category(). I am so glad to see that they are now refactoring the code in a much nicer way than in version 3.1, much more like a platform now with all the protected virtual methods.

Prior to 3.4, they are caching if a category have any subcategories by using the key CATEGORY_HAS_SUBCATEGORIES_KEY.

In 3.4, they have changed it to cache the actual subcategories by using the key CATEGORY_SUBCATEGORIES_KEY.

This is in fact a very nice move, and was a question that I have been asking for so long. If we bother to cache if we have something or not, why don't we just cache what we have.


As usual, I like to take the steps further. There is a lot of calculations and database calls(although already cached like the subcategories above) in the CatalogController.Category() action. I am going to cache the entire CategoryModel used by the action in the cache. The benefit is there is a lot of boxing and unboxing in this method and I am trying to save those as well as the database calls.

Checked in the official forum that they have other concerns for not caching the entire model so that they can cater for wider audience. I don't have that concerns in my business requirement, so I am ready to go for the big cut.

I first refactored the code that gets the CategoryModel called PrepareCategoryModel(). Then I override the methods and add the model to the cache.


By looking at the results side by side, I have to say I am pretty happy with the performance. It is now running 8 times faster than previous; twice faster than what I would have expected at around 1 second.