Back

Guest Blog Putting Code on a Diet

Read on to learn more...

By Guest Contributor | January 18, 2010
close up of a person's hand typing on a laptop

Share

  

Want to read this blog offline?

No worries, download the PDF version now and enjoy your reading later...

Download PDF

This is a guest post by Bruce Golub of Phosphor Media. The author’s views are entirely his or her own and may not reflect the views of Miva Merchant.

Broadband Internet access is now nearly universal in the US, and its adoption is reaching 70% on average. Europe is closing in on 50% with some areas virtually at 100%. So why should we care about saving a couple K-bytes here a couple of tens-of-a-second there?

Because there is never going to be a place place on the Internet for bloated and inefficient code. While the average Internet access speed has gone from 54 Kbs to 4.2 Mbs in 10 years, the average Internet user’s expectation has increased even more. Back when 56 Kbs was the norm, the average web visitor thought nothing of waiting up to 20 to 30 seconds for a page to load. Now, that expectation is less than 2 seconds. Even when a site is delivering content at sub 1 second speeds, studies have shown that reducing page load times by 10 to 20 percent have a significant positive impact on site visit duration and depth. (The time a visitor spends on the site; and the number of pages the visitor views.) On an e-commerce site, increased duration and page depth are usually directly proportional to sales conversions.

So, the question is, how do you make your site faster, even if its already fast? Continue on and we’ll cover some of the methods that lead to efficient coding and implementation of Miva Merchant storefronts. (Note, the coding we are referring to here is confined to Store Morph Technology, HTML and other browser based scripting such as Javascript.)

A Little Background

Lets take a look at the parts and processes of a Miva Merchant page and how those parts consume resources & time:

When a customer requests a page from Merchant:

  1. The server processes initial request and directs it to the MivaMerchant Empressa engine (what powers the Miva Merchant script). This generally takes very little time and the mechanisms controlling its efficiency are usually out of the hands of the store owner.
  2. The Miva Merchant script starts going through its logic to build an HTML page which is then passed back to the server. This logic includes processing the SMT logic in your Miva Merchant Templates. Here’s one of the places your efforts can greatly increase speed.
  3. The server sends a HTML page to the customer. The page of course, must travel through the Internet, then visitors ISP and back through the Internet to the visitor. Not much we can do here.
  4. The HTML page content arrives at the visitor’s computer and the browser reads (renders) the HTML in the page. As it reads the page, additional requests are made to the original server to fetch items such as images, style sheets, and linked scripts. Here we can also find opportunities to increase speed.

Determining Speed—Getting a Radar Gun

So, besides hitting reload and counting one Mississippi, two Mississippi, etc, how do you know how fast your page is loading? There are stop watches; but even those are going to be more dependent on reflexes than server and codes performance. One option is to use a bench mark tool such as a free feature in our Merchant FAST module. Two other alternatives that I know of are Emporiumplus.com’s Toolkit and PCINet.com’s Toolbelt. Any of these tools are great for monitoring the progress of your SMT and Template optimizing, but they don’t measure overall time (image loading, server transit time, and browser parsing). 

Organization, Optimization and Efficiency

There is a direct relationship between efficient code and well organized code; even if some organizational measures actually add to the code base. Being able to “see” the structure of code and content makes it easier to spot inefficiencies, errors, and other problems. So, lets start by getting organized:

Document Code

What? Doesn’t that ADD to the size of they resulting page? Why, yes it does. But page size isn’t as critical as other elements such as script calls to features and functions no longer used. For example, adding:

// Used to launch Bouncing Foo Ball feature

to an inline script such as:

<script language="JavaScript">
<!--
// Used to launch Bouncing Foo Ball feature
var this = 0;
var that = 0;
var whatever = 0;
etc;
// -->
</script>

Means that if the Bouncing Foo Ball feature is removed later on, you, the client or another developer can easily see that this code is superfluous and can be removed.

Different areas of your code require different commenting techniques

Example Use
<!—This is an HTML Comment—> HTML comments appear in the page template and in the source code of the resulting page, but don’t appear when viewing the page through the browser.
<mvt:comment>This is a SMT comment</mvt:comment> SMT Comments appear in the page template, but do not appear in the output of the resulting page.
// This is a Script comment Script comments can be used like HTML comments within script calls (i.e., between <script> and </script>) to document specific parts of a script. You can’t use HTML comments within a script tag because its already surround by HTML comments, and they can’t be nested. (i.e., <!—Comment <!—Comment—> within a Comment—> ).
/* CSS Comments */ Can be used to comment declarations within a CSS file. For example:/* Used for code examples */

 

.ex {background-color: yellow; border:1px solid black; margin: 0px 0px 12px 0px;}

Document Content

Similar to documenting code, documenting content makes it easy to spot redundancies,  keeps things in order and helps prevents incorrect layouts which can slow down page rendering.  Its also a great time saving when you are just beginning to learn how Miva Merchant puts together a page. It can prevent content abuses such as multiple doctypes, head, and body tags, and bloated layout code. If you are just starting out, go through at least the global items for your site (the tabs marked with an asterisk) and add an opening and closing comment.

For example, in the Global Header, add

<!—Global Header—>

as the first line and

<!—//Global Header—>

as the last line in that template. So, when you view your source code looking for layout issues, you can easily see what’s part of the global header, verses the pages other content.

For example, I often find stuff like the following in the output of a Miva Merchant page:


[ From the Global Header ]
<table><tr>
<td>Something Here</td>
<td>Or Another</td>
<td>Line of</td>
<td>Useless Text</td>
</tr><tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr></table>
[From the Page Content]
<table><tr>
<td>More Content</td>
<td>Are we done yet</td>
</tr></table>

When the following would suffice:

<!-- From Global Header -->
<table><tr>
<td>Something</td>
<td>Or Another</td>
<td>Line of</td>
<td>Useless Text</td>
</tr><tr>
<td colspan=4></td>
</tr>
<!-- //From Global Header -->
<!-- From page Content -->
<tr>
<td colspan=2>More Content</td>
<td colspan=2>Are we done yet</td>
</tr></table>
<!-- // From page Content -->

Not only fewer lines and perhaps easier to understand, but faster to render by the browser. Adding the HTML comments helps to see where the in-efficiencies are coming from, and how to correct them.

CSS Vs Table Based Layout

CSS (Cascading Style Sheets) are vastly superior to table-based layout from both an organizational, search engine friendliness and speed. The latest version of MivaMerchant will contain a template series based entirely on CSS Layout. While converting a Table based site to CSS is beyond the scope of this article, there are still some CSS based techniques you can apply to make even your Table based layout more efficient.

Setting the Table with CSS

There are some simple CSS techniques you can use with tables. These techniques can replace font calls, cell formatting, aligning, backgrounds and colors. Lets take a look at a few to get you started.

Fonts

Nothing says bloat like:

<table><tr><td><font size=1><font color=blue><font family=Arial, Helvetica, sans serif, MS Monster, BS Somefont><strong><font size=2>Text</font></strong></font></font></font></td></tr></table>

Especially when its repeated for every chunk of text in every table cell. Instead, a simple style class can handle all of that and more. For example: if you created a CSS class called mySpecialTable and assigned all the required font styling to it, you would just use:

<table class=mySpecialTable><tr><td>Text</td></tr></table>

CSS can also be used with tables to assign background colors, images, cellpadding, cellspacing, alignment and more. The W3C has some great CSS tutorials and references. For example, Starting with HTML + CSS and Adding a touch of style.

Learning these techniques, even with Table based layouts, can greatly reduce code clutter and size, and make your layout easier to read and understand. For example,

<table cellpadding=“12” cellspacing=“8” border=“1” width=“200” height=“100” align=“left” hspace=“20” vspace=“20” bgcolor=“red”>

Can be optimized by using a CSS class and subsequent definition:

Table declaration
<table class=“example”>

Class declaration

.example {
padding:12px;
border:1px solid black;
width:200px;
height:100px;
text-align:left;
background-color:red;
}

Byte for Byte they may be similar, but the advantage of using CSS for tables is two-fold. One, for each additional table that needs to look this way, you only use class=“example” to the template. And two, if you decide to change say the background color, you only need to do it in the style sheet, and not rummage through every page and every templates finding each place you used this style.

Substance and Style

Using CSS also makes it easier for non HTML savvy folks who might be working on your site to get the content in the right place as the class names can guide the way. For example,

<div class=“WelcomeMessage”> </div>

(and although it doesn’t validate in all cases, I’ve been using <div class=“name”></div class=“name”> to make it easier to see where a container begins and end.

Class Acts

Once you’ve gotten started using CSS, there are some more advanced methods to gain further optimization of size and also make the style tags more manageable. Thinking in terms of class groups really helps maintain your sanity, which results in fewer overall tags, thus less downloading. For example, you might have some styles like:


.class1 {this:that; the:other; and:still-more; more:ofthisstuff}
.class2 {this:that; the:other; and:still-more; none:ofthisstuff}
.class3 {this:that; the:other; and:still-more; someother:stuff}

If you created styles like this:


.class1 {this:that; the:other; and:still more; more:ofthisstuff}
.class2 {none:ofthisstuff}
.class3 { someother:stuff}

Then you would be able to recreate the three original styles with less overall code to manage. The class2 rule from the first set would be implemented as <div class=“class1 class2”>. The Third rule would be implemented as <div class=“class1 class2”>. Plus you would get two additional effects by combining class2 with class3, and class1 with class2 and class3.

(This actually doesn’t save as much load as it saves sanity…but when i started doing this, my rules dropped 50%…making for faster to downloads and easier updating.)

Hacking away at Store Morph Technology.

Now let's take a look at what we can do with SMT Coding—the stuff that makes your templates actually produce HTML and control content, features and appearance.

Remove SMT Items Not in Use

The original templates in MM assumed that everyone was going to use a specific set of features on each page of the site. In real life this is not the case. Removing items not in use can be the biggest “bang-for-the-buck” in speed increase. Tests we have done at PHOSPHOR Media show speed increases of 20% to 40% simply by going through each page and determining exactly what is needed for each page. Some items also consume more resources than others…so consider their impact before using them. For example, Inventory. While it's a great feature to have if you are trying to control inventory and give your customers an idea of what is available, turn it off if you are not using it. Also resist the urge to inventory to make some products unavailable for ordering if this is not an inventory issue. There are more efficient methods available.

Some items can be removed globally if not in use such as Inventory and Affiliate items…others should be done on a page by page basis as some pages will use a feature while others may not.

To globally remove an item:

  1. In the Merchant admin, open any page.
  2. Click the Items tab.
  3. Locate the Item in question and click its Edit button.
  4. On the Edit Item page click the Pages tab.
  5. In the Assigned column, click /- icon to select all pages.
  6. Click Update.

(You can also use this page to selectively remove items that are used on some pages, but not others. But be carefully.

To individually remove an item:

  1. In the Merchant admin, open any page.
  2. Click the Items tab.
  3. Locate the Item in question and uncheck its Assigned box.
  4. Click Update.

Note:  When removing items, you may see this warning: “Unassigning items permanently removes their template source from this page”. This message appears regardless of whether you actually have the item listed on the page in question. Double check to see if the item is listed. It wont matter, but you might as well make the template cleaner.

Optimize Your SMT Code

There are usually dozens of ways to write code that creates a particular effect. Some are more efficient—meaning that Miva Merchant engine has to work less to get the same result—than others, and others are just plain wrong. If in doubt, always ask the friendly folks on the Miva Merchant forums for confirmation and advice.

<mvt:if expr=“l.settings:product:price EQ 0.00 OR l.settings:product:price EQ 0.0 OR l.settings:product:price EQ 0”>
Some conditional text was here!
</mvt:if>

This is the actual code I once saw in someone’s template. If you don’t know why I am showing it here, then you should definitely be asking the forum for advice on your coding attempts<g>. You can also find a primer on using SMT in a blog by Tiny Queen.

Note: The answer to the above example is: since the product price is a numerical value, ‘0.00’, ‘0.0’, ‘000.0’, etc, all equal ‘0’ so simply using: <mvt:if expr=“l.settings:product:price EQ 0”> or even just <mvt:if expr=“l.settings:product:price”> will work just fine.

More Common Non-Optimal Code Examples:

Not using the least possible exclusion. For example:

<mvt:if expr=”’|’$g.screen$’|’” IN ‘|SFNT|INVC|BASK|OINF|OCST|ACAD|ACED|28 Page Declarations later|’”>

when you just want something to NOT to appear on the Product and Category Pages, which would be simplier and faster to write as:

<mvt:if expr=“NOT ‘|’$g.screen$’|’” IN ‘|PROD|CTGY’”>

Note:  if you where a real optimization freak, you would probably reverse CTGY and PROD as, when testing for ‘IN’ the test ends when the first match is found. Since most visitors hit category pages first, listing it first would be overall slightly faster…but by then, you’ll probably be debating the merits of coding in all lower case letters, and attending StarTrek conventions. Oh, speaking of which—lower case that is, not StarTrek—use IN verses CIN whenever possible. IN means match “this” IN “this string” while CIN means match “this” in “tHIS sTring” regardless of case.

Don’t Create Variables That Already Exist

The introduction of modules such as Tool Kit and Tool Belt allow store owners to create their own variables for use in conditional statements and display. Before creating one, make sure that variable doesn’t already exist. You can use tools such as our Merchant Detective module, or Latu’s Store Helper to see these variables.

Don’t Use Custom Fields and Conditionals for Static Formatting

Merchant 5’s Custom Fields feature along with conditional statements are great tools for extending the functionality of your storefont. Frequently, these features are miss-used to create what we call “static formatting.” Static formatting is anything that appears the same to different users. A common example is to create a product display which uses custom fields to show additional descriptive information such as dimensions, additional part numbers, application information etc. While we understand and applaud the desire to ensure consistency of information, it creates an unnecessary burden on your server. Instead, consider some other means of formatting the actual description field to be consistent from product to product.

Nirvana: Where SMT and CSS Meet

Compare these two code samples:

Table Based Category Product List

<mvt:foreach iterator="product" array="products">
<mvt:if expr = "(pos1 MOD 3 ) EQ 1">
<tr>
</mvt:if>
<td align="center" valign="bottom">
<mvt:if expr="NOT ISNULL l.settings:product:thumbnail">
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:product:code;"> <img src="&mvte:product:thumbnail;" border=0> </a>
<mvt:else>
&nbsp;
</mvt:if>
<br>
<mvt:item name="fonts" param="body_font">
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:product:code;"> &mvt:product:name;</u></a><br>
&mvt:product:formatted_price;
</mvt:item>
</td>
<mvt:if expr = "(pos1 MOD 3 ) EQ 0">
</tr><tr><td colspan=3>
<hr width="100%" color=#cccccc SIZE=1>
</td></tr>
</mvt:if>
</mvt:foreach>
<mvt:if expr = "((pos1 MOD 3 ) NE 0)">
<mvt:if expr = "((pos1 MOD 3 ) EQ 1)">
<td colspan="2">&nbsp;</td>
</tr>
</mvt:if>
<mvt:if expr = "((pos1 MOD 3 ) EQ 2)">
<td>&nbsp;</td>
</tr>
</mvt:if>
</mvt:if>

CSS Based Category Product List

<mvt:foreach iterator="product" array="products">
<div class="prodFl">
<div class="prodFlImage"><mvt:if expr="NOT ISNULL l.settings:product:thumbnail">
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:product:code;"> <img src="&mvte:product:thumbnail;" border=0> </a>
<mvt:else>
&nbsp;
</mvt:if>
</div>
<div class="prodFlText">
<a href="&mvt:global:sessionurl;Screen=PROD&Product_Code=&mvta:product:code;"> &mvt:product:name; </a><br>&mvt:product:formatted_price;         </div>
</div>
</div>
<mvt:if expr="(pos1 MOD 4) EQ 0"><div style="clear:both"> &nbsp; </div></mvt:if>
</mvt:foreach>

Which one would you think is faster and easier to maintain? This method relies on powerful CSS feature called “float”. Basically, it says display this first item (DIV), then show the next item as long as it fits, along side the first. The line, <mvt:if expr=”(pos1 MOD 4) EQ 0”><div style=“clear:both”> &nbsp; </div></mvt:if>, controls how columns are shown (provided you have the space) or you can let the items float based on available width and let the visitor choose how many across they want to see.

Get Code Out of Your Code

If you use javascript functions or inline style tags, reference external files (link) rather than calling the functions directly into your template (inline). Linked files, like images are saved locally to the user’s computer so that their content is downloaded once.

There is a slight disadvantage to calling scripts and external CSS files. Each time such a file is called, an additional HTTP (server request) has to be made which does take time. However, this is offset by the fact that once that file is called its is saved locally. So on the second page, not only is the HTTP request bypassed, but the content of the script or CSS file doesn’t need to be transmitted.

Also, if a script is only used on one or several pages, you might get some speed benefit (and cleaner output) by wrapping the code or reference in a conditional. For example, if a script ONLY runs on the invoice screen, you could use:

<mvt:if expr="g.screen EQ 'INVC'">
<script type="text/javascript" src="/scripts/this_file.js"></script>
</mvt:if>

If there are several screens that need the script, you can use:

<mvt:if expr="'|'$g.screen$'|'" IN '|SFNT|INVC|BASK|etc|'">
<script type="text/javascript" src="/scripts/this_file.js"></script>
</mvt:if>

Group Your Scripts

You only need one “script group”. Gather all the scripts that can should be in the head area and place them in one group.
If your source code looks like this:

<script>
<!--
function Here() {
do=dont;
will=wont;
bill=kill;
}
//-->
</script>
<script>
<!--
function There() {
if (I.repeat.myself)
blame.reload()
else
congradulations()
}
//-->
</script>

Make it look like this:

<script>
<!--
function Here() {
do=dont;
will=wont;
bill=kill;
}
function There() {
if (I.repeat.myself)
blame.reload()
else
congradulations()
}
//-->
</script>

Reduce Offsite Script Calls

Linking to a JavaScript or similar script file outside of your domain not only slows page load, but can also completely block the loading of the page. For example, if the remote server is unavailable, not only will those features also be unavailable, but the entire page may refuse to load. So whenever possible, copy scripts to your web site and link to them there.  If you can’t download the script, for example, social media tags, Google analytic scripts, etc, at least place the link at the BOTTOM of the page (right after the </body> tag). This will allow most of the page content to load before the script is called, if the script is unavailable.

Note: Obviously, this doesn’t work for scripts that generate content used within the body of the page. For example, script that actually CREATES a button, rather than just control the action when a button is selected.)

Put Stuff in the right place

Ok, while this won’t really make that much difference in site performance…it will make your life easier so you can spend more time performing the other optimization tricks in this article. Don’t put content that appears on every page…on EVERY PAGE; put it in a global container. The most common example is using the global header and global footer. For example, your site’s Mast head (main graphic and branding) should be in the global header.

One thing that most folks new to Miva Merchant don’t realize even though its right in front of them, is that you can include SMT items inside of SMT items. Eh? Well, the standard page template starts out with:

<mvt:item name="html_profile" />
<head>
<title>&mvt:store:name;: &mvt:category:name;</title>
<base href="&mvt:global:basehref;">
<mvt:item name="prodctgy_meta" param="ctgy" />
<mvt:item name="head" param="head_tag" />
</head>
<mvt:item name="body">
<mvt:item name="hdft" param="global_header" />
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr><td align="left" valign="bottom" colspan=2 >
<mvt:item name="navbar" />
</td></tr>
etc  ...

but you could place the navbar item inside the global header and have this:

<mvt:item name="html_profile" />
<head>
<title>&mvt:store:name;: &mvt:category:name;</title>
<base href="&mvt:global:basehref;">
<mvt:item name="prodctgy_meta" param="ctgy" />
<mvt:item name="head" param="head_tag" />
</head>
<mvt:item name="body">
<mvt:item name="hdft" param="global_header" />
<tr><td align="left" valign="bottom">
<mvt:item name="hdft" param="header" />
</td></tr>
etc…

Note: you can’t add an item that requires an </mvt:if> closing tag. That is, you can only add items that end with /> unless you include BOTH the opening and closing tag.

Why should you do this? Let's say your design requires a lot of HTML surrounding the navbar to get it to fit into your design. Suddenly, you (or your client) decides to make a change—even a minor one. If you had the code in the Global Header, you have only one template to change; not the 28 standard page templates. Again, this is just something to get you thinking. For example, most of our page templates look like this:


<mvt:item name="html_profile" />
<mvt:item name="head" param="head_tag" />
<mvt:item name="hdft" param="global_header" />

<mvt:item name="some_page_specific_item " />

<mvt:item name="hdft" param="global_footer" />

Everything else is coded into items within these five items. We find that this makes site updates faster and easier as a global layout changes usually requires editing a single item. Again, not for everyone—it requires a few SMT coding tricks for things like category tree swapping and page titling—but the concept can be very useful.

Image is Everything

Images can account for 80 percent or more of a web pages load or speed. The overall byte size of images usually dwarfs the size of html, scripting and text contents…so pay attention. Most sites we encounter contain JPGs that are uncompressed. Or GIF files that should be Jpegs and visa-versa. While there are many great sites on image optimization, let me point out a few things specific to Miva Merchant that might not be obvious.

Since an image is downloaded only once per customer, it makes more sense to focus more on PRODUCT and Category images than overall web design graphics.

A 120×120 Thumbnail isn’t going to show much detail…so don’t bother going light on the compression. Besides. It's going to load with dozens or maybe multiple dozens of images. Thumbnails should be the gateway to the product detail page.

Use a largest format, higher quality popup image on the product page. The standard product page can then be made smaller with greater compression. Once the customer is assured that they found the right product, the pop-up image can give them all the details they need…if its not quite the right product, then the customer hasn’t wasted a lot of time waiting for that large format image to download. We usually recommend 120X120 thumbnails, 300×300 product images and 600/700 pixel pop-up images.

If you have thousands of products, consider organizing them in sub directories according to type and category. (Note, because you can have products in multiple categories, use neutral ones. Remember, this is for you…not your customer. For example, though those Nike running shoes may be listed on the site under Men’s Shoes, Athletic AND Sports, Running Men’s, you may want them under /products/Nike/running/thumb and /products/Nike/running/fullsize.

(Yes, I know. You can’t use the upload feature in the admin, but who is going to do that with thousands of images.)

Parting Thoughts

There are literally thousands of ways to increase code efficiency…some are pretty obscure and result in shaving off thousands of seconds, others depend, as stated previously, on the nature of your site. Suffice to say, we’ll be posting more ideas here in the futures, and we hope you post others as well in the comment section.

Back to top

Author's Bio

Guest Contributor

The Miva ecommerce platform powers some of the web’s most spectacular online stores—stores that benefit every day from our relationships with our partners and other valued providers. We work with our network of experts to create fresh, insightful content for all independent merchants. Interested in contributing to the Miva blog? Click below to learn more about our co-marketing opportunities.

More Posts Like This

Stay in the Loop

Sign up to receive the latest in ecommerce news, articles, whitepapers, and more.

OR CALL 800.608.MIVA

  • Facebook icon
  • Twitter icon
  • Instagram icon
  • LinkedIn icon