Tutorial :How do I improve ASP.NET MVC application performance?



Question:

How do you improve your ASP.NET MVC application performance?


Solution:1

A compiled list of possible sources of improvement are below:

General

  • Make use of a profiler to discover memory leaks and performance problems in your application. personally I suggest dotTrace
  • Run your site in Release mode, not Debug mode, when in production, and also during performance profiling. Release mode is much faster. Debug mode can hide performance problems in your own code.

Caching

  • Use CompiledQuery.Compile() recursively avoiding recompilation of your query expressions
  • Cache not-prone-to-change content using OutputCacheAttribute to save unnecessary and action executions
  • Use cookies for frequently accessed non sensitive information
  • Utilize ETags and expiration - Write your custom ActionResult methods if necessary
  • Consider using the RouteName to organize your routes and then use it to generate your links, and try not to use the expression tree based ActionLink method.
  • Consider implementing a route resolution caching strategy
  • Put repetitive code inside your PartialViews, avoid render it xxxx times: if you end up calling the same partial 300 times in the same view, probably there is something wrong with that. Explanation And Benchmarks

Routing

Security

  • Use Forms Authentication, Keep your frequently accessed sensitive data in the authentication ticket

DAL

Load balancing

  • Utilize reverse proxies, to spread the client load across your app instance. (Stack Overflow uses HAProxy (MSDN).

  • Use Asynchronous Controllers to implement actions that depend on external resources processing.

Client side

  • Optimize your client side, use a tool like YSlow for suggestions to improve performance
  • Use AJAX to update components of your UI, avoid a whole page update when possible.
  • Consider implement a pub-sub architecture -i.e. Comet- for content delivery against reload based in timeouts.
  • Move charting and graph generation logic to the client side if possible. Graph generation is a expensive activity. Deferring to the client side your server from an unnecessary burden, and allows you to work with graphs locally without make a new request (i.e. Flex charting, jqbargraph, MoreJqueryCharts).
  • Use CDN's for scripts and media content to improve loading on the client side (i.e. Google CDN)
  • Minify -Compile- your JavaScript in order to improve your script size
  • Keep cookie size small, since cookies are sent to the server on every request.
  • Consider using DNS and Link Prefetching when possible.

Global configuration

  • If you use Razor, add the following code in your global.asax.cs, by default, Asp.Net MVC renders with an aspx engine and a razor engine. This only uses the RazorViewEngine.

    ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new RazorViewEngine());

  • Add gzip (HTTP compression) and static cache (images, css, ...) in your web.config <system.webServer> <urlCompression doDynamicCompression="true" doStaticCompression="true" dynamicCompressionBeforeCache="true"/> </system.webServer>

  • Remove unused HTTP Modules
  • Flush your HTML as soon as it is generated (in your web.config) and disable viewstate if you are not using it <pages buffer="true" enableViewState="false">


Solution:2

The basic suggestion is to follow REST principles and the following points ties some of these principals to the ASP.NET MVC framework:

  1. Make your controllers stateless - this is more of a 'Web performance / scalability' suggestion (as opposed to micro/machine level performance) and a major design decision that would affect your applications future - especially in case it becomes popular or if you need some fault tolerance for example.
    • Do not use Sessions
    • Do not use tempdata - which uses sessions
    • Do not try to 'cache' everything 'prematurely'.
  2. Use Forms Authentication
    • Keep your frequently accessed sensitive data in the authentication ticket
  3. Use cookies for frequently accessed non sensitive information
  4. Make your resources cachable on the web
  5. Compile your JavaScript. There is Closure compiler library to do it as well (sure there are others, just search for 'JavaScript compiler' too)
  6. Use CDNs (Content Delivery Network) - especially for your large media files and so on.
  7. Consider different types of storage for your data, for example, files, key/value stores, etc. - not only SQL Server
  8. Last but not least, test your web site for performance


Solution:3

Code Climber and this blog entry provide detailed ways of increasing application's performance.

Compiled query will increase performance of your application, but it has nothing in common with ASP.NET MVC. It will speed up every db application, so it is not really about MVC.


Solution:4

This may seem obvious, but run your site in Release mode, not Debug mode, when in production, and also during performance profiling. Release mode is much faster. Debug mode can hide performance problems in your own code.


Solution:5

When accessing data via LINQ rely on IQueryable ...

Why use AsQueryable() instead of List()?

... and leverge a good Repository pattern:

Loading Subrecords in the Repository Pattern

This will optimize data access to ensure only the data needed is loaded and when only it is needed.


Solution:6

Not an earth-shattering optimization, but I thought I'd throw this out there - Use CDN's for jQuery, etc..

Quote from ScottGu himself: The Microsoft Ajax CDN enables you to significantly improve the performance of ASP.NET Web Forms and ASP.NET MVC applications that use ASP.NET AJAX or jQuery. The service is available for free, does not require any registration, and can be used for both commercial and non-commercial purposes.

We even use the CDN for our webparts in Moss that use jQuery.


Solution:7

Also if you use NHibernate you can turn on and setup second level cache for queries and add to queries scope and timeout. And there is kick ass profiler for EF, L2S and NHibernate - http://hibernatingrhinos.com/products/UberProf. It will help to tune your queries.


Solution:8

I will also add:

  1. Use Sprites: Sprites are a great thing to reduce a request. You merge all your images into a single one and use CSS to get to good part of the sprite. Microsoft provides a good library to do it: Sprite and Image Optimization Preview 4.

  2. Cache Your server object: If you have some references lists or data which will change rarely, you can cache them into memory instead of querying database every time.

  3. Use ADO.NET instead of Entity Framework: EF4 or EF5 are great to reduce development time, but it will be painful to optimize. It's more simple to optimize a stored procedure than Entity Framework. So you should use store procedures as much as possible. Dapper provides a simple way to query and map SQL with very good performance.

  4. Cache Page or partial page: MVC provides some easy filter to cache page according to some parameters, so use it.

  5. Reduce Database calls: You can create a unique database request that returns multiple objects. Check on Dapper website.

  6. Always have a clean architecture: Have a clean n-tiers architecture, even on a small project. It will help you to keep your code clean, and it will be easier to optimize it if needed.

  7. You can take a look at this template "Neos-SDI MVC Template" which will create a clean architecture for you with lots of performance improvements by default (check MvcTemplate website).


Solution:9

In addition to all the great information on optimising your application on the server side I'd say you should take a look at YSlow. It's a superb resource for improving site performance on the client side.

This applies to all sites, not just ASP.NET MVC.


Solution:10

One super easy thing to do is to think asynchronously when accessing the data you want for the page. Whether reading from a web service, file, data base or something else, use the async model as much as possible. While it won't necessarily help any one page be faster it will help your server perform better overall.


Solution:11

1: Get Timings. Until you know where the slowdown is, the question is too broad to answer. A project I'm working on has this precise problem; There's no logging to even know how long certain things take; we can only guess as to the slow parts of the app until we add timings to the project.

2: If you have sequential operations, Don't be afraid to lightly multithread. ESPECIALLY if blocking operations are involved. PLINQ is your friend here.

3: Pregenerate your MVC Views when Publishing... That will help with some of the 'first page hit'

4: Some argue for the stored procedure/ADO advantages of speed. Others argue for speed of development of EF and a more clear seprataion of tiers and their purpose. I've seen really slow designs when SQL and the workarounds to use Sprocs/Views for data retrieval and storage. Also, your difficulty to test goes up. Our current codebase that we are converting from ADO to EF is not performing any worse (and in some cases better) than the old Hand-Rolled model.

5: That said, Think about application Warmup. Part of what we do to help eliminate most of our EF performance woes was to add a special warmup method. It doesn't precompile any queries or anything, but it helps with much of the metadata loading/generation. This can be even more important when dealing with Code First models.

6: As others have said, Don't use Session state or ViewState if possible. They are not necessarily performance optimizations that developers think about, but once you start writing more complex web applications, you want responsiveness. Session state precludes this. Imagine a long running query. You decide to open a new window and try a less complex one. Well, you may as well have waited with session state on, because the server will wait until the first request is done before moving to the next one for that session.

7: Minimize round trips to the database. Save stuff that you frequently use but will not realistically change to your .Net Cache. Try to batch your inserts/updates where possible.

7.1: Avoid Data Access code in your Razor views without a damn good reason. I wouldn't be saying this if I hadn't seen it. They were already accessing their data when putting the model together, why the hell weren't they including it in the model?


Solution:12

  1. Implement Gzip.
  2. Use asynchronous rendering for partial views.
  3. Minimize database hits.
  4. Use a compiled query.
  5. Run a profiler and find out unnecessary hits. Optimize all stored procedures which are taking more than 1 second to return a response.
  6. Use caching.
  7. Use bundling minification optimization.
  8. Use HTML 5 utilities like session cache and local storage for readonly contents.


Solution:13

Just wanted to add my 2 cents. The MOST effective way to optimize the URL route generation in an MVC application is... not generate them at all.

Most of us more or less know how URLs are generated in our apps anyway, so simply using static Url.Content("~/Blahblah") instead of Url.Action() or Url.RouteUrl() where possible, beats all other methods by almost 20 times and even more.

PS. I've ran a benchmark of couple of thousand iterations and posted results on my blog if interested.


Solution:14

In your clamour to optimize the client side, don't forget about the database layer. We had an application that went from 5 seconds to load up to 50 seconds overnight.

On inspection, we'd made a whole bunch of schema changes. Once we refreshed the statistics, it suddenly became as responsive as before.


Solution:15

Following are things to do

  1. Kernel mode Cache
  2. Pipeline mode
  3. Remove unused modules
  4. runAllManagedModulesForAllRequests
  5. Don't write in wwwroot
  6. Remove unused view engines and language


Solution:16

Using Bundling and Minification also helps you improve the performance. It basically reduces the page loading time.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »