ASP.NET MVC PERFORMANCE TUNING APPLICABLE TO .NET CORE AS WELL
ASP.NET MVC PERFORMANCE
TUNINGAPPLICABLE TO .NET CORE AS WELL
ALOK KUMAR PANDEY
CTO @BRAINDIGIT IT SOLUTIONPRESIDENT @ASPNETCOMMUNITYMVP @MICROSOFTSR. WRITER @LIVING WITH ICT
About Me?
Which Architecture is this?
Which Architecture is this?
What happens if I ignore this rule?• Does the world come to an end? • Does the sun stop shining? • Do the birds stop singing? • Does the grass stop growing? • Does my house burn down? • Does my dog run away? • Does my hair fall out? • If I ignore this rule and nothing bad happens, then why am I "wrong"? • If I follow this rule and nothing good happens, then why am I "right"?
Nine years have gone by since ASP.NET MVC first appeared
Building next-generation web apps
• Do you• want a framework that is faster than Node.js on I/O
and computation both? • know Is MVC 6 is now merged with Web API?• know the best practices while building RESTful APIs?
ASP.NET Core – Exceeds 1.15 Million request/s, 12.6 Gbps
http://web.ageofascent.com/asp-net-core-exeeds-1-15-million-requests-12-6-gbps/
Bad Smells in Code• Duplicated Code,• Long Method,• Large Class,• Long Parameter List• The Answer is,• Refactoring,
MVC design pattern
• objective in mind• reducing the complex code in the presentation layer,• the code in the user interface clean and manageable,• easier to test and maintain
Just in case
12
Model
View
Controller1
5
2
4
3
Browser
The request hits the controller
The Controller asks the Model for data
The Model gives the data back to the
ControllerThe controller formats the data and passes them to the View
The view renders the HTML that needs to be
sent to the client
Controllers
• Always try to keep Controllers Thin• controller should be extremely thin (< 5 lines of code)• Is testing required?• is it really necessary to test the functionality of a one-line method?• everything else should be tested.
Delete “AccountController”
You will probably never use these account management pagesKeeping demo code in a production application is EVILDelete it
Build your own “personal” conventions
ASP.NET MVC is the base on which to build your own reference architectureControllers (and views) inherint from your own base class
ActionResults
• ActionResults• Use Consistent Functionality
• Once we process Our data in the controller, • We almost always are returning an ActionResult of some kind. • It could be a View, a Redirect, or even a file.
ActionResults
• It gets monotonous and muddies up your controllers.• So build a commonly-used ActionResult for the task
Action Filters
• No HttpContext
Views• DO NOT include conditional code in your Views• Use Strong-Typed ViewModels where applicable• It's always a chore using ViewBag, ViewData, or TempData. Over the years, our
perspective is to send POCOs (Plain old CLR objects) to your Views.
• Embrace and use Partials• Partials are the equivalent to WebForms' UserControls. The advantage to partials
is that we can pass models into the partials making our site more modular.
Optimizing view lookup performance• Run in Release mode• <compilation debug="false" />
• Use only the View Engines that you needprotected void Application_Start() { ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new RazorViewEngine()); ...}
Choose your View Engine carefully
• The default is WebFormViewEngine• Not the best available• Choose the one that most suits you
Choose your View Engine carefully
• Spark View Engine• The flow is managed by HTML• It’s a templating engine
• Other Features• Renders PDF• Evaluates templates also with Javascript
ViewModels
• Make your ViewModels a little more functional• While passing data through our ViewModels requires a simple POCO, it doesn't
mean that our ViewModels can't help us to modify the data for a View.
Url Helpers
• Quit Chasing Links; • Use UrlHelpers as a "Table of Contents“• urls in one place will help us to replace links on a number of pages, we can go to
one place and change them instead of chasing links all over your application.
Html Helpers
• Use a minimal amount of TagBuilders in our Html Helpers• Only use HtmlHelpers for conditional decisions on existing data through our view.• Find an 'if' statement in our View, move it to an HtmlHelper.• Or put it in the model instead, if applicable.
• DO NOT place database calls in our Html Helpers
Routing
• Keep routes as simple as possible• Keep A "Route Table" Handy
Model Recommendations• DO separate the model its own project with a distinct assembly• DO put all business logic in the model• DO put all validation logic in the model• DO define interfaces for data access• DO put all session logic in the model
View Recommendations• DO put HTML in Views and Partial Views (not in a controller)• DO access data in views using ViewData• Whenever possible, we should use ViewData Model instead of the ViewData dictionary because it provides
better type safety. Additionally, we should use either data access mechanism rather than accessing the Request/Session state directly in the view template.
• Try to avoid nested partial view it may slow• Each controller creates a view in MVC, but in case of Add and Update (two action sharing common
purpose). It’s better to call same view from two action. because it helps in future if changes occur.• In ajax call it’s better to return partial view. Rather then returning data and binding in JS, because
we call controller action directly from ajax and then return view along data binding.
View Recommendations• DO enable (auto-generated) client side validation• DO insert server-side comments in templates• Use server side comments in the view templates for commenting. These
comments are stripped out before the server returns the HTML representation.• Like <%– This is a server side template comment –%>
Controller Recommendations• DO use model binding instead of manually parsing the request• <%= Html.TextBox("Name") %>
• DO explicitly name views in action methods• Like return View("explicitViewName")
• DO use Post/Redirect/Get (PRG) when submitting forms• HTTP GET is used for non-changing (idempotent) data to our model.• HTTP POST is used for changing data to our model.
Controller Recommendations
• DO implement HandleUnknowAction and HandleError• Like 404 or in the case of error etc.
Routing Recommendations• DO order routes from specific to general when using standard routing• DO use named route mechanism to avoid route ambiguity• routes.MapRoute("Default", "", new { controller = "Products", action = "List",
category = (string)null, page = 1 } );• routes.MapRoute("PageRoute", "Page{page}", new { controller = "Products",
action = "List", category = (string)null }, new { page = @"\d+" } );• <%= Html.RouteLink("Next", "PageRoute", new RouteValueDictionary( new { page
= i + 1 } )); %>
General Recommendations• We can Extend as per need• routing engine (MvcRouteHandler)• controller factory (IControllerFactory)• view engine (IViewEngine)
• DO use filters for adding behaviors• Will make lightweight in the request handling pipeline
General Recommendations• DO write units tests• DO guard against common attack vectors• Cross-site scripting (XSS) attacks• SQL injection• Cross-site Request Forgery (XSRF)• Improperly implementing model binding
• DO authenticate and authorize users to protect content
General Recommendations• DO use ASP.NET special resource folders and resource files• Do think about Performance on,• Database (Inefficient queries, Incorrectly placed indexes, Non-normalized design)• Bandwidth problems (Large request size, Content that references many other
items,Slow connection speed)• Processing power (Server: expensive operations, Client: poorly written javascript)
General Recommendations• DO consider partial page updates using AJAX for reducing bandwidth• DON’T overuse session, instead use TempData for short lived (intra-request) storage• DO use an OutputCache filter for static pages
[AcceptVerbs(HttpVerbs.Get), OutputCache(CacheProfile = "Dashboard")]public ActionResult Dashboard(string userName, StoryListTab tab, OrderBy orderBy, int? page){ ...}In the Web.config file, the duration is fine tuned to 15 seconds.
General Recommendations
• DO consider using asynchronous controllers for long running requests• ASP.NET’s threading pool has a default limit of 12 concurrent worker threads per
CPU• The server starts responding with 503 (server too busy) errors (> 5000 requests
pending)• Refer https://msdn.microsoft.com/en-us/library/ee728598(v=vs.100).aspx
What's true for love, is true for code
• Don't Repeat Yourself• Keep it Simple Stupid
Credits
• Presentation for DotNet Conf• References,• MSDN, Best Practices in MVC books and few points from “Simone Chiaretta”• Few points with our developers in Braindigit
Thank youfacebook.com/alokgo
Facebook Twitter
@alokpandey01