Have you noticed that when ASP.NET web application is accessed for the first time the response is slow? The reason for such behavior is batch compilation that occurs on the first hit.
ASP.NET batch compilation is the process of compiling ASP.NET markup (content of aspx files) into temporary dll’s. Compilation requires invoking compiler (csc.exe for C#) – that is pretty heavy activity. Process Explorer shows it clearly:
ASP.NET batch compilation occurs on per folder basis. Said that, if your application divided into multiple sub-folders that contain ASP.NET pages each time any of the folders accessed for the first time the batch compilation is invoked.
Customer’s case study
Customer’s web application is built with ASP.NET 1.1. It is divided into multiple subfolders reflecting logical modules that are hosted across about 20 application pools. The application connects to Oracle database.
QA team complains that the application responds slowly each time any of the modules (subfolders) accessed for the first time.
Using Process Explorer and profiler we identified three main latency points:
- Creating the application pool – w3wp.exe.
- Batch compiling the application for each subfolder.
- Creating Oracle connection pool when Oracle is accessed for the first time.
We decided to create a Warmer – solution that will hit each subfolder’s page in unattended manner thus warming up the application before the first user hits it.
For the solution we used free tools from IIS resource kit:
- LogPrser.exe to identify the URL’s of the pages to hit.
- TinyGet.exe to actually hit the pages identified by LogParser.
To identify what pages to hit we took IIS log files from QA environment and than we ran the following query using LogParser:
LogParser.exe "SELECT DISTINCT STRCAT(‘XXX’, cs-uri-stem) AS cs-uri-stem-strcat INTO ‘C:\result.txt’ FROM ‘C:\yourIISlogFile.log’ WHERE INDEX_OF(cs-uri-stem, ‘aspx’) > 0" -o:w3c
Notice XXX – it has nothing to do with XXX rated content rather it is a placeholder to replace it with tinyget command.
Open resulting yourIISlogFile.log file in Notepad, hit Ctrl+H for “Replace” and replace all occurrences of XXX with the following command:
tinyget -srv:www.YourServer.com -uri:
yourIISlogFile.log before the Replace:
yourIISlogFile.log after the Replace:
Remove the header and save the file with BAT extension – your Warmer is ready for action. Run it each time you deploy new version.
Do not forget to remove old temporary files in ASP.NET temporary folder:
C:\Windows\Microsoft.NET\Framework\<<NET FX VERSION>>\Temporary ASP.NET Files\
CAUTION. This action may potentially corrupt your application if you do not provide proper exception handling. On one hand it is good check to make. on other hand – be aware of it and do not do it on production sites unless you are completely sure it will not corrupt the application.
- Don’t run production ASP.NET Applications with debug=”true” enabled
- ASP.NET Memory: If your application is in production… then why is debug=true
- Stress Test ASP.NET Web Application With Free WCAT Tool
- Free Performance Tool – Analyze IIS Logs Like A Pro With Funnel Web Analyzer
- Identify ASP.NET, Web Services, And WCF Performance Issues By Examining IIS Logs