Search This Blog

Monday, July 31, 2006

ASP Tips: Tip 10: Use Response Buffering

You can buffer a whole page worth of output by turning on "response buffering." This minimizes the amount of writes to the browser and thus improves overall performance. Each write has a lot of overhead (both in IIS and in the amount of data sent down the wire), so the fewer the writes there are, the better. TCP/IP works much more efficiently when it can send a few large blocks of data than when it has to send many small blocks because of its slow start and Nagling algorithms (used to minimize network congestion).

There are two ways of turning response buffering on. First, you can turn on response buffering for an entire application, using the Internet Services Manager. This is the recommended approach and response buffering is turned on by default for new ASP applications in IIS 4.0 and IIS 5.0. Second, on a page-by-page basis, you can enable response buffering by placing the following line of code near the top of the ASP page:

<% Response.Buffer = True %>

This line of code must be executed before any response data has been written to the browser (that is, before any HTML appears in the ASP script and before any Cookies have been set using the Response.Cookies collection). In general, it is best to turn response buffering on for an entire Application. This allows you to avoid the above line of code on every page.


One common complaint about response buffering is that users perceive ASP pages as being less responsive (even though the overall response time is improved) because they have to wait for the entire page to be generated before they start to see anything. For long-running pages, you can turn response buffering off by setting Response.Buffer = False. However, a better strategy is to utilize the Response.Flush method. This method flushes all HTML that has been painted by ASP to the browser. For example, after painting 100 rows of a 1,000-row table, ASP can call Response.Flush to force the painted results to the browser; this allows the user to see the first 100 rows before the remaining rows are ready. This technique can give you the best of both worlds-response buffering combined with the gradual presentation of data to the browser.

(Note that in the above example of a 1,000-row table, many browsers won't start painting the table until they see the closing </table> tag. Check your targeted browsers for support. To get around this, try breaking the table into multiple tables with less rows, and call Response.Flush after each table. Newer versions of Internet Explorer will paint tables before they are fully downloaded, and will paint especially fast if you specify the table's column widths; this avoids forcing Internet Explorer to calculate the column widths by measuring the width of the contents of every cell.)

The other common complaint about response buffering is that it can use a lot of server memory when generating very large pages. Leaving aside the wisdom of generating large pages, this problem can also be addressed with judicious use of Response.Flush.

No comments: