.NET Core Performance Tuning - How to speed up asp.net core web application
Though the .NET Core is already optimized for performance, having some tunning and following best practice can help a lot, in another world every one need to have a reliable, flexible, and faster application with just applying better approach.
One clear guideline is always true for any application proper use data flow, caching, best practice for coding, following design pattern will lead to better undoubtedly. But in this post, we are looking some .net core specific tunning and web publishing and hosting key points.
Inlining and JIT
As we know Inlining technique will avoid the cost of jumping in execution. But be clear that Roslyn has nothing have to do with inlining. This job is of JIT. A JIT uses some logic to make inline or not they are listed below,
-
Methods which are greater than 32 bytes of IL will not be inlined,
- So it's good to have small methods, which is again a best practice point but valid in this case too.
- Virtual functions are not inlined,
- Methods which has complex flow control will not be in-lined.
- Complex flow control is any flow control other than if/then/else; in this case, switch or while.
- Methods that contain exception-handling blocks are not inlined,
- But methods which throw exceptions are still valid for inlining.
- If a method formal arguments are structs or Nullable<T>, then the method will not be inlined.
Note:- Rule of thumb, if the inlining method improves performance, then JIT will inline method
Garbage Collector (GC) and Memory Allocation
Memory management in .NET's is done by GC and we all know that garbage collection is a successful technique for memory management. But having a little-planed code can save much effort of GC and make our server resource free to do the better task in place of just busy in memory management.
So again it's time to talk about cache policy, local object caching, use of using blocks smart uses of object scoping can help a lot.
Do use of Filter types effectively
-We have
- Authorization filters,
- Resource filters,
- Action filters,
- Exception filters and
- Result filters,
learn them well and use for the better execution pipeline.
Learn when to use what type of Dependency in-service lifetime
We have
- Scoped - Scoped lifetime services are created once per request,
- Transient - Services are created each time they're requested,
- Singleton - Services are created the first time they're requested
So proper use of service lifetime can increase performance as well as reduces memory, CPU uses as well.
Return fully qualified View from Controller
It's good to return fully qualified defined view path so that the MVC Engine does not have to search for view location. The same applies for the controller logic as clear we have routing and controller placement as better performance can be achieved.
Use of health checks service in 2.x
Can be helpful in load balancer cases or when we are hosting applications in containers.
A code logic will looks like,
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks(); // Registers health checks services
}
public void Configure(IApplicationBuilder app)
{
app.UseHealthChecks("/healthz");
}
For more please refere https://blogs.msdn.microsoft.com/webdev/2018/08/22/asp-net-core-2-2-0-preview1-healthcheck/
Avoid LINQ
I know this can heart to some people but the fact is fact so I have added it, LINQ is difficult to optimize by JIT, so choices are yours. Note, use LINQ is not bad but remember how much performance tolerance we have for our application. On the other hand, LINQ to SQL more dangerous than only LINQ so save yourself at least this LINQ to SQL. Though there are the ways we can use smartly LINQ to SQL with better performance again it depends are we building for the performance or for small time project to RAID it.
Do refactoring for auto-generated code
In .NET core in many areas, we have a lot of auto-generated codes so allocate some time to look what are logic flow going on and can you make little better for your application because of you the one who knows your application better.
Remove unused profiles
- Remove unused middleware from startup.cs,
- Default Authentication remove if you not using it,
- Delete default controllers if not using,
- Check for unwanted comments in views which is just for test, if found remove
- Remove unwanted white spaces in views
Proper Selection of Data Type and it's operations.
Think for data size, data structures, what is seen that we generally hold data in var but if you know what data you going to get or you have an in-memory operation then go with known types rather than allowing auto to decide your thins. Remember their nothing auto and you know which variable or list can do a good job for your logic lines.
All the above points are some tips that always help you not in .net core but in any programming languages. But there are some more on deployment side too to get better performance some points are listed below,
We can have three types of deployments for .NET Core applications
- Framework-dependent deployment (FDD)
- The size of your deployment package is small.
- The application contains only its own code and any third-party dependencies that are outside of the .NET Core libraries.
- Self Contained Deployment (SCD)
- Sole control of the version of .NET Core that is deployed.
- The size of your deployment package is relatively large
- All components, including both the .NET Core libraries & the .NET Core runtime, included with the application and isolated from other .NET Core applications. SCD have executable such as app.exe.
- Framework Dependent Executables (FDE)
- The application can run by calling the published .exe without invoking the .net utility
- Unlike an SCD, the application only contains code and any third-party dependencies which are outside of the .NET Core libraries. FDEs produces an executable which runs on the target platform.
Chose any of them as per your need.
Response compression
In .net core, we have Response Compression Middleware like,
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseResponseCompression();
}
}
We can do more for some extra extension types like,
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression(options =>
{
options.Providers.Add<BrotliCompressionProvider>();
options.Providers.Add<GzipCompressionProvider>();
options.Providers.Add<CustomCompressionProvider>();
options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat new[] {"image/svg+xml"});
});
}
Reduce the number of HTTP requests
- If possible use latest version of the web server (IIS) to get the support of HTTP 2.
Minify Js and CSS files
- Always helps for the speed and also load only those JS and CSS that are needed for the running pages, some time during development developer load some JS and CSS file but if they are not used then find them and remove them.
- Load CSS file first and Load all possible js file in last.
- Optimize Images
- For speed optimized images will help always more.
- Better use of fluid images or responsive images.
- Use latest image extension like .svg and.WebP
-
Use of CDN
- Use of CDN is always good, but if in case you do not have then at least try to build some central resources of your static files like js and css and pass them with a different subdomain that will allow loading your resource faster, at least you same some time for loading and distribute the load.
Please add your points in comment too so that other can get help with that too.
Happy Performance Tuning :)