HTTP Flushing in ASP.NET MVC – CourtesyFlush

Sometime back I was working on my project to improve the page load speeds. I was following the regular techniques to improve page speed like bundling and minifying statics content, placing them in proper places and loading content from CDN etc.

While doing these changes I came to know about HTTP Flushing. At that time I did not spend time to understand the uses of HTTP Flush. Recently in one of my projects I wanted to use it to check myself.

I found that Nik Molnar wrote about how to make use of HTTP Flushing in ASP.NET MVC. He also wrote a nuget package called CourtesyFlush and you can check the code here.

When the request hits the Action method and if takes more time ( like DB calls, expensive work) the browser waits until the complete page is ready.

If we flush the part of the page like <head> the browser start loading the content of head element meanwhile Action method completes its request and send the remaining page to the browser. This will improve the user perceived performance of the page.

Here I have created a sample MVC 5 website and added some delay in the “About” action method to mimic its taking time to process.

namespace WebApplication2.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult About()
        {
            // assume long running action here
            Thread.Sleep(2000);

            ViewBag.Message = "Your description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }
}

Check the page load time in dev tools network view. As you can see the scripts and css did not load until full page completed.

BeforeHTTPFlush

Let’s add CourtesyFlush nuget package and try the same page. To make this work you’ll want to move everything which you want flush out of _Layout.cshtml to a new file called _Head.cshtml.

public ActionResult About()
{
this.FlushHead();

	// assume long running action here
	Thread.Sleep(2000);

	ViewBag.Message = "Your application description page.";

	return View();
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>

We created a separate _Head partial view. Add this to the _Layout view.

@Html.FlushHead();
<body>

    @* code removed for bravity *@

    @RenderBody()

    @RenderSection("scripts", required: false)
</body>
</html>

Check the network view now. The content of the head section starts loading before page is ready.

BufferAfterHTTPFlush

 

 

 

Leave a comment