ASP.NET can be used to create powerful and efficient web applications; however, there are times when users will experience a lag during the initial connection to the site. Even though subsequent page requests during the user’s session will be much faster, that initial lag will create a perception of sluggishness. This issue is due to ASP.NET dynamically compiling the site and loading it into the cache of the IIS application pool. The actual duration of the lag depends on many factors including the complexity of the site and the IIS configuration. There are many discussions online about ways to address this perceived problem which include 1) Precompilation prior to deployment 2) configuring IIS to hold on to the cache of compiled web applications longer and 3) using site warmup scripts. In this post, I will describe another option: the use of a site splash screen.
Precompilation is probably the most effective way to address this problem (that is if you are willing and able to go through the deployment configuration). Disabling the IIS application pool cache timeout may seem like a quick fix but it can lead to site stability problems (i.e. bad idea). The warmup script idea is actually a fairly simple and effective solution (particularly for sites with low traffic). Just make a simple script that requests a page from the site and use Windows Task Scheduler to run that script periodically during the day. However, there are times when this is still not enough (e.g. large sites with frequent changes to application logic). In this case, instead of increasing the frequency of the warmup script schedule (which would create unnecessary site traffic), I use a splash screen to let users know the site is loading. Using both warmup scripts and a splash screen may seem like a “belt with suspenders” type of solution but I think it actually fits in nicely into most ASP.NET site designs. As long as the splash screen does not appear unnecessarily (i.e. when the site is immediately available), it doesn’t hurt to put one in.
onload event and the user is redirected to the site’s home page.
Markup for a sample splash screen is provided below. The file is saved as
index.html so that the web server loads it by default before any other page (this configuration may vary on different servers so adjust it accordingly). Of course if the user bookmarks another page inside the site this splash screen will be bypassed (I am going to dodge that issue). The logic is self-explanatory but there are a few items to note. In most cases, the user will never see the splash screen because the re-direction will happen instantly. On rare occasions (e.g. a user with a slow PC, network lag, or high server load), the user may see a flicker. To avoid this, a 100ms delay was put in before the user sees the loading message. Using
setTimeout also gives us an opportunity to reset the loading animated gif to get around an Internet Explorer bug which stops the animation.
Now all that is left to do is use ASP.NET to generate a dynamic image (that’s the
Pulse.ashx file referenced in the markup above). An HTTP Handler is best suited for this task because it avoids the overhead of a full
.aspx page. We don’t want to create anything overly complicated or resource intensive so a 1 pixel image will suffice.
Imports System.Web Imports System.Drawing Public Class Pulse Implements IHttpHandler Public Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements IHttpHandler.ProcessRequest ' validate parameters If context Is Nothing Then Exit Sub ' create canvas Dim objBmp As New Bitmap(1, 1) Dim objGraphics As Graphics = Graphics.FromImage(objBmp) objGraphics.Clear(Color.Red) ' create the picture and output to client objGraphics.Flush() context.Response.ContentType = "image/jpeg" objBmp.Save(context.Response.OutputStream, Imaging.ImageFormat.Jpeg) context.Response.Flush() ' clean up objBmp.Dispose() objGraphics.Dispose() End Sub Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable Get Return False End Get End Property End Class