Schongar P.VBScript unleashed.1997
.pdf
Chapter 11
Optimizing Code
by Bill Schongar and Paul Lagasse
CONTENTS
Organizing Your Code
Chaos Theory 101
Code Behind the Scenes
Error Checking and Debugging
Use of Functions and Syntax
Variables Versus References
Data Types
ActiveX Controls
Quality, Not Quantity
Divide and Conquer
Development Tools
Still Using a Text Editor?
ActiveX Control Pad
Visual Basic to VBScript Converters
Future Integrated Development Environments?
Review
Let your VBScript code be the best it can be. No, you don't send it into the armed forces; instead, you send it to VBScript boot camp. Teach your code some discipline, make it work as part of a team, and turn out code that you can depend on to do the job you set it to, and do it right the first time. You're already starting out with good material; you just have to make it as suitable as possible for your needs.
Optimizing VBScript isn't a daunting task; it's just a combination of a dash of common sense, along with a hefty dose of what's best in your situation. Unlike its bigger cousins, Visual Basic and Visual Basic for Applications, VBScript doesn't have a lot of room for gray areas about what will make it faster, slower, or better. The subset of functionality limits the extent that you can "tweak" code, but it does present a couple of new things to consider.
This chapter takes a look at what kinds of things you can do to make your VBScript application run a little better and speed up your development cycle. This includes
Organizing your code
Use of functions and syntax
Development tools
If you're already a Visual Basic guru, much of the stuff you'll see here will be pretty familiar, and you might even have
your own special tricks you want to add in your own development. If you've never touched Visual Basic before, don't worry. Everything in this chapter is first and foremost aimed right at you, to give you the edge you need to make great, clean code.
Organizing Your Code
There's a lot to be said for being able to read your own writing, and the same holds true for code. HTML pages in and of themselves can often be a mess, and when you add source code for a program, it gets to be a little bit chaotic. That can either work for or against you, depending on what you have in mind.
Chaos Theory 101
One of the wonders of embedded scripting is that what you write is out there for everyone to see. All your functions, all your tricks, and all your work and source code are just one download away from just about everyone's view. Like a business interview, what you present in that first impression may give people an impression (accurate or not) of the quality of your code. If it sprawls all over the HTML source, they'll just be glad it works. If, on the other hand, the code is cleanly spaced out and thoroughly commented, it shows a sense of organization.
Keeping code orderly is an easy task as long as you start at the beginning. Record why you used particular functions, so that if you have to fix a problem or change the code later you'll be ready to make the changes without trying to decipher possibly cryptic entries. Don't go overboard, though! Remember that anything you type has to get downloaded by the end user, and they don't appreciate several hundred lines of comments taking up download time on every page.
Code Behind the Scenes
If you'd like to make folks work a little harder to see your source code or are just more organized by nature, there are options available to you. The most complex would be to roll all your VBScript code into an ActiveX control, and make people download it if they want to use your code. Since that kind of defeats the purpose of using VBScript in the first place and brings a whole new level of programming complexity into the mix, you'll probably want to avoid that route.
A much more efficient and convenient method is to take advantage of Microsoft's HTML Layout files (.ALX files). These are files that combine all the ActiveX control tags and assorted details so that they don't show up on the main page. This gives you two benefits: First and foremost, it gives you a separate file in which to organize the VBScript portion of your HTML file. If you're using repetitive code (on forms validation as an example), you may not want the same information cut and pasted into every HTML file. If you update the ALX file once, any HTML page that references it will automatically get the update.
To show what kind of difference this makes in readability, Listing 11.1 shows a small HTML page with VBScript embedded in it, while Listings 11.2 and 11.3 show the same HTML page with a Layout control object and its associated ALX files. The more complex the script, the better off you are removing it from the HTML page. Once you start using ActiveX controls, it's almost impossible to do much without going this route.
Listing 11.1. HTML and VBScript in one page.
<HTML>
<HEAD>
<TITLE>New Page</TITLE>
</HEAD>
<BODY>
<SCRIPT LANGUAGE="VBScript">
<!--
Dim Index
Dim Caption(5)
Caption(1) = "See the Caption has changed"
Caption(2) = "Of Course you could do a lot more"
Caption(3) = "With this type of control structure"
Caption(4) = "Like Moving the text across the screen"
Caption(5) = "And allow the user to set the speed"
Sub IeTimer1_Timer()
Index = Index + 1
If Index = 6 then Index = 1
IeLabel1.Caption = Caption(Index)
end sub
-->
</SCRIPT>
<OBJECT ID="IeTimer1" WIDTH=39 HEIGHT=39
CLASSID="CLSID:59CCB4A0-727D-11CF-AC36-00AA00A47DD2">
<PARAM NAME="_ExtentX" VALUE="1005">
<PARAM NAME="_ExtentY" VALUE="1005">
<PARAM NAME="Interval" VALUE="2000">
</OBJECT>
<OBJECT ID="IeLabel1" WIDTH=368 HEIGHT=27
CLASSID="CLSID:99B42120-6EC7-11CF-A6C7-00AA00A47DD2">
<PARAM NAME="_ExtentX" VALUE="9737">
<PARAM NAME="_ExtentY" VALUE="714">
<PARAM NAME="Caption" VALUE="This text will change at regular intervals">
<PARAM NAME="Angle" VALUE="0">
<PARAM NAME="Alignment" VALUE="4">
<PARAM NAME="Mode" VALUE="1">
<PARAM NAME="FillStyle" VALUE="0">
<PARAM NAME="FillStyle" VALUE="1">
<PARAM NAME="ForeColor" VALUE="#E8FD00">
<PARAM NAME="BackColor" VALUE="#000000">
<PARAM NAME="FontName" VALUE="Arial">
<PARAM NAME="FontSize" VALUE="12">
<PARAM NAME="FontItalic" VALUE="0">
<PARAM NAME="FontBold" VALUE="0">
<PARAM NAME="FontUnderline" VALUE="0">
<PARAM NAME="FontStrikeout" VALUE="0">
<PARAM NAME="TopPoints" VALUE="0">
<PARAM NAME="BotPoints" VALUE="0">
</OBJECT>
</BODY>
</HTML>
Listing 11.2. HTML page with the Layout control.
<HTML>
<HEAD>
<TITLE>New Page</TITLE>
</HEAD>
<BODY>
<OBJECT CLASSID="CLSID:812AE312-8B8E-11CF-93C8-00AA00C08FDF"
ID="sample2_ALX" STYLE="LEFT:0;TOP:0">
<PARAM NAME="ALXPATH" REF VALUE="file:J:\temp\sample2.ALX">
</OBJECT>
</BODY>
</HTML>
Listing 11.3. ALX file containing VBScript.
<SCRIPT LANGUAGE="VBScript">
<!--
dim Index
dim Caption(5)
Sub IeTimer1_Timer()
Index = Index + 1
If Index = 6 Then Index = 1
IeLabel1.Caption = Caption(Index)
end sub
-->
</SCRIPT>
<SCRIPT LANGUAGE="VBScript">
<!--
Sub Layout1_OnLoad()
Caption(1) = "See the Caption has changed"
Caption(2) = "Of Course you could do a lot more"
Caption(3) = "With this type of control structure"
Caption(4) = "Like Moving the text across the screen"
Caption(5) = "And allow the user to set the speed"
end sub
-->
</SCRIPT>
<DIV ID="Layout1" STYLE="LAYOUT:FIXED;WIDTH:389pt;HEIGHT:26pt;">
<OBJECT ID="IeLabel1"
CLASSID="CLSID:99B42120-6EC7-11CF-A6C7-00AA00A47DD2"
STYLE="TOP:0pt;LEFT:41pt;WIDTH:281pt;HEIGHT:17pt;
ZINDEX:0;">
<PARAM NAME="_ExtentX" VALUE="9922">
<PARAM NAME="_ExtentY" VALUE="609">
<PARAM NAME="Caption" VALUE="This text will change at regular intervals">
<PARAM NAME="Angle" VALUE="0">
<PARAM NAME="Alignment" VALUE="4">
<PARAM NAME="Mode" VALUE="0">
<PARAM NAME="FillStyle" VALUE="0">
<PARAM NAME="FillStyle" VALUE="0">
<PARAM NAME="ForeColor" VALUE="#E8FD00">
<PARAM NAME="BackColor" VALUE="#000000">
<PARAM NAME="FontName" VALUE="Arial">
<PARAM NAME="FontSize" VALUE="12">
<PARAM NAME="FontItalic" VALUE="0">
<PARAM NAME="FontBold" VALUE="0">
<PARAM NAME="FontUnderline" VALUE="0">
<PARAM NAME="FontStrikeout" VALUE="0">
<PARAM NAME="TopPoints" VALUE="0">
<PARAM NAME="BotPoints" VALUE="0">
</OBJECT>
<OBJECT ID="IeTimer1"
CLASSID="CLSID:59CCB4A0-727D-11CF-AC36-00AA00A47DD2"
STYLE="TOP:0pt;LEFT:8pt;WIDTH:25pt;HEIGHT:25pt;ZINDEX:1;">
<PARAM NAME="_ExtentX" VALUE="873">
<PARAM NAME="_ExtentY" VALUE="873">
<PARAM NAME="Interval" VALUE="2000">
</OBJECT>
</DIV>
Something to keep in mind, though, is that anytime you add a control to the page, you increase download time if the user doesn't have it on his system. When you add an ALX file, you also add the delay while that file is retrieved. If absolute performance is your goal, and you don't use any HTML Layout controls to add functionality to your script, you would be better off avoiding the use of ALX files to store your code. However, since the chances of the HTML Layout control being on a user's system are very high if they've ever visited another site, it's your call.
Error Checking and Debugging
One of the most effective pieces of optimization is to take a piece of code that doesn't run, and then fix it. Sound obvious? You'd be surprised how many people and how many pages put together functions or code, and then don't check
the whole thing, or don't check it after that one last "quick change." After all, it worked when it was tested the first time; what's going to stop it from working with that insignificant modification? Yep, you guessed it... practically anything.
The simplest test case for any VBScript application is to load it into whatever is supposed to run it, and see if any errors pop up. The great thing about Microsoft's VBScript runtime is that for safety's sake it's going to perform some checks on script validity before it does anything with the information it contains. So, in about the time it takes you to double-click the HTML file, you can find out if something's wrong. Most of the time this kind of spot-check is only going to spot very basic syntax errors, like missing a comment tag, or spelling a variable differently in a few places, but it's also the kind of stuff that a pair of tired eyes passes over far too easily.
There are a wide variety of error-checking and debugging steps you can take, which you can find explained in detail in Chapters 12, "Debugging," and 14, "Customize Your Web Page with Cookies." Once your code is error-free, then you'll be ready to tweak it to meet your needs.
Use of Functions and Syntax
If VBScript is a subset of Visual Basic for Applications (VBA), and VBA is a subset of the full Visual Basic package, it stands to reason that there just isn't as much that can possibly go wrong or need improvement when you're creating your code, right? Yes and no.
Being a subset of any language definitely means that lots of the problem-causing elements are missing, but it also leaves adventurous developers in search of a way to implement a function that just isn't there. The classic "just sit down and code around it" method may or may not work, depending on just what it is you're trying to sneak past the interpreter, but it may certainly make some tasks a lot harder than they might otherwise have been. What do come into play are many of the same tips and techniques that programmers have been availing themselves of in Visual Basic for a number of years now.
Variables Versus References
With so many ways to address informational components, such as the text in an HTML form element, you might not be too concerned about what methodology you use. You could directly reference the element through a unique name in a statement such as newtext = MyText1. Text, or you can use any combination of Form.Element.Property or Document.Form. Element.Property to recurse your way through different levels of naming. If you're going to be using that property several times, though, you're better off storing the data to a variable in memory, and then referencing that data in the form of a variable later. As an example, Listings 11.4 and 11.5 show two different ways of attacking the same use of data from a form's text input element (named Department) inside a form named UserForm1. While both snippets of code would work inside a real VBScript function, Listing 11.5 uses variables, and would end up being faster. Note that the code examples aren't complete working VBScript programs, just small parts of a larger application.
Listing 11.4. Using Document references instead of variables.
1:Sub Btn1_onClick
2:if (Document.UserForm1.Department.Text = Human Resources)
then
3:{
4:call HRValidate(Document.UserForm1.Department.Text)
5:}
6:if (Document.UserForm1.Department.Text = Engineering) then
7:{
8:call EngValidate(Document.UserForm1.Department.Text)
9:}
10:if ....
11:end sub
Listing 11.5. Using variables instead of Document references.
1:Sub Btn1_onClick
2:Dim dept = Document.UserForm1.Department.Text
3:if (dept = Human Resources) then
4:{
5:call HRValidate(dept)
6:}
7:if (dept = Engineering) then
8:{
9:call EngValidate(dept)
10:}
11:if ....
12:end sub
Besides making the code more readable, the use of the variable dept substituting for Document. UserForm1. Department.Text reduces the underlying number of recursive and repetitive object calls, significantly improving overall performance. This type of optimization is very important when dealing with looping structures like While...
Wend and For...Next loops. Storing the value of a property in a variable and then incrementing that value using a variable is much faster than retrieving data from the property each pass around the loop. One of the great things about objects is that they internally store all the functions that can be used to modify them. This code makes data corruption impossible because the object knows exactly what it wants. However, depending on the quality of the code, getting the text property of an object consecutively can take much longer than getting the property once and then maintaining it in a
variable. The extra layer of code that makes objects safe and secure can also make them much more cumbersome for fast operations.
Data Types
One of the most convenient reductions present in VBScript is that of the single data typethe variant. Instead of Diming strings and integers all over the place, VBScript considers all data to be more or less generic. When you begin to use outside functions, such as those in ActiveX controls, you can certainly continue to use the variant data type to pass information to controls, and then have them convert it, but it's often more efficient to use the built-in data conversion routines that VBScript provides, saving one more step. It is a good idea to use functions like Cint, CLng, and Csng and VarType to check the values that your variants contain. An even better way of keeping track of the types of variables you are using is to standardize your variable name declarations. Use a prefix that describes the data type in the name of the variable as you define, so that in the future you are able to easily identify the type of data you are referencing.
For example, if you want to store the state of a particular control property as a Boolean, you can define your storage variable as blnButtonState. The prefix that you use in the variable name will help you determine just what type of data you will expect to find inside. If you are trying to store currency information for a banking application in a variable, make sure that all of the variables dealing with funds are prefixed with cur. That is, CurTotal will hold the current total for a user's account with the currency data type. There is no hard and fast standard for this, so work out what works best for you.
ActiveX Controls
Optimizing ActiveX controls is roughly equivalent to trying to compress a brick. They're self-contained and precompiled, and you have only a certain amount of control about the way they handle things. What you do have control over is how you use them, both in quantity and functionality.
Quality, Not Quantity
Before you run out and place every ActiveX control ever made into the HTML on your page, consider the lowest common denominator for connection speeds and download times. If your Internet connection comes in the form of a T-1 line, a 200KB control is an insignificant amount of download time. If you're on ISDN or a dedicated 56.6KB line, controls around 100KB aren't excessive. If you're on a 28.8 modem, or stuck on a 14.4, file sizes start to become extremely important. Having recently downgraded from a T-1 line, we can tell you from experience that people on slow connections won't be too thrilled about waiting a minute or more just for text animation or a PowerPoint slide show.
The task you're faced with is minimizing the supporting files you need in order to get the functionality you want. This often involves a good deal of research, and a bit of design brainstorming. Do you take the chance that someone has a specific control, or is this page's primary duty speed of display and response? Do you embed an Excel spreadsheet, or do you convert the file into an HTML table? You have to make the decisions as to where a change is necessary for speed, and where such a change would detract from functionality and appearance. But sometimes you can make things easier on yourself.
If you look at some of the ActiveX controls out there, you'll notice that there are a variety of different ways of getting a particular task done. While a number of individual controls could be downloaded, the HTML Layout control contains a bunch of useful controls all bundled together. Although you might not need them all, you might need two or three of them, and it's more efficient to download the one CAB file and have it installed than it is to initiate multiple downloads and installations, as long as the single CAB file isn't more than about 30KB bigger than the individual controls.
The trick is to see where one control can serve multiple purposes, and where a control could be replaced with clever (but efficient) coding. Do you need an Image control, or can you get by with an animated GIF? Don't skimp on functionality, though. If you need control over an animated image, you need ActiveX controls to do it. If you have large sequences of
