I use the aspnetboilerplate/aspnetzero template for my Multi-Tenant SaaS application with Multi-Database. This uses CastleWindsor as DI Framework.
I experience very bad performance and I tracked it down with dotTrace - it says that Castle.MicroKernel is the most active code.
My requests take about 5-6 seconds and most of the time passes before it even hits the controller. (while debugging) I think that resolving all services/controllers is slow. I changed some dependencies (App-Services) from Transient to PerWebRequestLifetime but it didn't affect performance.
Does anyone know, how I can get better performance?
In my Views (_Layout file) I call several different Childactions, that are on Layoutcontroller, this Controller gets following Services injected:
public LayoutController(
IPerSessionCache sessionCache,
IUserNavigationManager userNavigationManager,
IMultiTenancyConfig multiTenancyConfig,
ILanguageManager languageManager,
ITenancyNameFinder tenancyNameFinder,
TenantManager tenantManager,
IUserLinkAppService userLinkAppService,
UserManager userManager)
Actions are
[ChildActionOnly]
public PartialViewResult AppHeader()
{
var headerModel = new Areas.Mpa.Models.Layout.HeaderViewModel
{
LoginInformations = AsyncHelper.RunSync(_sessionCache.GetCurrentLoginInformationsAsync),
Languages = _languageManager.GetLanguages(),
CurrentLanguage = _languageManager.CurrentLanguage,
IsMultiTenancyEnabled = _multiTenancyConfig.IsEnabled,
IsImpersonatedLogin = AbpSession.ImpersonatorUserId.HasValue,
HasLinkedAccounts = AsyncHelper.RunSync(_userLinkAppService.HasLinkedAccounts)
};
return PartialView("~/Views/Layout/_AppHeader.cshtml", headerModel);
}
[ChildActionOnly]
public PartialViewResult AppNavbar(string currentPageName = "")
{
var sidebarModel = new Areas.Mpa.Models.Layout.NavbarViewModel
{
Menu = AsyncHelper.RunSync(() => _userNavigationManager.GetMenuAsync(MeNavigationProvider.MenuName, AbpSession.ToUserIdentifier())),
CurrentPageName = currentPageName
};
return PartialView("_AppNavbar", sidebarModel);
}
and similar ones...But I checked the performance with an empty Layout File but my requests still take way too long
ASP.NET Boilerplate performance benchmark results
We created 2 identical simple application: One with ABP (https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/TestProjects/AbpPerformanceTestApp)
and other without ABP (https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/TestProjects/StandartTestApp)
Used Frameworks
Test Tool
We used jMeter for tests.
Test Results
Without ABP
With ABP
As seen in the statistics, ABP has added average 5ms overhead on top of a default asp.net code. Since this overhead is CPU usage, throughput is average 5% different.
We disabled Logging and Transaction of ABP for a better comparison (Logging especially effects performance since it uses I/O). Other aspects, filters and features are enabled as by default.
Thanks to Stevens comment:
Make sure your injection constructors are fast. You are probably doing some kind of I/O during object graph construction.
I actually figured out, that this was the problem. One of our Services did I/O in the constructor - which is very slow and results in bad performance of the IoC-Container instantiating it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With