Join us for a deep dive into the details of the performance improvements in Sitefinity 12.2. Learn what we optimized and how much time it can save for the tasks you perform every day.
Sitefinity 12.2 delivers a broad set of new features that make marketers, content editors, and developers more productive. The Sitefinity engineering team cares deeply for product performance. We keep track and regularly test for performance regressions, and we address the found issues during the regular development cycle.
Some code changes are easy from an engineering point of view - tiny, isolated changes with small regression potential can increase product performance when they target the right performance bottlenecks. However, solving some performance problems requires a more holistic approach and brings substantial code changes with associated regression potential. For these we had to dig deep into all aspects of the system to identify performance bottlenecks and pinpoint areas in the code that could be improved for crucial user scenarios.
We delivered two types of improvements. First, we targeted long-running operations, like starting up a Sitefinity instance. You’ll experience these changes immediately. Second, we changed common operations used throughout the entire Sitefinity codebase. In this case, the individual speed-ups are smaller in absolute values, but the compound improvements are noticeable because of the repetitive nature of these operations. With these changes, we made Sitefinity faster overall.
In this blog post, you will find details for the most significant performance improvements we developed.
You will benefit from these improvements mostly during development where build and startup operations are frequent, as well as in cases of application restarts in Production environments.
We measured the startup time as the time it takes Sitefinity to initialize, without taking into account the time it takes for the .NET framework to start the application and for Sitefinity to load the first-page request after the initialization.
Setup |
Time before |
Time after |
Time reduction |
Quantum Demo project - Azure App Service (P1V2) |
47.95 s |
35.74 s |
25% |
Quantum Demo project – Azure App Service (P2V2) |
26.58 s |
22.65 s |
15% |
Quantum Demo project – Azure App Service (P3V2) |
25.09 s |
21.93 s |
13% |
Customer project - Azure App Service (P1V2) |
40.17 s |
32.58 s |
19% |
Customer project - Azure App Service (P2V2) |
25.68 s |
20.82 s |
19% |
Customer project – Azure App Service (P3V2) |
23.90 s |
20.42 s |
15% |
Local machine – Intel Xeon E3-1246v3 3.5GHz and SSD |
14.5 s |
13.2 s |
9% |
You will see the impact of these improvements when content changes invalidate the output cache, as well as when the output cache expires on its own, for example, with the Standard cache profile that has a two minute expiration.
We measured the server response time as the time to first byte (TTFB) without output cache. We took the results as an average between several different pages from each website. The results also don't measure the first time a page loads, which can include compilation and loading objects into the cache.
Setup |
Time before |
Time after |
Time reduction |
Quantum Demo Project - Azure App Service (P3V2)
|
0.52 s |
0.36 s |
31% |
Quantum Demo Project - Azure App Service (P1V2)
|
0.53 s |
0.37 s |
30% |
Customer project - Azure App Service (P1V2) |
1.04 s |
0.73 s |
30% |
Quantum Demo project – Azure App Service (P2V2) |
0.47 s |
0.38 s |
20% |
Customer project – Azure App Service (P3V2) |
0.90 s |
0.76 s |
16% |
Customer project – Azure App Service (P3V2) |
0.94 s |
0.79 s |
15% |
Local machine – Intel Xeon E3-1246v3 3.5GHz and SSD |
0.121 s |
0.104 s |
14% |
You will experience improved load times of the Pages screen both for first use after Sitefinity initialization and subsequent loading. This change affects only the redesigned user interface.
We measured the load time of the redesigned user interface after Sitefinity initialization completes using the Pages screen.
Setup |
Time before |
Time after |
Time reduction |
Quantum Demo Project - Azure App Service (P1V2)
|
23.46 s |
3.90 s |
83% |
Quantum Demo Project - Azure App Service (P2V2) |
16.48 s |
3.37 s |
80% |
Quantum Demo Project - Azure App Service (P3V2)
|
16.78 s |
3.22 s |
81% |
Customer project – Azure App Service (P1V2) |
21.00 s |
4.88 s |
77% |
Customer project – Azure App Service (P2V2) |
15.00 s |
4.52 s |
70% |
Customer project – Azure App Service (P3V2) |
14.83 s |
4.89 s |
67% |
Local machine – Intel Xeon E3-1246v3 3.5GHz and SSD |
8.10 s |
2.70 s |
67% |
We have identified various hotspots during the startup of the system. We approached the problem holistically and worked on improving the hot paths in lower code layers. Some are related to specific logic and methods that we introduced to help you easily customize the MVC widgets. With Sitefinity 12.2, we provide various optimizations, some of which are configurable via newly introduced settings. You can decide whether you want these settings enabled or not.
We improved the Sitefinity startup by changing the way the system loads assemblies with Feather controllers at startup.
We’ve introduced a new way the ControllerContainerAttribute and ResourcePackageAttribute are retrieved. A new setting controls this, located in Settings -> Advanced -> Feather -> Use cached controller container assemblies. Because this change does not affect the end-user experience, this setting is enabled by default in Sitefinity 12.2. This change applies to both newly created and upgraded projects.
In previous versions, there was a performance overhead because Sitefinity loaded all the assemblies one by one during startup. In Sitefinity 12.2, we’ve added a post-build action that generates a JSON file describing the Feather assemblies. What this means is that when the clients build the SitefinityWebApp project, a script runs, scans for these attributes and writes the names of the assemblies in a JSON file in the bin directory. If you have enabled the setting, when a Sitefinity project starts, it loads only the assemblies described in the JSON file instead of loading all the assemblies in the bin folder.
We’ve introduced a new setting, “Automatically load Ninject extensions.” With it, you can control the automatic loading of the Ninject extensions. You can find this setting in Settings -> Advanced -> Feather.
The system will look for and load custom Ninject modules when it starts only if you turn this setting on. By turning off this setting, you can boost the startup considerably. For example, in Azure App Service P1V2, scanning for Ninject extensions can take around 10s – ouch!
This setting is enabled in Sitefinity 12.2. This means that your projects will work as before the upgrade. However, please consider turning off this setting if you do not use Ninject extensions in your projects.
Test |
Time before |
Time after |
Time reduction |
Start Quantum in Azure |
00:01:18.73 |
00:01:04.90 |
18% |
As of this release Sitefinity modules are loaded in parallel on system startup. This way, all modules can load simultaneously, and they don’t wait for one to complete to start loading the other. This improvement is very impactful since the total time to load all modules is reduced to the time it takes to load the slowest module.
Test |
Time before |
Time after |
Time reduction |
Parallel modules loading |
00:00:03.55 |
00:00:01.72 |
52% |
This change contributes to a considerable decrease in startup time.
We have reduced the DB queries that the Feather FileMonitorInitializer makes during startup down to a single one.
Test |
Time before |
Time after |
Time reduction |
Time for initializing FileMonitoringInitializer when starting empty project |
00:00:01.70 |
00:00:00.17 |
90% |
With these changes, we focused on making the Sitefinity frontend snappier, and therefore, your site visitors – happier. We worked on some very low-level code which is performance-critical for rendering the site pages.
This optimization is the main contributor to the reduction in page load time. This optimization affects the Sitefinity runtime, page rendering, and it is an overall performance improvement related to building queries.
To perform any database query, Sitefinity constructs a custom Sitefinity expression visitor to build a LINQ expression tree. For historical reasons, the Visit method was called twice for each query. We simplified this and started invoking the Visit method only once.
Test |
Time before |
Time after |
Time reduction |
Page request for www.telerik.com |
00:00:02.81 |
00:00:01.39 |
51% |
We changed the implementation of the GetRelatedItems API and now it queries the DB only once. You’ll automatically benefit from this optimization without changing your code.
We applied the "Related Data Queries Optimization" changes for all providers in Sitefinity on a low level. We also optimized the DataProviderBase code and eliminated the count query it performed internally.
These two changes impact most operations and increase the speed of almost every end-user operation.
Resolving types in ObjectFactory is a very common operation. The simple API hid too well the underlying complexity and performance implications. Because the ubiquitous usage of this code pattern, we decided to improve its performance without changing the API and introduced a cache for resolved types in ObjectFactory.
This change speeds up almost every operation. And while the speed up for individual operation is just a tiny bit, the compound result is significant, and Sitefinity becomes faster overall.
Test |
Time before |
Time after |
Time reduction |
200 Config.Get operations with 5000 types registered |
00:00:00.35 |
00:00:00.01 |
97% |
This optimization affects the first time you open the Sitefinity backend and load the main menu, where we reduced the number of DB queries.
Test |
Before |
After |
Improvement |
Number of DB queries on startup |
Around 400 |
Around 50 |
# of queries reduced by 80% |
Time for Main Menu On-load |
00:00:01.05 |
00:00:00.06 |
Reduced time by 94% |
This change speeds up operations such as displaying pages containing MVC widgets.
We optimized the implementation of PackageManager.PackageExists method, and it now caches the package in the context for the lifetime of the request.
Test |
Time before |
Time after |
Time reduction |
Get current resource page package when requesting MVC page in an empty project |
00:00:00.0126162 |
00:00:00.0000021 |
99.98% |
You will be particularly happy with this change if you have an MVC Navigation widget displaying multiple pages.
We optimized the AddChildNodes method invoked from the MVC Navigation widget. Previously, this method needed to traverse the whole sitemap tree while this was not required in most cases. We significantly sped up this process. You’ll automatically benefit from this change without changing your code.
A handful of strategic touches add up to a meaningful performance boost in Sitefinity 12.2, which developers and content editors alike will surely appreciate. Better yet, the difference it makes to your end-users will also pay back handsomely. After all, people are significantly more likely to engage with fast-loading and responsive websites.
And it’s not just the speed and performance. Security and productivity, the overall look and feel—there are reasons to upgrade both big and small. Get 12.2 and you’ll know what we mean. Don’t miss out on the best Sitefinity experience yet.
Alternatively, if you prefer a walk-through by a Sitefinity expert, feel free to schedule a demo. We're looking forward to answering any questions you may have.
Todor started his career in software development more than 20 years ago and has used multiple technologies, languages, and frameworks. He also switched professions a few times. His passion has always been the high-productivity, visual development with clean and unceremonious code. A passionate gamer and avid book reader, he still prefers spending quiet evenings with his family.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites