Safewhere Identify is a big product with huge amount of features which also means that it has plenty of things to do during start up time. However, in reality our customers love not only features but also request for speed. Therefore, we have started a project to improve start-up time for Safewhere Identify. In version 5.5, because we don’t have all the time in the world, we managed to address a few issues that can give noticeable improvement. We expect to have make more improvements in future versions.
Improvements done in version 5.5
We made the following improvements in version 5.5:
- Drop support for 51degrees mobile library.
- Pre-build and cache Entity Framework’s EDMX models.
- Upgrade AutoMapper to latest version and remove unnecessary mappings.
Drop support 51degrees mobile library
Identify has long used 51degrees’ library to do mobile device recognition. Since the library has a lot of data of virtually all devices, it unfortunately consumes a large amount of memory. In addition, although it loads up data in background threads, doing that does use server resources which indirectly slows other things down. Taking into account the fact that we are using responsive views now, there is very little need for a full mobile device recognition library. Therefore, we decided to remove it from Identify.
Pre-build and cache Entity Framework’s EDMX models
Identify uses Entity Framework’s code first to define SQL data models. Formerly, EF needs to compile the code-first models into it EDMX models everytime Identify starts up. To solve this issue, we made use of a new feature of EF 6.2 which can cache the compiled EDMX models to disk. Technical-wise, the models are pre-compiled by Identify Configurator by the time an instance is created/replicated/upgraded.
To disable EDMX caching, you can delete all EDMXCache folders from Admin/Runtime/Service folder.
Upgrade AutoMapper to latest version and remove unnecessary mappings
Safewhere Identify uses AutoMapper heavily behind the scene to map all the domain models and its various service interface models. In addition to upgrading from version 3.2.1 to version 8.0 to be benefited from its recent performance optimization, we also remove unnecessary maps from Runtime part.
Other start-up activities
Identify also does a bunch of other activities during start-up, but they are all tighted to the core architecture and there is simply no way to improve them anytime soon.
How about serving the first request
The first request to Identify Admin will automatically triggers:
- Admin’s start-up
- Runtime’s start-up
- Have the UserNamePassword view shown: this step contains two big sub steps:
- Load data and cache in memory. This step is unavoidable and there is little room for optimization.
- Compile cshtml views.
One popular approach to reduce compiling time for cshtml views is to pre-compile them at build time. However, most customers will customize the views anyway which will invalidate precompiled views anyway. Our test shows that using hosted form can speed up first time render significantly. Please note that logging in to the Admin site triggers to set up hosted forms triggers compilation of the Username Password login view and maybe the Authentication list view.
As a side note, it seems compilation time is badly affected by the number of referenced assemblies a web application has, which is huge in Identify case. There is currently no viable solution for this issue.
We test by accessing Identify Admin which automatically triggers:
- Admin’s start-up
- Runtime’s start-up
- First request that has the UserNamePassword view shown
and use Miniprofiler to record start-up time of Identify before and after all improvements are done. The absolute numbers can vary from machine to machine, and even from time to time in the same machine.
|Benchmark result||Before||After||Absolute gain||Relative gain|
|Admin – 8.8s
Runtime – 6.5s
|Admin – 6s
Runtime – 3.7s
|Admin – 2.8s
Runtime – 2.8s
|Serving the first request|
|Benchmark result||Use cshtml views||Use hosted forms||Absolute gain||Relative gain|
|Render: UserNamePasswordAuthentication 5796.6 ms ( ~5.8 s)
Render partial: ReturnToLoginSelectorLink 1847.9 ms ( ~1.8 s)
|Render: UserNamePasswordAuthentication 747.6 ms (~0.8 s)
Render partial: ReturnToLoginSelectorLink 6.6 ms (0.006 s)
* Measured numbers don’t include time to compile views on Runtime side.