Azure Web App (ASP.NET MVC) becomes cold every ten minutes and takes +10-20s to load
I have a couple of possible answers.
Entity framework code-first/database initialization: If you are using code first setup with migrations and possibly seed data, each of these things can cause some "warmup" issues.
Specially if you are not initializing the database on app startup, that would mean that the first time you hit your database is when it gets initialized.
Entity framwork version: Entity framework itself has also had a lot of performance improvements in 5 and 6.x some of these also have to do with both cold and warm startup speeds.
Views aren't precompiled: If you are getting slow loads on pages (like after deployment) every first hit of a new page (view), and then subsequent loads are fine. This can be because pages aren't compiled, i can elaborate on that if thats the case.
Recycle It sounds like you are experiencing these issues when the application recycles, and it isn't auto initializing (which is why you get that cold hit) the worst performance issues i have seen with these things are usually entity framework and precompile related. But both can be easily fixed. But ensuring the app is "always running" and self initializes after recycle also ensures that no users get this cold hit.
UPDATE: Since it was view related i can offer a solution i have found very useful. Installing RazorGenerator.Mvc Nuget package. And adding this Engine as the first engine will ensure you use compiled views.
In App_Start
you could create a file called RazorGeneratorMvcStart.cs
with content like this:
using RazorGenerator.Mvc;
[assembly: WebActivatorEx.PostApplicationStartMethod(typeof(MyNamespace.RazorGeneratorMvcStart), "Start")]
namespace MyNamespace {
public static class RazorGeneratorMvcStart {
public static void Start() {
ViewEngines.Engines.Insert(0, new PrecompiledMvcEngine(typeof(RazorGeneratorMvcStart).Assembly));
VirtualPathFactoryManager.RegisterVirtualPathFactory(engine);
}
}
}
The razor engine can even take a parameter for UsePhysicalViewsIfNewer
for those that like replacing a view live. In that case it uses the precompiled version, unless a view with a newer date than the compiled .dll has been placed in the folder.
This approach should solve performance issues with views.
A few ideas:
On your Web App blade, go to the Diagnose and solve problems menu. Then click on performance counters. I'd honestly fish through every one of the available perf counters, paying attention to the timeline vs your degraded performance. I once found out that SignalR was choking out my server due to runaway connections by looking at Thread Count.
Is the server errors log in Application Insights clean?
Under the Diagnose and Solve Problems screen, do you see anything suspicious in the Failed Request Tracing Logs?
- Separate out anything from deployment vs local. If the application is running perfect in local environment, then something different is happening when it goes to Azure. Resolving something is taking lot of time.
- Any static resource (script, styles etc) do get auto cached by browser on 1st request, so on subsequent request, the issue should not come.
- Since you know that "Render" method is giving the problem, looks like a complex nesting computation and browser DOM manipulation is happening. However if this is not a challenge when on local, then check if rendering calls for outside resources and they getting blocking calls (may need heavy use of ajax or server side async calls, although I assume you would already have that in place.)
- Possible refactoring may be required (to have smaller stacks and possible use of threading/non-blocking IO), however require to see your code to suggest on that.
Share your page load event and any subsequent calls made by it. Also how's the view is rendered along with any DOM handling.