ASP.NET MVC slow on host? - asp.net

I have uploaded my ASP.NET MVC(3) site to my host but it site is alot slower in first time load of all pages(even with no data fetch)?
First time I visiting startpage It takes 7.30 s, if I hit reaload after 1 min it will take 1.05 s, if I hit reaload repetly it will give me between 500 ms and 800 ms.
If I return after around 5 min and hit reaload I will get a 7 s load again?
If I run the same websight from my localhost(IIS7) I will get 1 s first time and then 650 ms for rapid reload.
The webpage is using database but its the same database in both cases (that is placed at my host).
The webpage is www.biss.se
Where should I begin to look?
Edit:
This is my Application_Start()
protected void Application_Start()
{
AccountModel accountModel = new AccountModel();
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
MappingHandler.RegisterMappings();
#region Register Extra DataNotations for Display Attribute
ModelMetadataProviders.Current = new DisplayMetaDataProvider();
#endregion
if (!accountModel.CheckIfAdminAccountExists("adminAccount"))
{
accountModel.CreateUser("adminAccount",
"Admin",
"Admin",
"",
"",
postCode: "",
locationId: "",
inactive: false,
siteRole: Controllers.SiteRoles.Admin,
activatedByUser: true);
}
}

When the first request hits an ASP.NET application, this application is loaded in memory by the web server by creating an AppDomain and the code inside Application_Start is executed. This process could take more or less time depending on the actions you are performing inside this event and the number of assemblies to be loaded. After a period of inactivity or if certain memory/CPU thresholds are reached IIS could recycle the application and unload it from memory. On the next request the same process repeats.
So basically what you should be looking for is the tasks you are performing inside your Application_Start event which is executed upon the first request. If those tasks involve I/O operations such as database access or stuff you could log the time it takes to perform them. This way you will be able to pinpoint the exact procedure of your code that take long time and be able to fix it if it depends on you, or contact your hosting provider if it is a problem on their side.
The MiniProfiler is a great tool for this profiling purpose.

You should look into your IIS settings.
IIS shuts down all sites witch was not hit by requests for a certain period of time.
So if there was no requests for a few minutes site ll be unloaded from memory and need
Thats the reason you have defferent behavior on local and remote machine.
Some times hosts block this settings for reason to low memory usage of clients on one virtual machine.
I cant recall the setting to be changed. Some one should give more certain answer.

Just had the same behavior with an ASP.MVC3 app running on IIS8 Windows2012 server.
If you are sure of what you are doing you can configure IIS to keep your app pool alive.
The solution can be found here on G+
The most important thing is to configure the idle time-out setting for the application pool.

If you go to Advanced Settings, Application Pool then you can see the Maximum Worker Processes property and set the value to 2, instead of 1.
I solved my problem in that way.

Related

ASP.NET Web Application Slowness

I have an asp.net web application running on an IIS 7.5/.NET Framework 4.0 server. Whenever I navigate to any webpage running on this server, it takes about 12 seconds to initially load. After that, navigation is quick (about 0.5 seconds, even on heavy hitting pages). If you leave it idle for two minutes, it slows again for the next request. I can tell that this is because the connection time-out is set to 120 seconds...I am guessing that after that limit, the site must reload everything when the next page is requesting. This site does call two different databases, however, default page should not do so and suffers the long initial load time. I have tried setting up Application Initialization for IIS 7.5, but noticed very marginal change at best after this was done. From what I've been reading, there seems to be very mixed success with this module in IIS 7.5. Is there any other means of circumventing this load time without having to rely solely on a high connection timeout value, since that would not resolve initial load time anyway?
When a WebApp is idle for along time IIS will close the application to save resources. This might have happened in your case.
Its also said that the application would turn off if the last user session timed out. I hope this article will guide you properly.
Look at what happens when the request gets to the runtime.
When ASP.NET receives the first request for any resource in an
application, a class named ApplicationManager creates an application
domain. (Application domains provide isolation between applications
for global variables, and allow each application to be unloaded
separately.)
Within an application domain, an instance of the class named Hosting
Environment is created, which provides access to information about
the application such as the name of the folder where the application
is stored.
After the application domain has been created and the Hosting
Environment object instantiated, ASP.NET creates and initializes
core objects such as HttpContext, HttpRequest, and HttpResponse.
After all core application objects have been initialized, the
application is started by creating an instance of the
HttpApplication class.
If the application has a Global.asax file, ASP.NET instead creates
an instance of the Global.asax class that is derived from the
HttpApplication class and uses the derived class to represent the
application.
See How it happens
Was not related the connection timeout as I thought it was, but rather another timeout and necessary files missing. Per Zerkey's question in the comments above, I got a little curious and looked around for ways to see what was loading, as debugging it from my PC was still slow, but considerably faster (about 4-6 seconds). In IIS on the server this is published to, I went to Worker Processes, selected the process and clicked current requests on the right. This showed me that it gets hung up on a 3rd party mobile redirection service I am using called 51degrees.mobi. It was taking about 10 of those 12 seconds for those file to load. What was happening is that the logging capabilities were set to log in an App_Data folder, and that directory was missing. It evidently wasn't giving me a visible error, it was just trying it and failing. Once I added this directory and log file, and reactivated Application Initialization, everything is quick.

Fixing slow initial load for IIS

IIS has an annoying feature for low traffic websites where it recycles unused worker processes, causing the first user to the site after some time to get an extremely long delay (30+ seconds).
I've been looking for a solution to the problem and I've found these potential solutions.
A. Use the Application Initialization plugin
B. Use Auto-Start with .NET 4
C. Disable the idle-timeout (under IIS Reset)
D. Precompile the site
I'm wondering which of these is preferred, and more importantly, why are there so many solutions to the same problem? (My guess is they aren't, and I'm just not understanding something correctly).
Edit
Performing C seems to be enough to keep my site warmed up, but I've discovered that the real root of my site's slowness has to do with Entity Framework, which I can't seem to figure out why it's going cold. See this question, which unfortunately hasn't been answered yet has been answered!
I eventually just had to make a warm up script to hit my site occasionally to make sure it stayed speedy.
Options A, B and D seem to be in the same category since they only influence the initial start time, they do warmup of the website like compilation and loading of libraries in memory.
Using C, setting the idle timeout, should be enough so that subsequent requests to the server are served fast (restarting the app pool takes quite some time - in the order of seconds).
As far as I know, the timeout exists to save memory that other websites running in parallel on that machine might need. The price being that one time slow load time.
Besides the fact that the app pool gets shutdown in case of user inactivity, the app pool will also recycle by default every 1740 minutes (29 hours).
From technet:
Internet Information Services (IIS) application pools can be
periodically recycled to avoid unstable states that can lead to
application crashes, hangs, or memory leaks.
As long as app pool recycling is left on, it should be enough.
But if you really want top notch performance for most components, you should also use something like the Application Initialization Module you mentioned.
Web Hosting Challenge
You have to remember that none of the machine configuration options are available if you are hosted on a shared server as many of us (smaller companies and individuals) are.
ASP.NET MVC Overhead
My site takes at least 30 seconds when it hasn't been hit in over 20 minutes (and the web app has been stopped). It is terrible.
Another Way to Test Performance
There's another way to test if it is your ASP.NET MVC start up or something else. Drop a normal HTML page on your site where you can hit it directly.
If the problem is related to ASP.NET MVC start up then the HTML page will render almost immediately even when the web app hasn't been started.
That's how I first recognized that the problem was in the ASP.NET MVC startup.
I loaded an HTML page at any time and it would load blazing fast. Then, after hitting that HTML page I'd hit one of my ASP.NET MVC URLs and I'd get the Chrome message "Waiting for raddev.us..."
Another Test With Helpful Script
After that I wrote a LINQPad (check out http://linqpad.net for more) script that would hit my web site every 8 minutes (less than the time for the app to unload -- which should be 20 minutes) and I let it run for hours.
While the script was running I hit my web site and every time my site came up blazingly fast. This gives me a good idea that most likely the slowness I was experiencing was because of ASP.NET MVC startup times.
Get LinqPad and you can run the following script -- just change the URL to your own and let it run and you can test this easily.
Good luck.
NOTE: In LinqPad you'll need to press F4 and add a reference to System.Net to add the library which will retrieve your page.
ALSO : make sure you change the String URL variable to point at a URL that will load a route from your ASP.NET MVC site so the engine will run.
System.Timers.Timer webKeepAlive = new System.Timers.Timer();
Int64 counter = 0;
void Main()
{
webKeepAlive.Interval = 5000;
webKeepAlive.Elapsed += WebKeepAlive_Elapsed;
webKeepAlive.Start();
}
private void WebKeepAlive_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
webKeepAlive.Stop();
try
{
// ONLY the first time it retrieves the content it will print the string
String finalHtml = GetWebContent();
if (counter < 1)
{
Console.WriteLine(finalHtml);
}
counter++;
}
finally
{
webKeepAlive.Interval = 480000; // every 8 minutes
webKeepAlive.Start();
}
}
public String GetWebContent()
{
try
{
String URL = "http://YOURURL.COM";
WebRequest request = WebRequest.Create(URL);
WebResponse response = request.GetResponse();
Stream data = response.GetResponseStream();
string html = String.Empty;
using (StreamReader sr = new StreamReader(data))
{
html = sr.ReadToEnd();
}
Console.WriteLine (String.Format("{0} : success",DateTime.Now));
return html;
}
catch (Exception ex)
{
Console.WriteLine (String.Format("{0} -- GetWebContent() : {1}",DateTime.Now,ex.Message));
return "fail";
}
}
Writing a ping service/script to hit your idle website is rather a best way to go because you will have a complete control. Other options that you have mentioned would be available if you have leased a dedicated hosting box.
In a shared hosting space, warmup scripts are the best first level defense (self help is the best help). Here is an article which shares an idea on how to do it from your own web application.
I'd use B because that in conjunction with worker process recycling means there'd only be a delay while it's recycling. This avoids the delay normally associated with initialization in response to the first request after idle. You also get to keep the benefits of recycling.
A good option to ping the site on a schedule is to use Microsoft Flow, which is free for up to 750 "runs" per month. It is very easy to create a Flow that hits your site every hour to keep it warm. You can even work around their limit of 750 by creating a single flow with delays separating multiple hits of your site.
https://flow.microsoft.com
See this article for tips on how to help performance issues. This includes both performance issues related to starting up, under the "cold start" section. Most of this will matter no matter what type of server you are using, locally or in production.
https://blogs.msdn.microsoft.com/b/mcsuksoldev/2011/01/19/common-performance-issues-on-asp-net-web-sites/
If the application deserializes anything from XML (and that includes web services…) make sure SGEN is run against all binaries involved in deseriaization and place the resulting DLLs in the Global Assembly Cache (GAC). This precompiles all the serialization objects used by the assemblies SGEN was run against and caches them in the resulting DLL. This can give huge time savings on the first deserialization (loading) of config files from disk and initial calls to web services.
http://msdn.microsoft.com/en-us/library/bk3w6240(VS.80).aspx
If any IIS servers do not have outgoing access to the internet, turn off Certificate Revocation List (CRL) checking for Authenticode binaries by adding generatePublisherEvidence=”false” into machine.config. Otherwise every worker processes can hang for over 20 seconds during start-up while it times out trying to connect to the internet to obtain a CRL list.
http://blogs.msdn.com/amolravande/archive/2008/07/20/startup-performance-disable-the-generatepublisherevidence-property.aspx
http://msdn.microsoft.com/en-us/library/bb629393.aspx
Consider using NGEN on all assemblies. However without careful use this doesn’t give much of a performance gain. This is because the base load addresses of all the binaries that are loaded by each process must be carefully set at build time to not overlap. If the binaries have to be rebased when they are loaded because of address clashes, almost all the performance gains of using NGEN will be lost.
http://msdn.microsoft.com/en-us/magazine/cc163610.aspx
I was getting a consistent 15 second delay on the first request after 4 minutes of inactivity. My problem was that my app was using Windows Integrated Authentication to SQL Server and the service profile was in a different domain than the server. This caused a cross-domain authentication from IIS to SQL upon app initialization - and this was the real source of my delay. I changed to using a SQL login instead of windows authentication. The delay was immediately gone. I still have all the app initialization settings in place to help improve performance but they may have not been needed at all in my case.

iis startup delay with aspx pages

Environment: Windows Server 2003; IIS 6, ASP.NET 2.0.50727
I'm going crazy with a brand new web server that we set up (note that this problem doesn't happen on our other web servers which have the same configuration). When loading and asp.net app the first time, the page hangs for over a full minute before showing the page in the browser. After it loads the first page, everything runs very quickly.
Note 1: You will probably say that the application is being compiled for the first time. But I've ruled that out. I put trace messages EVERYWHERE in the app and all the trace messages run within a second of requesting the page. Thus, the app compiles and runs immediately. But when the app is finished rendering the page and my last trace message is printed, nothing happens. IIS is doing something behind the scenes for a full minute before transferring the finished page along http to the user's browser.
Note 2: We found that after hitting the app the first time and things run fine, if we wait an hour then we get the delay again. Thus, IIS has something in its cache that it clears out after an hour and causes our site to stall again.
Note 3: Between each test we stop/start IIS to force it to hang upon loading the app.
Note 4: We watched the Task Manager to see if IIS was spiking and taking up a lot of resources processing something. But that wasn't it. We did see a very quick spike to 50% immediately before the browser showed the page, but for the previous 60 seconds there was only 1% usage on the server.
Note 5: On another test I created a HelloWorld.html page and this does not cause IIS to hang. Thus, it has something to do with calling the ASP.NET library the very first time it sends a rendered page across http. Also, since the app has already been compiled and runs instantly, it's just the part of asp.net that sends the rendered page to the user's browser that causes the delay.
Any ideas? We are a a loss here. All of our other web servers are setup the same way and work fine, but this is a new install. So there must be a configuration setting that was missed or maybe something needs to be installed?
Thanks,
Brian
If you have access to the servers, then make sure that app pool recycling is actually logged to the event logs
cscript adsutil.vbs get w3svc/AppPools/DefaultAppPool/LogEventOnRecycle
you can set it to log everything with
cscript adsutil.vbs Set w3svc/AppPools/DefaultAppPool/LogEventOnRecycle 255
See more here
Then check if there were any recycles.
App initialization, creation the worker process, threads, load the app domain and all the references dll's can take some time, that's normal, but that 1 minute delay is something else probably.
Try to precompile the app on the server and see if that helps
aspnet_compiler -m /LM/W3SVC/[site id ]/Root/[your appname]
If you want to dig deeper, you can check the event trace ETW.
logman query providers
Save the IIS /ASP.NET related Guids to a file like iisproviders.txt
logman start ExampleTrace -pf iisproviders.txt -ets -rt
reproduce
LogParser "SELECT * FROM ExampleTrace" -i:ETW
logman stop ExampleTrace -ets
You can find more hereTroubleshooting appdomain restarts and other issues with ETW tracing
I would also check the w3wp.exe with procexp if it has a TCP connection time out or with Procmon for other clues.
If you have experience with windbg, then you can make a request to the app then quickly attach the debugger to the process
windbg -p [process id of the app pool]
.loadby sos mscorwks
g
and take it from there. If there are exceptions, process crash, etc you should be able to catch it...
Once we had a weird server issue like this and a .NET reinstall solved the problem, still not sure what was the culprit.
Could be some aspnet.config settings on this box that are different from others. Have you tried copying over their config files to this server? There appears to be certificate options along with registry modifications that you can do to remove some lag time during the initial load of a page (precompiling aside)
See here and here
One thing you might want to check on is if there are any database access going on on your page load. That might be blocking the creation of the page during initial page load. Then when the query is cached (either by the db engine or another cache mechanism like memcached), subsequent page loads work as normal.
As per your last comment,
I could stop/start IIS multiple times and the app always ran instantly. I thought it was fixed for good. But now I just tried again (it has been sitting idle for the past couple of hours) and now it is back to hanging on the first request.
This could mean that the cache has expired and thus needs to hit the database once again, causing the delay in page load.

Show a "loading" message in Application_Start()

I have an MVC3 application that takes 30+ seconds for global.asax Application_Start() to execute. When a user hits the site for the first time after the App Pool was reset, the browser just sits there with a "waiting for website..." message.
Is there a way to show a "Loading data..." message/page to let the user know that everything is OK and to be patient?
No, there's no way to show any messages from Application_Start. IIS 7.5 has a cool AutoStart feature which allows you to preload your application in memory and thus avoid the long waiting. Another possibility is to have some external service that queries your site at regular intervals so that it doesn't get unloaded by IIS.
If you cannot use this feature, then you will have to reduce/optimize the amount of work you do in your Application_Start so that it doesn't take 30 seconds.
Not within the same .net application - you can't show anything from within Application_Start. You could create another small app as a landing page which polls for a response from your main app and then redirects once it gets one.
But a better solution would be to move some work out of Application_Start - can't you let the user arrive at your first page and then call an initialization method once they have landed?
You can't do that in that particularly way, as there is no response from the server, and for such, you can't do anything.
But how about to implement a heartbeat that will query any URL of your application avoiding it not to enter in stand mode?
an idea: Set an external service to query your application every 5 minutes:
RestSharp requests on momentapp's restful api

Why is calling a web service slower from a web page?

We have a DLL used as the middle layer between our website front end and our back end ticketing system. The method of insertion into the ticketing system is a bit complicated to explain, but the short version is that it's slow. The best case scenario I've gotten is a 9 second submission time.
The real problem though, is that I can only get that time through a Windows app, not through an ASP.NET web site. I've set up both a Windows test application and a web page for testing, and even though the code is copied between them the web page is consistently submitting in 17-20 seconds, while the windows app is getting 8-11 seconds.
What could be causing that?
EDIT: In response to a couple of the answers...
The call to the web service is taking the bulk of the time, but I have no control over this web service as it's provided by the ticketing system vendor. I need to find out why the web service is taking different amounts of time when it's being called form a different kind of application. The code is exactly the same in both cases, and it's running a loop then reporting the times recorded.
The code is:
for (int i = 0; i < numIterations; i++)
{
startTimes[i] = DateTime.Now;
try
{
cvNum = Clearview.Submit(req, DateTime.Now, DateTime.Now, false);
}
catch (Exception ex)
{
exceptionCount++;
lblResult.Text += #"<br />Exception Caught: " + ex.Message + #"<br />";
}
endTimes[i] = DateTime.Now;
}
It's the same loop in both cases, and I'm marking the time right before and after the call to the library, which does further processing and then calls the web service. But that processing should be consistent shouldn't it? I have traced during debugging and not seen any delay getting to the actual web service call...
EDIT Again: Working with Ants, in both cases 99.4% of the time is being sent just on the web service call. There appears to be no difference there... except that when timed out the web page is taking longer than the windows app.
Potentially the location of the web service in relation to the web server could be having an issue. Also, the page structure and other processing inside your web UI could be having an impact on how long it takes the application to process.
As mentioned logging items on both sides is a great idea, if that doesn't get you what you need, you might try a performance profiler such as Ants Profiler by Red Gate that can help identify the line, method, or class that is using the bulk of the time.
Are you running both on the same machine? Is the middle-layer that you are calling located on a remote machine? The time durations you mentioned vaguely feels like a DNS timeout issue, when opening a connection incurs the penalty for the first (down/misaddressed) DNS response to timeout. Are you sure that whatever config file/var pointing the DLL to the middle-layer are the same in both invocations?
I second the suggestion to use Wireshark to see what is going on. You can at least satisfy yourself that the backend processing time is (should be, anyways) the same...
Pepper your application on both sides with logs - that will show you where the time is going. If that doesn't help, use Wireshark to trace the network activity.

Resources