IT:AD:IIS:Performance
Tools
Install YSlow plugin for Chrome Developers
[Yahoo Web Performance Best Practices and Rules](http://developer.yahoo.com/yslow/)
- Minimize HTTP Requests * Combine files. Combine JScript. CSS Sprites.
- Add an Expires or a Cache-Control Header * For static content set in 10 years in future, and add Version No to filename… * For dynamic content, use
Cache-Control - Gzip Components * Supported by 90% of current browsers, reduces payload by 70%…
- Put StyleSheets at the Top * Allows progressive rendering, rather than blank, while waiting for more info, in order to not have to repaint screen.
- Put Scripts at the Bottom * Scripts block parrallel loading - even across domains - so no images, or anything can come in till finished.
- Avoid CSS Expressions * Depracated in IE8. Was too CPU Intensive.
- Make JavaScript and CSS External * Externalized as files (rather than Inline) means cacheable…
- Reduce DNS Lookups * Cache is cleared at most every hour. Has to relook up. Between 2 (due to externalized static resources) but not more than 4…
- Avoid Redirects * Put a trailing slash!
- Remove Duplicate Scripts * Obvious…but it happens in 20% of sites.
- Configure ETags * Configure them for webfarms
- [Flush the Buffer Early] * Right after Head, so that it can go get css, etc. while wating for server to build rest of page.
- Use GET for AJAX Requests * POST is a two step process.
- Post Load Components * Load non-visible images later (see YUI Image Loader, and YUI Get utitity)
- Post Load Components * For future pages…
- Reduce the Number of DOM Elements * Obvious…CPU hit
- Reduce Cookie Size * They are sent out with every request (images, css, etc.)
- Use Cookie-Free Domains for Components * A solution to the last issue…
- Make favicon.ico Small and Cacheable * Can cause 404's, will send cookies, is downloaded first…
- Make things small: * iPhone won't cache things larger than 25K
Server Execution Best Practices
- IIS: Run Windows Server 2008 (R2) on new hardware:
- I didn't find an article that explicitly discusses this. We ran into this issue however when Windows Server 2008 was in Beta. The Windows Server 2008 bits are optimized to take advantage of the features of new CPU architectures. You probably will see that Windows Server 2008 doesn't perform well on old hardware compared to Windows Server 2003.
- IIS: Put existing default document on top of the Default Document list
- The list of IIS default documents increased over the years (iisstart.htm, default.htm, default.asp, index.htm, index.php etc.). Problem is that IIS has to go through the list of default documents and look in the file system until it finds one that actually exists. You can increase the execution speed by stripping the list of default documents or putting the one you are using on top of the list.
- IIS: Use IIS7 or ASP.NET output caching
- There is a good tutorial on the ASP.NET web-site on how to take advantage of Output Caching.
- Ultra-Fast ASP.NET also has a chapter on it.
- IIS7: Output Caching is discussed in this Learn.IIS.Net article.
* IIS: Use authentication and SSL only if necessary
- Couldn't find something linkable but the problem is obvious: authentication can introduce a round-trip to the backend, e.g. Active Directory and encryption is CPU extensive.
- IIS: Turn off unnecessary features like Request Tracing
- Request and ETW Tracing is pretty lean and invaluable for troubleshooting problems. But if you are under a lot of load you should probably turn these features off.
* PHP: Use FastCGI and not CGI
- The IIS team is committed to make PHP run well on Windows.
- Providing a first class FastCGI implementation was the first step which made this a reality.
- The Web Platform Installer makes installing PHP on IIS a one-click experience.
- Everything else on http://php.iis.net
* PHP: Enable Wincache
- If you run PHP without an output cache you will quickly run into performance problems.
- Wincache is an Open Source output cache for PHP developed by the IIS team.
- The simplest way to install it: Web Platform Installer
* PHP: Set FastCGI MaxInstances to 0
- FastCGI spawns multiple PHP processes for each web application.
- If you are in a hosted environment this might soon become an issue.
- Here is a great blog post on how MaxInstances can mitigate this problem.
* ASP.NET: turn of debug=“true” in web.config
- Increased memory footprint and unoptimized code are only two of the problems you'll see if the debug flag is set to true.
- ScottGu blogged about this a while ago.
ASP.NET: Read through the ASP.NET Performance Coding Architecture Guides
- Great book and also free.
* ASP.NET: Read about the Large Object Heap
- Every object larger than 85k goes into the LOH.
- The problem with the LOH is that the .NET Framework has a hard time to Garbage Collect LOH objects frequently enough in certain web scenarios, e.g. if you allocate a large object for every incoming HTTP request.
- See here
* ASP.Net: Use
ASPNET_COMPILERto optimize for the first impression - ASP.NET applications can take a long time to start up.
- Due to human nature the first impression counts however.
- That's why the Web Platform Installer runs
ASPNET_COMPILERat the end of an install of an ASP.NET application. ASPNET_COMPILERdoes a batch compile of all ASP.NET files and resources.- This speeds up startup, especially on slow disks!
- More about
ASPNET_COMPILERhere.aspx).
* ASP.NET: Review IIS idle timeout and proactive recycling settings
- Given the considerable startup time of ASP.NET applications you might want to look at the IIS recycling and idle timeout settings.
- IIS recycles Application Pools proactively every 29 hours. It also times out Application Pools when the site is inactive.
- A proactive recycle might be initiated right when you have the most traffic on your site and an idle timeout might happen just because you removed your server from the web farm for a few minutes.
- If you can afford it you might want to turn off idle timeout and find some better recycling settings for your ASP.NET application.
* ASP.NET: review Thread Pool settings
- there is a setting in ASP.NET that might not work well for high throughput sites.
- It's the
maxConcurrentRequestsPerCPUsetting. It's set to 12 by default, i.e. not more than 12 concurrent requests per CPU will be executed. Usually this setting works well. - We've seen instances however where a higher setting is necessary.
- Thomas has a great blog post on the thread settings in IIS7.
Optimizing Network Transfer Best Practices
* Use Content Distribution Networks
- Steve Souders book has a whole chapter about it.
* Use compression
- There are several great articles on compression on several blogs:
- the IIS compression configuration reference:
* Minify Javascript and CSS
- Enough said in Steve Souders book.
- Minification tools which work well on Windows:
* Use Doloto for splitting the initial Javascript payload
- Very well explained on the Doloto web site. No reason for me to rehash.
* Do not scale images in HTML
- Steve Souders first book
* Optimize Images
- Steve Souders: Even Faster Web Sites
* ASP.NET: Disable ViewState
- Before you remove ViewState you should understand it. Here is a good start. Once you are sure you don't need it - EnableViewState="false" is your friend.
* Use the Cache-Control header to help the browser cache
- IIS allows you to set the
Cache-Controlheader via the UI. - I wrote a blog entry on how to do it a couple of weeks ago. Here is also a command-line script if using the UI is too cumbersome:
>appcmd set config "Default Web Site/scripts" /section:staticContent /clientCache.cacheControlMode:UseMaxAge /clientCache.cacheControlMaxAge:"365.00:00:00"
* In ASP.NET you can do it [programatically](http://quickstarts.asp.net/QuickStartv20/aspnet/doc/caching/output.aspx) via the Response.Cache object or you can do it declaratively via the [OutputCache Location="Client"](http://msdn.microsoft.com/en-us/library/hdxfb6cy.aspx) directive.
* Avoid Redirects.
- If you can't use permanent redirects (301's) instead of temporary redirects (302's).
* A redirect introduces another network round-trip. Avoid it. * Best described [here](http://developer.yahoo.com/performance/rules.html) or in Steve Souders [first book](http://www.stevesouders.com/hpws).
* Combine Javascript and CSS
* Same as row above.
* Strip unnecessary response headers
* They are sent out in every request. * In IIS it's easy to remove the X-Powered-By header via the UI. * The ETag header is not as easy unfortunately. "[Ultra-Fast ASP.NET](http://www.amazon.com/Ultra-Fast-ASP-NET-Build-Ultra-Scalable-Server/dp/1430223839)" has an example how to remove the ETag in managed code.
* Network: Reduce DNS Lookups
* DNS lookups introduce network roundtrips because the name has to be resolved and for that the browser needs to talk to a DNS server. * Sometimes it's a good idea to use another one or two DNS names however. For static content for example. Static content doesn't need all the other stuff you might need for dynamic content, e.g. cookies. Steve Souders has a whole chapter about this topic.
* Use authentication/SSL only when necessary
- Do you really need authentication or SSL for images or scripts? Are they really worth protecting? Authentication can introduce additional round-trips because sometimes a challenge response authentication dance is needed to authenticate successfully.
- Use the IIS7 bandwidth throttling module if your bandwidth is misused by somebody. Great example in “Ultra-Fast ASP.NET”. You can throttle the bandwidth of a response based on the user, system load or any other criteria. Probably worth considering if you don't have unlimited bandwidth, especially if you have media content. Remember: On average only 20% of a video is usually watched by a user before he moves on to something else. If you already downloaded the full movie in this time you wasted a whole lot of bandwidth.
* Review Cookies and their sizes
- Cookies can get pretty big.
- Cookies are sent with every request.
- So if the image has 50 images, it gets sent 50 times…
- Consider using the Cookie path feature if you can't reduce the size
* ASP.NET: Keep Master Pages lean
- Master Pages are part of every response. Don't bloat them.
* Careful with ETags on IIS 6.0
* Use lowercase to reference your resources
- Windows is not case-sensitive and it doesn't matter if you use lowercase, uppercase or a mix of both. The problem is the browser however. Because other OSs are case-sensitive the browser has to be case-sensitive as well. This means that it will cache multiple versions of a resource if you use different cases.
* Another issue: resources compress better if lowercase is used. Why? Because most letters are lowercase. Using a smaller set of characters will produce more dictionary matches and compression is more effective. I read this is in “Ultra-Fast ASP.NET”. Need to try this though!
#### References #### * http://bit.ly/wQCdr7 * 12titans.net * Ultra-Fast-ASP-NET