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

 

 

 

Creating local report using MS Reporting Services

Microsoft reporting services provide the way to represent data in the form of reports in easy manner. It’s a powerful tool, we can generate complex reports using it.   We can create reports by creating Server Reports Project in visual studio  and publish them to server. We can also create local report for ASP.NET using the same mechanism. Here i want to show you how can we achieve this.

Before going further check if your system got Reporting Services components installed. Create a Server Reports project (here i am using VS2005) by following the steps in this link. In this example i am assuming that your report consumes data returned from Stored Procedure and your SP takes some parameters. The report files created by this project will have .rdl extension and these files are XML files so you can easily change them using any notepad.

Now copy your final report file(.rdl) to ASP.NET application and change the file extension to .rdlc. Now open the report file using any text editor like notepad then remove the parameters tags if your reports requires any parameters.

How to remove parameter tags:

<ReportParameters></ReportParameters> and <QueryParameters></QueryParameters> section of the XML represents the parameters required by your report. So delete these tags and content inside these tags and save the file. Now your report is ready to use in your ASP.NET application.

Add report viewer control to your webpage. Below code shows, code required to use SSRS reports as local report.

Default.aspx:

<rsweb:ReportViewer ID="rptViewer" runat="server" Width="100%" ShowBackButton="false" ShowExportControls="true"
ShowFindControls="true" ShowPageNavigationControls="true" ShowRefreshButton="false" ShowPrintButton="false"
ShowParameterPrompts="false" ShowZoomControl="false" Visible="false">
<LocalReport>

</LocalReport>
</rsweb:ReportViewer>

Default.aspx.cs:

DataTable dt = GetReportData(param1);
String path = &quot;~/Reports/YourReport.rdlc&quot;;
BindDataToReport(dt, path);
private void BindDataToReport(DataTable reportDataTable,String reportPath)
{

    if (reportDataTable != null &amp;&amp; reportDataTable.Rows.Count &gt; 0)
    {
        rptViewer.Visible = true;
        rptViewer.LocalReport.ReportPath = string.Empty;
        ReportDataSource rptDataSource = new ReportDataSource(&quot;ReportDataSource&quot;, reportDataTable);
        rptViewer.LocalReport.DataSources.Clear();
        rptViewer.Reset();
        rptViewer.LocalReport.ReportPath = Server.MapPath(reportPath);
        rptViewer.LocalReport.DataSources.Add(rptDataSource);
        rptViewer.LocalReport.Refresh();
    }
    else
    {

       //else part here
    }
}

Note:

In the above example i created report using VS2005 and used it as local report in the project created by .NET3.5(VS2008) because the local reports in VS2010 uses SSRS 2008 schema while VS2008 uses SSRS 2005 schema. SSRS 2008 introduces tablix data region concept which is the combination of matrix,table and list. This is not available in SSRS 2005. So take care while using reports as local report.

I hope this post helpful to you. Happy coding Happy