在服务器上生成动态内容是使用asp最主要的原因之一,所以我们选择的第一个测试项目是确定把动态内容发送到应答流使用什么方法最好。基本的选择有两种(以及它们的一些变化):使用内嵌asp标记,使用response.write语句。
为测试这些不同的方法,我们创建了一个简单的asp页面,页面先定义一些变量然后把它们插入到表格。虽然这个页面很简单,而且没有实际用途,但它足以让我们分离和测试各个问题。
2.1 使用asp内嵌标记
第一个测试是使用asp的内嵌标记< %= x % >,其中x是一个变量。这是使用最方便的方法,而且它可以让页面的html部分变得更容易阅读和维护。
< % option explicit
dim firstname
dim lastname
dim middleinitial
dim address
dim city
dim state
dim phonenumber
dim faxnumber
dim email
dim birthdate
firstname = "john"
middleinitial = "q"
lastname = "public"
address = "100 main street"
city = "new york"
state = "ny"
phonenumber = "1-212-555-1234"
faxnumber = "1-212-555-1234"
email = "john@public.com"
birthdate = "1/1/1950"
% >
< html >
< head >
< title >response test< / title >
< /head >
< body >
< h1 >response test< /h1 >
< table >
< tr >< td >< b >first name:< /b >< /td >< td >< %= firstname % >< /td >< /tr >
< tr >< td >< b >middle initial:< /b >< /td >< td >< %= middleinitial % >< /td >< /tr >
< tr >< td >< b >last name:< /b >< /td >< td >< %= lastname % >< /td >< /tr >
< tr >< td >< b >address:< /b >< /td >< td >< %= address % >< /td >< /tr >
< tr >< td >< b >city:< /b >< /td >< td >< %= city % >< /td >< /tr >
< tr >< td >< b >state:< /b >< /td >< td >< %= state % >< /td >< /tr >
< tr >< td >< b >phone number:< /b >< /td >< td >< %= phonenumber % >< /td >< /tr >
< tr >< td >< b >fax number:< /b >< /td >< td >< %= faxnumber % >< /td >< /tr >
< tr >< td >< b >email:< /b >< /td >< td >< %= email % >< /td >< /tr >
< tr >< td >< b >birth date:< /b >< /td >< td >< %= birthdate % >< /td >< /tr >
< /table >
< /body >
< /html >
/app1/response1.asp的完整代码
最好记录 = 8.28 毫秒/页
2.2 使用response.write输出每一行html代码
许多优秀的文献指出,应当避免使用前面的内嵌标记方法,因为它导致一个称为“上下文切换”的操作。这个操作发生在web服务器所处理的代码类型发生变化的时候(从纯html的发送到脚本处理,或反过来),这种切换需要一定的时间。许多程序员在了解了这一点之后,他们的第一个反应是将每一行html代码都用response.write函数来输出:
…
response.write("< html >")
response.write("< head >")
response.write(" < title >response test< /title >")
response.write("< /head >")
response.write("< body >")
response.write("< h1 >response test< /h1 >")
response.write("< table >")
response.write("< tr >< td >< b >first name:< /b >< /td >< td >" & firstname & "< /td >< /tr >")
response.write("< tr >< td >< b >middle initial:< /b >< /td >< td >" & middleinitial & "< /td >< /tr >")
…
/app1/response2.asp片断
最好记录 = 8.28 毫秒/页
响应时间 = 8.08 毫秒/页
差 额 = -0.20 毫秒 (减少 2.4%)
和内嵌标记版本相比,我们所看到的性能改善非常小,简直令人惊讶。这或许是因为页面中多出了许多函数调用。不过这种方法还有一个更大的缺点,由于html代码嵌入到了函数内,脚本代码变得非常冗长,阅读和维护都不方便。
2.3 使用封装函数
response.write并不会在文本行的末尾加上crlf(carriage return – line feed,回车换行),这是使用上面这种方法最令人失望的地方。尽管已经在服务器端把html代码作了很好的格式化,但在浏览器中看到的仍旧只有长长的一行代码。不过失望的不仅是这一个问题,人们很快就发现不存在能够自动添加crlf的response.writeln函数。一个很自然的反应就是创建response.write的封装函数,在每行的后面加上crlf:
…
writecr("< tr >< td >< b >first name:< /b >< /td >< td >" & firstname & "< /td >< /tr >")
…
sub writecr(str)
response.write(str & vbcrlf)
end sub
/app1/response4.asp片断
最好记录 = 8.08 毫秒/页
响应时间 = 10.11 毫秒/页
差 额 = +2.03 毫秒 (增加 25.1%)
结果是性能的大大下降。当然,这主要是因为这种方法使得函数的调用次数加倍,它对性能的影响非常明显。应当不惜代价地避免这种用法,crlf导致每行的末尾多了两个字节,而这两个字节对于浏览器显示页面是没有用的。在大多数情况下,浏览器端html代码的格式美观只是方便了你的竞争者阅读和理解页面的设计。
2.4 合并多个response.write
如果不考虑最后一次有关封装函数的测试,下一个合理的步骤应当是将所有字符串从分开的response.write语句合并到一个语句,从而减少函数调用次数、提高代码运行效率。
…
response.write("< html >" & _
"< head >" & _
"< title >response test< /title >" & _
"< /head >" & _
"< body >" & _
"< h1 >response test< /h1 >" & _
"< table >" & _
"< tr >< td >< b >first name:< /b >< /td >< td >" & firstname & "< /td >< /tr >" & _
…
"< tr >< td >< b >birth date:< /b >< /td >< td >" & birthdate & "< /td >< /tr >" & _
"< /table >" & _
"< /body >" & _
"< /html >")
/app1/response3.asp片断
最好记录 = 8.08 毫秒/页
响应时间 = 7.05 毫秒/页
差 额 = -1.03 毫秒 (减少 12.7%)
这是目前为止最好的方法。
2.5 合并多个response.write,且在每一行的末尾增加crlf
也有人非常关注他们的html代码在浏览器端是否美观,因此我们又在每一行html代码的末尾加上了一个回车,使用的是vbcrlf常量,其他的测试代码与上例一样。
…
response.write("< html >" & vbcrlf & _
"< head >" & vbcrlf & _
" < title >response test< /title >" & vbcrlf & _
"< /head >" & vbcrlf & _
…
/app1/response5.asp片断
最好记录 = 7.05 毫秒/页
响应时间 = 7.63 毫秒/页
差 额 = +0.58 毫秒 (增加 8.5%)
结果是性能略有下降,这可能是因为增加了字符串连接操作,同时输出的文本也增加了。
2.6 意见
根据上述asp输出测试的结果,我们得出如下编码规则:
避免过多地使用内嵌asp。
把尽可能多的response.write语句合并成单个语句。
绝对不要为了加上crlf而封装response.write。
如果要格式化html输出,直接在response.write语句后面加上crlf。
