|
|
|
|
|
home > code > tutorials > Speeding Up ASP Page Execution |
|
Speeding Up ASP Page ExecutionASP pages are executed on the fly by a server when they are requested by a visitor. Because they are not compiled, ASP scripts are slow and hold up the processing of an html page. This results in people leaving your site and severely reduces the enjoyment that your asp apps can provide. So what can you do about it? There are a few things you can do to speed up an asp script. By speeding up, I mean decreasing the execution time of a script. These tricks will not speed up a database script that writes 10,000 entries to an html table. The reason that those scripts take so long is not necessarily related to the database trip and asp execution but to the rendering of html, especially tables, by a browser. All that said, these tricks will probably increase ASP performance even more if your site is really busy. So on we go... Disabling session state
You can increase the execution speed of your apps by disabling session state at the
top of any page that does not use any session objects. When you disable session state,
any session variables or methods are not available. In other words, a simple call
like But if you can figure out a way to live without the session, it's well worth the price. To disable session state you must make an @ declaration at the top of your page like this: <% @ EnableSessionState = False %> This line must be the first line of an asp page and encased in it's own asp script tags or you will get an error like: invalid @ directive and then all of your source code will be displayed below the error message. To do more than 1 @ declaration, like declaring a script language, you would put all the directives on the same line, the first line of the page, like this: <% @ Language = vbscript EnableSessionState = False %>Declaring Option Explicit You can combine disabling the session state with other options to really increase the execution time of an asp page. For example, declaring Option Explicit increases the speed of a page by not forcing asp to create a temporary instance of every variable when it is found during execution. Option Explicit will throw an error if you have not explicitly declared every variable that you used in your asp page by using the Dim statement. Using option explicit can also help you debug your code. The Option Explicit statement must be directly underneath the @ declarations or you will get an error. With option explicit, our fast asp page looks like this: <% @ Language = vbscript EnableSessionState = False %> <% Option Explicit ' some asp code %>Enabling the response buffer Another thing you can do is set the response buffer property to true. This speeds up the execution by not writing any html to the client's browser until the page has completely executed. The html is then transferred all at once instead of in small pieces during runtime. To enable buffering in our quick asp page, we add the response.buffer = true line below Option Explicit: <% @ Language = vbscript EnableSessionState = False %> <% Option Explicit Response.Buffer = True ' some asp code %>Don't switch ASP scripting engines in the same page Yeah, I know, this sucks but it's true. Sometimes you have to switch scripting engines in an ASP page - what i mean is: your @ Language declaration is vbscript and then all of a sudden, you need to call a sweet jscript object like the Browser object. So you build some <SCRIPT RUNAT=SERVER tags set to another language and do what you have to do... Well, when you do that, your really taxing ASP. Your making it do two separate compilations, combine the code and finally, execute the final code. It's at least two extra steps. If you find yourself doing the switch back and forth between JScript / VBScript / PerlScript, you might want to consider switching to the language used the most within the affected pages and just rewrite whatever code isn't that language on the page. Since ASP keeps pages independent of each other, it really doesn't matter if page1.asp is written in jscript, page2.asp is written in perlscript and page3.asp is written in vbscript. If you can live with that type of implementation, your pages will be faster than those that use more than one scripting engine on the same page. Avoid getting Response.WriteBlock to execute more than onceIf you've never heard about the Response.WriteBlock property, your not alone. It's a hidden property within the response object. What does it do? well, whenever you break up your <% %> tags to write html, you cause the compiler to call Response.WriteBlock. Consider this code: <HTML> <BODY> <% dim i for i = 0 to 10 %> <% = i%> <BR> <% next %> </BODY> </HTML> When the compiler gets a hold of this code, it has to render it by calling Response.WriteBlock over and over again. Once for each time you broke up the asp script delimiters. You can make this code faster by rewriting it as follows: <% response.write "<HTML>" response.write "<BODY>" dim i for i = 0 to 10 response.write i & "<BR>" next response.write "</BODY>" response.write "</HTML>" %> This code causes the compiler to only call Response.WriteBlock one time, saving cycles and memory and increasing the speed of the ASP code execution. Don't re-call functions and collections over and over again for the same valueThis is a common mistake programmers make. Consider this code which illustrates what NOT to do:
<%
if Len(Trim(Request.Form("item"))) > 0 then
sql = "INSERT INTO table1 (item) VALUES('" & Request.Form("item") & "')"
Response.write "you wrote : " & Request.Form("item")
end if
%>
Whats happened above is the Request.Form collection keeps getting called over and over again for the "item" input, yet the input's value hasn't changed. Whenever you call the Request.Form collection, it much search every name/value pair in the collection for a non-case sensitive match on the input name. This translates to cycles wasted and a slow down in the ASP app. A better way to write that code would be like this:
<%
Dim item
item = Request.Form("item")
if Len(Trim(item)) > 0 then
sql = "INSERT INTO table1 (item) VALUES('" & item & "')"
Response.write "you wrote : " & item
end if
%>
Now the collection has only been searched for that input one time. Effectively using this technique throughout your ASP pages will definitely speed up the page. Consider being very specific when using the Request collectionsFirst off, I'm going to say: "I don't use this rule" - but thats no reason not to talk about it. Unlike all the other rules above, this one is more of a judgement call based on the programmer, or more likely, the app your writing. If your familiar with my apps, you are totally used to seeing code like this:
<%
dim name
name = Request("name")
%>
The request object has five collections plus a default collection. A call to the default collection is what you are seeing above. The other collections are : Form, QueryString, ClientCertificates, ServerVariables and Cookies. Everyone is familiar with these collections. They are pretty much the most crutial tools available in the Request object - they allow you to gain access to the client's request information. When you do a call to the default Request collection, each of the sub collections are searched in the following order:
The process stops when the first match is found. If you're passing a lot of information between pages, using the default collection to get inputs can result in slow downs - especially if you're looking for servervariables that way. What I usually do is use the default collection if im looking for form or query string variables only - that provides a bonus because then the app works with both a GET and a POST request. But I always explicitly do Request.Cookies, ClientCertificates and ServerVariables when I need items from those collections. Only open a database connection one time per pageDatabase work takes cycles. When you work with SQL Server, you are making socket requests back and forth on port 1433/TCP. Sockets work is pricy but by far the most expensive part of the transaction is the actual connection to the resource in question - in this case, the database. Consider bad code like this which opens a database more than one time:
<%
dim c, r, id
set c = createobject("ADODB.Connection")
c.open "connstring"
set r = createobject("ADODB.recordset")
r.open "SELECT id FROM table1 ORDER BY id DESC", c
id = r.fields(0).value
r.close
set r = nothing
c.close
set c = nothing
set c = createobject("ADODB.Connection")
c.open "connstring"
c.execute "INSERT INTO table1 (id) VALUES(" & id + 1 & ")"
c.close
set c = nothing
%>
What you see above is code which gets a value out of a database and then creates a new row in the same database. This code makes the mistake of closing the database between sql executions. That code will be slower than it could be by rewriting it properly like this:
<%
dim c, r, id
set c = createobject("ADODB.Connection")
c.open "connstring"
set r = createobject("ADODB.recordset")
r.open "SELECT id FROM table1 ORDER BY id DESC", c
id = r.fields(0).value
r.close
set r = nothing
c.execute "INSERT INTO table1 (id) VALUES(" & id + 1 & ")"
c.close
set c = nothing
%>
The difference is, the database connection is only opened one time above, saving time. When used comprehensively on every page of a website, these guidelines can make your apps run as fast as possible in the ASP environment. |