BUILD 2014 Notes - Deep Dive: Improving Performance in Your ASP.NET App

Saturday, 21 June 2014
  • By
  • Jeff Ammons
  • Tags:
  • ASP.Net
  • Web
  • Performance
  • Conference Notes
  • Build Conference

Video Screen Capture

Levi Broderick speaking about improving ASP.NET performance.

Microsoft's Build Conference is their annual developer extravaganza.

The best thing about Build is that most of the sessions are published on Channel 9, so you can learn the new technologies even if you couldn't attend.

I am in the list of people who could not attend, but who are eager to learn.

If you are reading this, then I assume that you are also in that category.

As I watch these videos I tend to take notes.

As I watched this video and took notes in Vim with Markdown, it dawned on me that it would be a very short path to turning my notes into summary info that other folks might benefit from.

This also serves as my brain-dump/memory jogger for later.

I don't know how many I'll do, but if I get feedback that this is valuable, I'll likely do more.

Do remember that these are just my notes. You will definitely still need to watch the videos to make heads or tails of the notes. I don't plan to write full summaries or in many cases use full sentences.

Deep Dive: Improving Performance in Your ASP.NET App

Levi is a senior developer on the ASP.NET team and in this presentation he runs through a list of “gotchas” that affect many ASP developers.

Load Tester

WCAT WCAT: http://www.iis.net/downloads/community/2007/05/wcat-63-(x64)/ “WCAT”

First, DAMN IT MICROSOFT STOP USING PARENTHESES IN URLS!!!

Sorry. twitch twitch

Those of us using Markdown find that a bit annoying.

Web Capacity Analysis Tool (WCAT).

This is a simple load tester for web sites.

There are more advanced load testers, but this one is free and easy.

RAMMFAR

Run All Managed Modules For All Requests (RAMMFAR).

Basically route ALL requests through ASP, even static files.

This is useful to put ASP forms authentication in front of a PHP site.

You most likely want to disable this.

<system.webServer>
    <modules runAllManagedModulesForAllRequests="false" />
</system.webServer>

Suggestion

Put static files in separate app pool so it can have different settings than the main site.

For instance static.foo.com instead of foo.com. Turn RAMMFAR turned off for the static site.

This is a good idea for a lot of reasons Levi didn't go into. You can turn the cacheing way up, etc.

Session State

Sessions from same browser are handled serially.

Multi tabs for instance are a problem.

If you open 5 tabs, it has to process them one at a time since it knows they are all using the same session cookie. Can't keep things threadsafe otherwise.

In demo Levi sets a sleep:

Thread.Sleep(1000);

For Web Forms you can set the page to disable session state.

EnableSessionState = false on aspx page.

For MVC Controllers decorate the controller:

[SessionState(SessionStateBehavior.Disabled)]

Remove empty Session_Start from Global.asax.

App Suspension

Requires Win Server 2012 R2

Check out lambda syntax (_ ⇒ ) what does underscore mean in that context? _ Means parameter needed but not used

App pool level. Suspends process when there are no requests.

“Suspend” in the vein of Windows Phone or Windows 8 Modern App: dehydrate, rehydrate. Store state and remove from memory, then restore when activity resumes.

I suspect that this is extremely useful in an Azure Websites kind of world where huge numbers of apps need to run on the same virtual hardware.

Runtime caching

Object cache as opposed to Output cache.

HttpRuntime.Cache

  • High-performance in-memory cache
  • Outside ASP you can call System.Runtime.Caching.dll ObjectCache
  • Web farm requires affinitization.

Takes care of removing items from memory if memory pressure becomes too great.

Better choice than your own statics or dictionary.

I'm thinking comparable to Redis.

Long-running requests

25-30 KB RAM per request

Websockets or SignalR make better choice

Websockets 10 K or so. They are working on reducing this further.

SignalR negotiates best connection: websockets or long polling.

Async/Await

CLR ThreadPool

See aspConf talk for more info

Viewstate

Sucks. Don't use it. Not what Levi said. It still sucks. That's what jeffa says.

Use ViewStateMode for granular control. Only add what you really need.

Turn off for page, on for specific controls.

Limit what you store in the Page.ViewState property.

Do not set EnableViewStateMac=false Never, ever under any circumstances

Will break in the future if you use it.

Basically if you do this you are not encrypting the viewstate and someone will take advantage of that at some point and you will get what you deserve.

Data Access

This topic is talking about web forms data source.

Reduce number and size of queries.

EF code first and asp.net 4.5 model binding.

Prefer QueryableDataSource or ObjectDataSource over SqlDataSource.

Glimpse: shows you what's going on in your web app. Great diagnostic tool.

Get glimpse from nuget.

SqlDataSource does Select * EVERY time. Even during paging.

Damn. That sucks.

install-package glimpse.ef6

install-package ef…. 6.0 not 6.1. May be fixed by now.

Configuration

Places where throttling can occur:

  • Max concurrent requests per application

    • applicationHost.config
  • Max concurrent requests per CPU

    • aspnet.config:
  • ASP.NET request queue limit

    • machine.config: <processModel…/>

Miscellaneous Tips

  • Is debug=true still present in web.config?

  • Avoid one .aspx file per folder - try to cluster. Calls compilation system per folder so clustering helps

  • Consider precompilation to reduce startup time Avoids the above

  • Avoid writes to files under c:\inetpub\wwwroot Asp and iis monitor changes there (and children) looking for web.config etc changes. Causes recyle of app. Make sister folder to inetpub/wwwroot, not child.

  • Remove empty methods in Global.asax IIS will call methods even if they are empty.

  • Use tracing, Glimpse, Intellitrace to find bottlenecks. Also AppInsights

  • Use perf counters for diagnostics

  • Consider enabling CDNs on ScriptManager

  • Weigh 32 vs 64-bit processes 64 uses twice as much memory for some things.

  • Don't be afraid to scale out Basically an 80/20 thing. You reach a point of deminishing returns on your optimization efforts that means you are wasting your time.

Resources