Posts Tagged ‘JavaScript’

January 10, 2012

Web Development – HTML5 – Custom Data Attributes

By in Development, SoftLayer, Technology, Tips and Tricks

I recently worked on a project that involved creating promotion codes for our clients. I wanted to make this tool as simple as possible to use and because this involved dealing with thousands of our products in dozens of categories with custom pricing for each of these products, I had to find a generic way to deal with client-side form validation. I didn’t want to write custom JavaScript functions for each of the required inputs, so I decided to use custom data attributes.

Last month, we started a series focusing on web development tips and tricks with a post about JavaScript optimization. In this installment, we’re cover how to use HTML5 custom data attributes to assist you in validating forms.

Custom data attributes for elements are “[attributes] in no namespace whose name starts with the string ‘data-’, has at least one character after the hyphen, is XML-compatible, and contains no characters in the range U+0041 to U+005A (LATIN CAPITAL LETTER A to LATIN CAPITAL LETTER Z).” Thanks W3C. That definition is bookish, so let’s break it down and look at some examples.

Valid:

<div data-name="Philip">Mr. Thompson is an okay guy.</div>
<a href="softlayer.com" data-company-name="SoftLayer" data-company-state="TX">SoftLayer</a>
<li data-color="blue">Smurfs</li>

Invalid:

// This attribute is not prefixed with 'data-'
    <h2 database-id="244">Food</h2>
 
// These 2 attributes contain capital letters in the attribute names
    <p data-firstName="Ashley" data-lastName="Thompson">...</p>
 
// This attribute does not have any valid characters following 'data-'
    <img src="/images/pizza.png" data-="Sausage" />

Now that you know what custom data attributes are, why would we use them? Custom attributes allow us to relate specific information to particular elements. This information is hidden to the end user, so we don’t have to worry about the data cluttering screen space and we don’t have to create separate hidden elements whose purpose is to hold custom data (which is just bad practice). This data can be used by a JavaScript programmer to many different ends. Among the most common use cases are to manipulate elements, provide custom styles (using CSS) and perform form validation. In this post, we’ll focus on form validation.

Click through for a detailed, step-by-step example. »

December 12, 2011

Web Development – JavaScript Optimization

By in Development, SoftLayer, Technology, Tips and Tricks

So you have a fast website. You’ve optimized your database queries and you’re using the most efficient page caching mechanisms. The users of your site are pretty satisfied, but you want just a little bit more. How can you push your site to the next level by making sure you’ve included all the optimizations you can to get the fastest speed possible?

Optimize your JavaScript.

You might not be concerned with optimizing you code because newer browsers have gotten significantly faster at processing JavaScript. But like all other programming languages, there are minor tweaks you can make that provide a significant performance gain. Let’s take a look at a few of the ways you can be certain that you’re getting the most out of your client-side JavaScript code.

JavaScript in External Files
The first optimization is to write your JavaScript in external files. By using external files, your browser is able to cache your code. This prevents users from needing to re-download your JavaScript during every page load and potentially during every AJAX request. When a browser visits any website, it checks the src attribute in the <script> tags and then determines if it already has a copy of that file on your computer. If it does, it won’t spend wasteful time re-downloading the exact same code. If you include your code directly in your HTML within <script> tags, it will download that same code each time so that it can be processed. Save those precious bytes!

Minification
Now that you’re putting your code in external files, your next goal is to reduce the amount of time it takes to initially download that code so that it can be cached by the browser. This is where minification comes into play. Minification (or minimization) is the process of removing all unnecessary characters from source code (without changing its functionality). Essentially this means you’ll remove whitespace characters and comments.

Unless you like to torture yourself (and those who follow your work), you probably write code that’s pretty readable. This includes splitting code up between multiple lines, indenting your code with spaces or tabs, and writing comments that explain some esoteric portion of code. All these items are not important to the JavaScript engine because it will just ignore them, but it still takes time to download these extra bytes that will never get used.

Luckily for you, you don’t have to spend time creating the tool that will remove these unneeded characters. There are several good tools out there that will minify your code, and I recommend YUI Compressor. This tool can reduce your code by up to 60% (depending upon how efficiently you write your code). In addition to removing all the unnecessary characters, YUI Compressor will rewrite your code to use smaller variable names. If you have a local variable in a function called var myDescriptiveVariable, the compressor will rename it to var a. We just took our 21-character variable name down to 1 character! If this variable is used in 10 places, we’ve trimmed 200 characters with this one variable, and this happens for every local variable in your script! That’s a lot of bytes saved.

If you’re paying close attention, the key takeaway you’ll notice is that using local variables (compared to global variable that don’t get minified) is one great way to reduce the size of your code after minification occurs.

Initial Page Load Operations
Now that your code has been minified, let’s take a look at initial page load operations. Since some JavaScript operations are synchronous and will halt other browser processing, we want to make sure we don’t slow down the page when the user is trying to perform an action. There are two things we can do to improve initial page loading performance. First, reduce the amount of code you actually invoke on page load (or when the DOM is ready for interaction using Mootools’ domready event, jQuery’s document ready event or your favorite framework’s equivalent). Second, implement lazy-loading techniques. For example, instead of adding all your events to all the elements on the page initially, wait for user interaction or some other process to add the events. Let’s look at a few specific examples so you can see what I mean. Note: the code samples are using Mootools syntax.

Before:

var comments = $('.articles > div.comments');
$('showComments').addEvent('click', function() { comments.show(); });

After:

$('showComments').addEvent('click', function() { $('.articles > div.comments').show(); });

While this may improve initial page load, each time we click on showComments, we have to parse the DOM (Document Object Model) to find all the comments, and this is not a cheap operation. The key here is test your own code and determine with each scenario which way is faster and which will keep your users the happiest. Just realize that on demand operations may be more acceptable to users than having to wait for the page to load. You be the judge!

Code Caching
We discussed file caching before, but what about code caching? We need to determine which operations will benefit the most from caching. The two items I will focus on are loops and DOM interactions. Loops can be costly because you may be performing unnecessary actions within each iteration.

Before:

for (var i=0; i<$$('.toggle').length; i++) {
 var el = new Element('div.something', {
 html: $$('.toggle')[i].get('text')
 });
 el.inject($('content'));
}

After:

var i = 0,
 els = $$('.toggle'),
 length = els.length,
 container = new Element('div');
 
for (i=0; i<length; i++) {
 new Element('div.something', {
 html: els[i].get('text')
 }).inject(container);
}
 
container.inject($('content'));

The “Before” loop is inefficient because we are querying the DOM three separate times to get the elements we need (twice for .toggle elements and once for the #content element), and we are having to determine the length property of that collection of elements during each iteration. In our case, the length won’t change, so we only need to find it one time. Finally, during each iteration, we add a new element to the #content div, and this causes a redraw of the page. DOM manipulation and redrawing can be expensive, so let’s look at how the second method is so much more efficient.

We start by caching our DOM elements so we only have to pull them once and get the length property of those elements only once. We’ve also created an element which will be used to contain all our new elements. Since the container has not been added to the DOM yet, we can add and remove from it without having to worry about the expensive redraw of the page. Once all our elements have been added to the container, we then inject the container into the #content div. Since this is only happening once, we have significantly improved performance.

Selector Efficiency
The last optimization technique I’ll review is selector efficiency. Selectors are used to grab specific elements from the document in order to interact with them in your code. It’s very possible to write poor-performing selectors. Some selectors to avoid:

$$('*')

This will grab all the elements in your document. If you have a huge document, this could take a while. You better not be using this selector in a loop!

$$('[data-some-attribute]')

This selector is inefficient because it has to look for this data attribute within every element in the document. If there are thousands of elements and each has several data attributes, you should just go get some coffee.

$$('body .person:nth-child(3n+1) .category p span.title')

This selector is fairly complicated. The reason this can be inefficient is because it may have to unnecessarily inspect many elements to get to the one(s) it needs. Determine if you can simplify the selector by being more specific and using an id to get to elements or even consider slightly modifying your HTML so that it’s easier to create efficient selectors.

There are plenty of other techniques that will help improve the speed and efficiency of your JavaScript, but these are a good start and should help make you and your users happy. Remember that DOM interactions are slow and expensive, so do what you can to reduce chatting back and forth with the document. Check your loops and minify your code, and your users will surely return.

Happy coding!

-Philip

June 28, 2011

Modern Website Design: Layout

By in SoftLayer, Technology, Tips and Tricks

There have been many books written about website design, and I am not about to take on the challenge of disputing any of them or trying to explain every facet of design. In this short blog, I want to explain what I have come to understand as the modern layout of websites. The term “layout” may have many different definitions, but for this article I am talking about the basic structure of your website, meaning separation of concerns, data transfer from host to client, how to handle changes in data, and when to change your page structure.

Separation of Concerns

It is important when sitting down for the first time to build a website to come up with an outline. Start by making a list of the parts of your website and the functions of those parts. I always start at the base of my web structure and work from there. HTML is always the foundation of a website; it defines the structure and outlines how you will display your data – plain and simple. It doesn’t have to include data or styles, nor does it need to be dynamic … At its essence, it’s a static file that browsers can cache.

Client-side scripting languages like JavaScript will take care of client-side animations and data dispersal, while cascading style sheets (CSS) take care of style and presentation, and server-side scripting languages like PHP or Perl can take care of data retrieval and formatting.

Data Transfer

Where is your data going to come from, and what format it will be in when the client receives it? Try to use a data format that is the most compatible with your scripting languages. I use JavaScript as my primary client side scripting program, so I try to use JSON as my data format, but that’s not always possible when dealing with APIs and transferring data from remote computers. JSON is quickly becoming a standard data format, but XML* is the most widely accepted format.

I prefer to use REST APIs as much as possible, because they sends the information directly on the client, rather than using the server as a proxy. However, if a REST API is not available or if there is a security risk involved, you get the advantage of being able to format the data on the server before pushing it to the client. Try to parse and format data as little as possible on the client side of things, the client should be concerned with placing data.

Changes in Data

In the past, websites were made from multiple HTML documents, each one containing different data. The structure of the pages were the same though, so the data changed, but the code was nearly identical. Later, using server side scripting programs, websites became more dynamic, displaying different data based on variables passed in the URL. Now, using AJAX or script injection, we can load new data into a static webpage without reloading. This means less redundant code, less load on the client, and better overall performance.

Page Structure

It is important when displaying data to understand when to change the structure of the page. I start by creating a structure for my home page – it needs to be very open and unrestricting so I can add pictures and text to build the site. Once the overall loose structure is established, I create a structure for displaying products (this will be more restrictive, containing tables and ordering tools). The idea is to have as few HTML structures as possible, but if you find that your data doesn’t fit or if you spend a lot of time positioning your data, then it might be time to create a new structure.

The Impact of a Modern Layout

Following these steps will lead to quicker, more efficient websites. This is (of course) not a new subject, and further understanding of web layout can be found in Model-View-Controller frameworks. If you find that you spend too much time writing code to interface with databases or place data, then frameworks are for you.

-Kevin

*If you have to deal with XML, make sure to include JavaScript libraries that make it easier to parse, like JQuery.

January 11, 2010

Stop Using Internet Explorer 6!

By in Tips and Tricks

Let me start by saying this… I hate Internet Explorer 6 (IE6). I really do.

Internet Explorer 6 was born on August 27, 2001. The browser was released in conjunction (well, a little after) with Windows XP as a major upgrade from Internet Explorer 5.5. From those humble beginnings in 2001, IE6 has continued to stay alive mostly because of the continued support/use of Windows XP and web-based applications built specifically for IE6.

Here are a few reasons IE6 is a big pile of junk:

  • Numerous security issues.
  • The inability to support CSS version 2 fully.
  • No support for alpha transparency in PNG images.
  • Quirks Mode, which emulates IE5.5.
  • No tabbed browsing.
  • It’s OLD!

So what makes a good browser!?

  • Full CSS 2+ support.
  • HTML/JavaScript W3C standards compliancy.
  • HTML/JavaScript performance improvements.
  • All new browsers utilize tabbed browsing.
  • Some new browsers (such as Google Chrome) have “Task Managers” that can allow you to destroy certain tabs that may have become unresponsive by a web site.
  • Support for HTML 5.

If you’re still using IE 6, consider upgrading to a new browser such as Mozilla FireFox, Google Chrome, Apple Safari, or a newer version of Microsoft Internet Explorer. You’ll make yourself and web developers around the world so happy!