Performance Optimizations in the Sitefinity 12.2 Release

December 26, 2019 Digital Experience, Sitefinity

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.

Startup Time

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.

Average Startup in Different Environments Improved Between 9 – 25%

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%

Sitefinity 12.2 Serves Content Faster—Improved Server Response Time

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.

Average Server Response Time (TTFB) for Pages in Different Environments Improved Between 14 – 31%

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%


New UI First Load Time (using Pages Screen)

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.

New UI First Load Time (using Pages Screen) in Different Environments Improved Between 67– 83%

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%

 

Performance Optimizations on Startup

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.

Use Cached Controller Container Assemblies

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.

Automatically Load Ninject Extensions

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%

 

Parallel Loading of Sitefinity Modules

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%

Feather File Monitor Initializer Optimization

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%

Runtime Performance Optimizations

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.

Performance Optimizations on the Expression Visitor

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%

Related Data Queries Optimization

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.

Data Provider Base Count Query

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.

ObjectFactory Cache for Resolving the Same Types

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%

Backend Pages Queries in the Main Menu

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%

Optimized MVC Package Resolving

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%

Optimized MVC Navigation

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.

Wrap Up

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.

UPGRADE NOW

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.

SCHEDULE A DEMO

Todor Totev

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.

Read next Sitefinity DX 14.3: Perfecting the Digital Experience Toolset