You are on page 1of 35

JavaScript: Leverage it's strengths to eliminate it's weaknesses

by P. LaNasa http://www.sitekickr.com/

Contents
1. Introduction 2. Fun with JavaScript Numbers and Prototype 3. Fun with JavaScript Strings and Prototype 4. Drop and give me 20 units: enhancing the numeric 5. Assertions are possible 6. Caching function return values 7. JavaScript organization for web development 8. Avoiding inline JavaScript 9. Using barricades for a more robust website 10. Bonus: Ad optimization leveraging JavaScript to improve RPM 11. Bonus: Optimize your JavaScript, save the environment

1. Introduction
I've been developing websites for over 10 years now, dabbling in almost every language and technology available, but also narrowing in on a handful of those that I find myself using on a daily basis. For many, that handful can be summed up in the popular acronym, LAMP (Linux, Apache, MySQL, Python/PHP/Perl). But, over the years, you really start to develop your own acronym that best describes your everyday development stack. For me, it's LAMCFJS (Linux, Apache, MySQL, ColdFusion, JavaScript). Of course, two of those don't fit the set, ColdFusion, because it requires a commercial license, and JavaScript because it's client-side. But that's my stack, and I'm stickin' to it. In recent years, I've developed a great fondness for JavaScript, and find myself blogging about it far more than any other topic. So, I thought I'd give this ebook thing a try, and piece together a few related posts. I hope you enjoy!

2. Fun with JavaScript Numbers and Prototype


One of the things that makes JavaScript so portable is it's intentionally minimal library of built-in functions. By reducing the assumption that some off-the-wall function is available in a given version, we are nearly guaranteed that our scripts will work in any environment. However, this also means that a bit more work as to be done on the part of the developer to create basic functions that might otherwise be available in other languages. The good news is that the need for these common functions has been lingering for many years, so most are readily available on the web. This lack of built-ins brings rise to another powerful feature of the language though. Because it's assumed that many functions will need to be created to operate on primitive data types, JavaScript provides us with the prototype property on function objects. Prototype allows us to easily add new methods to built-in objects (classes) "on-the-fly". Meaning, if you've already instantiated a numeric variable, any method you add to the Number prototype will automatically, and instantly be applied. So, let's have some fun with Number's prototype!

Is Number between x and y


This function isn't going to win any awards, but don't you think it looks cleaner than: if(x >= 5 && x <= 10) ? Number.prototype.between = function(x,y) { return (this.valueOf() >= x && this.valueOf() <= y) } > x = 10; > x.between(5, 15); true

Safe division (avoiding divide by zero issues)


I get the divide by zero problem, you can't divide anything into 0 parts, unless you're Chuck Norris. But, as far as 90% my web apps are concerned, divide by zero isn't some cool abstract concept, they just want a return value of zero (or maybe N/A). But, instead, I need to perform checks every time I do a division operation, to make sure the result isn't "infinity", as returned by JavaScript when you divide by zero. I'm not a fan of having dozens of useless conditions floating around my code. Instead, I'd like to add a level of abstraction to the divide by zero concept, letting my code think that the result is always zero. Further, I'd like to encapsulate that into a function.

Number.prototype.safeDivideBy = function(x) { var result = this.valueOf() / x; if(result === Infinity) { return 0; } else { return result; } } > x = 10; > x.safeDivideBy(0); 0

Convert to currency string


Your used to seeing currency related functions on the server-side, but with all this rich web application developer going around, a good set of currency-related functions might come in handy. Here's a start! Number.prototype.currency = function() { return '$' + (parseFloat(this.valueOf()).toFixed(2)).toString(); } > x = 10 > x.currency "$10.00"

Random numbers
I can't actually recall ever needing a random number between 0 and 1, but that's what JavaScript's random() function gives you. That's what any good random() function should give you. It's our job to build on that function for the specific needs of our application. In most cases, this means multiplying the result by a number, then rounding to an integer. Not bad, but this could be encapsulated into a function just as easily: Number.prototype.randomMax = function() { // return a random number with a maximum value of x return Math.floor(Math.random() * (this.valueOf() + 1)); } > x = 10 > x.randomMax(); 3

Existence in an array
If you've ever read "Code Complete" by Steve McConnell, you probably recall his discussion about Programming Into a Language. He was referring to the concept of tailoring a language to suit your development needs, rather than adjusting your needs to fit the limitations of the language. Prototype is one way we can achieve this within JavaScript. I used to do a fair amount of Python development, and came to love the in keyword syntax. It was so flexible in determining existence of one variable in a list or array. For example: 'test' in 'testing' 'test' in ['test', 'test1'] 9 in [9, 10, 11] I came to love it so much, that I just had to have it in my JavaScript development! Number.prototype.in = function(array) { var arrayLength = array.length; for(var i=0; i < arrayLength; i++) { if (array[i] === this.valueOf()) return true; } return false; } > myArray = [5,6,7,8] > x = 1 > x.in(myArray) false > x = 7 > x.in(myArray) true

3. Fun with JavaScript Strings and Prototype


More than a few reader's of my previous post on numbers pointed out that some of the functions I created were little more than semantically different from built-in functions. I agree, and that's okay. For me, adding functions to a built-in object's prototype doesn't serve to create cutting-edge string manipulation routines, but rather to reduce the complexity of my code, by encapsulating commonly used algorithms into an easy-to-call function. Using a built-in object's prototype not only allows us to use a more intuitive syntax: newString = myString.awesomeFunction(); But also helps us to maintain functional cohesion within our objects. Meaning, we don't need to scramble a bunch of unrelated functions together into a giant utility class, i.e. newString = util.awesomeFunction(myString); Not only does this lengthen our code, but it's disorganized. A function that does string manipulation has no business in a class (object) that calculates the perimeter of a rectangle. Furthermore, it wouldn't make sense to create another class (object) to house string manipulation methods when we already have the perfect one built in the String object. So, let's have some fun with String's prototype!

Occurrences in a string
Sure, this one's easy. Just perform a RegEx match. But, to someone else reading your code, it might not be immediately apparent what you're trying to do.
myString = 'this is my string'; numTimes = myString.match(/is/g).length;

Drop that into a function on String's prototype and you've got more readable code at the very least: String.prototype.occurrences = function(substring) { var occRegEx = new RegExp(substring, 'g'); return this.match(occRegEx).length; } > myString.occurrences('is'); 2 Okay, that was not awesome. Hey, I'm just getting started!

Markup
How many times have you written or seen JavaScript like this, myself included: if(document.form1.name.value === '') { document.write('<b>Oh no, you forgot your name?</b>'); } All those gurus are always telling you to keep JavaScript out of your HTML, so shouldn't the reverse apply? But, I really want to just spit out a boldface message. Here's a cleaner way: String.prototype.bold = function() { return '<b>' + this + '</b>'; } document.write('Oh no, you forgot your name?'.bold());

Language
The previous couple functions walk the line of cohesion and usefulness, maybe even step over it. So, let's get back to the core of what a string is: typically a word or group of words in a given language. The String prototype is the perfect home for language functions. String.prototype.isQuestion = function() { var questionIdentifiers = ['when', 'where', 'why', 'what', 'who', 'how', 'can']; // does the string contain a question mark? if(this.indexOf('?') !== -1) { return true; } // search keyword may indicate a question without explicitly specifying the question mark for(var i = 0; i < questionIdentifiers.length; i++) { if(this.indexOf(questionIdentifiers[i]) !== -1) { return true; } } return false; } We could use our new function to refine a user's search by conditionally returning results more likely to answer questions, than to provide generic information: if(searchPhrase.isQuestion()){ // favor search results in the knowledge base } else { // favor search results in the product store }

Is it a Word?
There's an unfair bias towards the numeric in computer science. Of course, it all stems from the fact that the CPU speaks numeric, while we humans speak string. You can follow a gradual trend towards natural language-based syntax in popular development languages such as ColdFusion and Python. But, there really isn't much happening in terms of native support for natural language processing. I'm a little surprised by this, because I feel as if half of the applications that I develop require at least a very primitive form of natural language processing (search, form validation, speech recognition, etc.) Many languages offer isNumeric(), isDate(), or isArray() functions. But, how about isWord(), isVerb(), isCommand()? isCommand() could be used in searching algorithms (similar to isQuestion()) above. If a command is detected, the user might know more or less what they are looking for, otherwise, they may need a deeper level of assistance. isWord() could be used in form validation. If a user submits a field, validate that it's actually a word (or group of words). The definition of a word is subjective, but we'll make a few assumptions: 1. A word does not contain spaces 2. A word can contain only letters or the hyphen 3. A word is less than 25 characters in length String.prototype.isWord = function() { if(this.length > 25) { return false; } return /^[A-Za-z\-]*$/.test(this); } A user submits a form which has fields for first and last name, so you validate against our new isWord() function: if(!firstname.isWord()) { alert('Is that really your name?'); } Well, maybe it isn't. Many folks out there have a two-word first name. So, let's expand our String prototype to help out here: String.prototype.words = function() { return this.split(' '); } Now we are armed with the basics necessary to properly validate a first name: for each(item in firstname.words()) { if(!item.isWord()) { alert('Is that really your first name?'); break; } }

4. Drop and give me 20 units: enhancing the numeric


When your high school gym teacher asked you to "drop and give me 20", did you ever have the guts to ask, "20 what?" Being the geeks that we are, such a question is perfectly valid, although in asking you might just earn yourself another 20 units of unwanted exercise! Although assumptions can be made in the real world about the unit implied by a certain context, the same can't be said for our code. Compilers and interpreters usually can't make assumptions like the one above based on context. Every programming language supports numbers natively, although they are almost always implemented as primitive types a place in memory to store a number, nothing less, nothing more. But as the opening paragraph suggests, numbers by themselves present very little information, unless they are paired with a unit. We write our own code to deal with units, but most often the code is not consistent, both in checking the unit of a number, and converting to and from units. If you are developing in a dynamic language, such as JavaScript, you are offered an opportunity to enhance the way numbers are stored natively. The ability to "attach" a unit to a number can be gifted to the Number data type. In the case of JavaScript, this is possible because a Number is an object, and most objects can be modified through JavaScripts prototype language feature.

Enhancing the Number object with the prototype property:


Number.prototype.setUnit = function(unit) { this._unit = unit; } Number.prototype.getUnit = function() { return this.unit; } The downside is that to leverage these new functions, we need to "formally" create a number object: myNum = new Number(56); myNum.setUnit('inches'); console.log( myNum.getUnit() ); On the flip-side, we still get to use our number as we're used to, it's functionally the same: myNum + 50 is still a valid arithmetic operation. The internal value of myNum is still 56.

Adjusting the constructor for more meaningful code


Sure, the technique above works great, but who really wants to initialize a Number object that way every time they want need to use an integer or float? What if we adjusted the Number object's constructor, to allow us to provide the unit as well? That would certainly make our additional efforts of creating a Number object more worthwhile, and perhaps make the code a little easier on the eyes:

var oldProto = Number.prototype; Number = function(num, unit) { this.value = num; this.unit = unit; }; oldProto.valueOf = function() { return this.value } Number.prototype = oldProto; Number.prototype.setUnit = function(unit) { this.unit = unit; } Number.prototype.getUnit = function() { return this.unit; } The real magic of the code above is the recreation of the valueOf() function on the Number object. If you've read an opinions on creating numbers with the new keyword, you might have found them all to be against such a practice. But, much of their reasoning is that you loose the ability to perform operations on them. By redefining the valueOf function that JavaScript uses internally, we preserve that capability. However, it should be noted that the equality operation will no longer work! This is important to remember. x = new Number(30, 'inches'); y = new Number(30, 'inches'); x == y will return false. This is because the equality operator does an object comparison and does not use the valueOf() function. I'd have to say that this is probably the only downside to this method, we're forced to compare against the valueOf() method: x.valueOf() == y.valueOf(); Or, if we're feeling ambitious, adding a equals function to the Number object would serve our purposes equally well: x.equals(y); If you think this approach lends to code that's easier to read and write, using the code examples above, creating such a function should be relatively easy.

Avoiding inconsistent unit values


As in the examples above, we certainly could allow string literals to be passed into the constructor. But, what happens when we use inches in one case, Inches in another case, and inch in yet another case? There are too many possible conditions to account for when testing against the units value. A simple solution to this is to provide a basic "units map":
Number.units = { inches: 'in', millimeters: 'mi', feet: 'ft' }

So, our new method of creating a Number object would look something like: x = new Number(30, Number.units.inches); But, what would prevent supplying string literals to the constructor? You could also perform some validation in the constructor: Number = function(num, unit) { this.value = num; var unitValidates = false; for each(value in Number.units) { if(value === unit) { unitValidates = true; break; } } // an assertion would make more sense here // unless we're accepting unit input from the user if(!unitValidates) { throw new Error(unit + ' unit is not allowed'); return false; } this.unit = unit; };

Dropping in the conversion functions


Next comes the need to convert between units. There are two ways we can do this: Number.unitMap = [ {Number.units.inches : {Number.unit.millimeters: 25.4, Number.unit.feet: 1 / 12 }, {Number.units.millimeters: {Number.unit.inches: 1 / 25.4, Number.unit.feet: 1 / (25.4 * 12) }, {Number.units.feet: {Number.unit.inches: 12, Number.unit.millimeters: 12 * 25.4 } ]

1. Modify the Number object itself Number.prototype.changeUnit = function(unit) { this.value = this.value * Number.unitMap[this.getUnit][unit]; } 2. Use a function to return the converted value Number.prototype.convertUnit = function(unit) { return this.value * Number.unitMap[this.getUnit][unit]; }

Arguments against the arguments against adjusting built-in prototypes


That double-negative is not a typo. As stated before, there are unlimited arguments against modifying built-in object prototypes. Some are valid, but most are nothing more than opinions about programming style and convention. (26).doSomething(); The above statement, agreeably is confusing and probably not a good practice. But, the method I discuss above doesn't allow for such "literal processing", as you are required to formally create a Number object with the new keyword. var x = new Number(30, Number.units.inches); This statement can hardly be considered bad style or practice. It uses standard JavaScript object creation syntax, spells out clearly that we are using a modified version of the Number object, and encapsulates the use of units. At worst, we're trading a questionable JavaScript practice for many rock-solid software construction practices including abstraction and encapsulation.

5. Assertions are possible


Assertions are a great development-time debugging tool. They allow us to raise a red flag whenever a condition occurs that should never occur. This is, of course, an entirely different strategy than errorhandling, which is a production-stage, run-time tool that helps to improve a programs robustness by gracefully "surviving" after an expected error occurs. Assertion Example: The current object has been initialized before calling this routine Error-handling Example: User attempted to import a CSV file with 5 rows, instead of the expected 6 rows Assertions are a handy self-disciplinary tool for the developer, but not all development languages support them natively. Unfortunately, JavaScript falls into this category. But, the concept behind the assertion is simple, and the code behind the concept is very easy to integrate into any language. Below is very basic assertion function that can be executed as a statement. It can make use of console logging or popup dialog alerts. But, the real magic happens when the function "detects" that the script is no longer in development mode. In this case, it will rewrite itself to a very basic empty function to improve performance. Cool right! ASSERT = function(condition, message) { /* the checks below will only be performed in development */ /* during production, if an ASSERT is left in place, it will cause the ASSERT function to rewrite itself to a void, empty function to improve performance */ /* you can assign appropriate values to local or dev parameters as makes sense by your application */ if(local OR dev) { ASSERT = function(condition, message) { /* do nothing */ } } else { if(!condition) { alert(message); // or console.log(message); throw new Error(message); } } }

6. Caching function return values


As web applications get more complex, more and more of the processing work is pushed to the client browser in the form of JavaScript code. We seasoned web developers earned our stripes in the serverside world, where our own web server executed the code. With this direct tie between a web browser and our precious server resources, caching was relied upon heavily, not only to improve site performance, but to reduce server load, which directly correlates to server operation costs. We had those two motivations to leverage caching. With the client-side revolution though, the web developer is seeing a decrease in server load, and an increase in client (browser) load. Sounds like a dream come true. But, this leads back to the motivation for performance. We no longer need to rely on our own server resources for performance, but instead pass the buck onto the user's computer processing power. The issue isn't solely tied to developer motivation, but also to client-side language support. JavaScript doesn't offer a built-in caching solution. So, if we have a function which only expects 3 or 4 unique argument values over the script's lifetime, and that function happens to take 5 seconds to process, we're not doing our duty as programmers to put caching to work for the user. After all, we're still going to use the client's memory for caching, what do we have to lose! Implementing a function return value cache only takes a few lines of code. Below is pseudocode that is syntactically correct JavaScript. I call it pseudocode because it really doesn't deal with all of the requirements that a proper cache should have (such as invalidating, lifetime, maximum size, etc). But, it introduces the concept and provides a foundation.

function Cache() { /* create the cache object as a singleton (only one instance allowed) */ if(typeof Cache.instance === 'undefined') { Cache.instance = this; } var data = [ ] // we'll abbreviate cacheAwareCall as caCall this.caCall = function(functionName) { var cacheCheck = this.load(functionName, this.caCall.arguments); if (typeof cacheCheck !== 'undefined') { return cacheCheck; else { var returnValue = window[functionName].apply(this, this.caCall.arguments) this.save(functionName, this.caCall.arguments, returnValue); return returnValue; } } this.save = function(functionName, argumentObject, returnValue) { // prepend item to cache data.unshift({ fname: functionName, arguments: argumentObject, returnValue: returnValue }); } this.load = function(functionName, argumentObject) { for(entry in data) { if(data[entry]['fname'] === functionName) { // we have a match on the function name // deepCompare is not implemented here, examples are throughout the web if(deepCompare(argumentObject, data[entry] ['arguments']) { return data[entry]['returnValue']; } } } return undefined; } return Cache.instance; }

7. JavaScript organization for web development


For those of you who have come across this post, and don't yet know about the object-oriented features of JavaScript, it will not carry much meaning. I used to be you, believing that JavaScript was only for validating web forms or making slick rollovers, and further-yet, that object-oriented programming is really only useful in game development or larger projects. I don't have the talent to persuade you otherwise, but these two guys do: Object-Oriented JavaScript: Create scalable, reusable high-quality JavaScript applications and libraries If you are in the first camp, not fully understanding the object-oriented nature of JavaScript, I have little doubt this book will open your eyes and present the language in a way you never seen before. Code Complete: A Practical Handbook of Software Construction, Second Edition If you are in the second camp, not fully understanding the power of object-oriented development in general, this book is really a must have. It was a game changer for me many years ago, and the methodologies are language-independent, so anyone can benefit. With that being said, and assuming that if you're at this point in the post, you are familiar with OO development and JavaScript's OO features. You've probably authored a few JavaScript-based web apps, and are well aware of the challenges it presents when compared with traditional desktop OO development. Namely: There isn't a good way to organize classes and packages, and reference them from other classes and packages (unless everything is in one big file). Splitting classes and packages into multiple folders and files requires multiple HTTP connections to load all of the code The asynchronous nature of callbacks is useful, but can add a good deal of complexity to the even the simplest methods It's clear from a page load time perspective that condensing all of your classes into one file is the best choice. But having a few thousand lines of code in one file can make it difficult to locate the exact method you are looking for, as well as cause upload-time annoyances as the file grows larger and larger (if you are developing on a remote server). To overcome these issues, you can: 1. Do your JavaScript development on your local machine. JavaScript is interpreted inside your web browser, so it does not require a web server. Another drawback for some is the same origin policy. If you are developing locally, browser security restrictions disallow you from making cross-domain requests. To get around this though, many browser have initialization flags that turn this security feature off. For example, you can start chrome with the disable-web-security option. 2. Use an IDE that recognizes JavaScript objects and organizes them into "classes, methods and properties" for you. I like Eclipse for this. The Project Explorer pane does a good job of classifying the objects, i.e.

Although, I was a little disappointed to find that the project explorer doesn't catch on to this function definition syntax: myMethod = function() { } So, functions defined in this way, within a "class", don't show up in the explorer view. If you need to develop on a remote server, and prefer to separate your JavaScript classes and packages into a folder/file hierarchy as is familiar to compiled languages, you're not outta luck. We just have to get creative! In traditional OO languages, we are accustomed to included individual classes within packages on a "need-to-use" basis, i.e. import mypackage.myclass In JavaScript, we're kinda stuck with the <script> tag, which is really only useful for loading in an entire JavaScript source file. That source file might contain 5 classes or 50 classes, all of which we must load, regardless of which ones we'll actually use. Because of this limitation, we typically include all of our classes in one big file. It doesn't have to be this way!

We can extend JavaScript a bit, including just a few lines of code to emulate the package/class include methods found in our traditional languages. This of course, requires a few capabilities: The ability to dynamically load JavaScript files. When I say dynamically, I don't mean "at runtime", because there's no compiler, everything is at runtime. What I'm talking about is the ability to load a JavaScript file from within JavaScript. We know we can do this by dynamically inserting a <script> tag into our document, and providing it the appropriate src attribute. The ability to determine if a class has already been loaded, so we don't duplicate any efforts. This is possible with the JavaScript typeof operator. For our cases, we need to introduce the eval function, since we're dealing with a dynamic function name. A naming convention, so we know which JavaScript file to load, based on which package/class name was provided. By sticking to the convention of the filename carrying the same name as the class, and the folder carrying the same name as the package, our little loader will always know which file to grab. As Nicholas Zakas points out, we can encapsulate the loading of an external JavaScript file into a function, and provide a callback to execute after the script has loaded, so our method call might look like: loadScript("/mypackage/myclass.js", function(){ //initialization code }); Now, if we alter his script a bit, to use the naming convention we suggested above, the loadScript function would be more like:
function loadScript(package_class, callback){ var className = package_class.split('.').pop(); if(eval('typeof ' + className) !== 'undefined'){ callback(); } var script = document.createElement("script") script.type = "text/javascript"; if (script.readyState){ //IE script.onreadystatechange = function(){ if (script.readyState == "loaded" || script.readyState == "complete"){ script.onreadystatechange = null; callback(); } }; } else { //Others script.onload = function(){ callback(); }; } script.src = '/' + package_class.replace(/\./g, '/') + '.js'; document.getElementsByTagName("head")[0].appendChild(script); }

Essentially, we are replacing the dot notation with folder notation, so by calling this method: loadScript('Mypackage.Myclass', function(){ //initialization code });

We are actually loading the /Mypackage/Myclass.js file. The Myclass.js file contains a Myclass function, which upholds our naming convention. Notice also, in the opening lines of the new loadScript method, we check to see if the class has already been loaded. But, what if we want to load multiple classes, and have our callback fire only after all of the external scripts for those classes have been loaded? One possibility would be to create an array of script elements, load them all, then with each onload event, check to see if all scripts have been loaded:

function loadScripts(packages_classes, callback){ var scripts = [], scriptCount = packages_classes.length; for(var i = 0; i < scriptCount; i++ { var className = package_class.split('.').pop(); if(eval('typeof ' + className) !== 'undefined'){ scripts[i] = {loaded: true}; } else { scripts[i] = {loaded: false}; } scripts[i].script = document.createElement("script") scripts[i].script.type = "text/javascript"; if (scripts[i].script.readyState){ //IE scripts[i].script.onreadystatechange = function(){ if (scripts[i].script.readyState == "loaded" || scripts[i].script.readyState == "complete"){ scripts[i].script.onreadystatechange = null; scripts[i].loaded = true; if(checkAllLoaded()) { callback(); } } }; } else { //Others scripts[i].script.onload = function(){ scripts[i].loaded = true; if(checkAllLoaded()) { callback(); } }; } scripts[i].script.src = '/' + package_class.replace(/\./g, '/') + '.js'; document.getElementsByTagName("head") [0].appendChild(scripts[i].script); }

// private function - check if all scripts have been loaded var checkAllLoaded = function() { for(var i = 0; i < scriptCount; i++ { if(!scripts[i].loaded) { return false; } else { return true; } } } } I have not tested the above code, at all! It's meant to be more theoretical. But, it would appear that loading multiple external files, and waiting for a callback is possible. So, a method like this, very clean and consise is actually possible in JavaScript!
loadScripts(['Mypackage.Myclass', 'Mypackage.Myclass2', 'Myotherpackage.Myotherclass'], function(){ // tie it all together here! });

8. Avoiding inline JavaScript (and CSS)


Every HTML page consists of three major components: The skin/template (including meta data) HTML tags used to wrap the content and provide information about the page The content Text marked up with HTML tags The presentation CSS rules and JavaScript code The skin/template should be separated from the content on the server-side, using a framework or layout method as described in my post on Site Structure. The presentation, however, needs to be separated on the client-side, using <style>, <link>, and <script> tags. This is one of the oldest and most-commonlyspoken-of web development practices, and I'd like to go into detail on why this is such a good idea. Essentially, what separation of content and presentation means is that we are to avoid embedding inline styles and scripts in our HTML content. For instance, this is a prime example of what not to do: <a style="text-decoration: none;" onclick="alert('you clicked me!')">click</a> Markup like this is found all over the web, often as a result of inexperienced web coders using graphical editors, but experienced web developers share the blame too. It's all too easy when 5 o'clock comes around and your taking every shortcut possible to get out the door, to forgo creating a style class, and instead just drop those styles right into the HTML tag. Instead of just frowning on the practice, let's look at a few reasons why this separation is so important: 1. Referencing bare HTML content is more difficult This reason doesn't present itself right away. It usually comes into play after a website has been launched, and it's content is consumed by services or clients other than a web browser. Because CSS and JavaScript is only useful to web browsers, anything else which references the content will either ignore it, or be negatively affected by it. You are, in essence forcing non-browsers to absorb presentational information when it carries no meaning. Search engines do a great job of ignoring the presentational items when they index your pages, but it doesn't mean they like it. 2. Global presentational changes are difficult This one becomes apparent if you have more than 5 pages on your site, each with inline presentational elements. If you have a page title styled as such: <h1 style="font: normal 24rem/1.5rem Arial, Helvetica, sans-serif; color: green;">My page heading</h1>

Then, at some point down the road, you decide that green isn't really the look you were going for with page titles, you need to manually adjust all of your HTML files, to make the inline style adjustment. This difficulty is compounded with JavaScript, as often times your editor's global file search/replace feature will be difficult to use against a multiline search. 3. Future-proofing <script> tags currently validate inside elements (with XHTML you need to use the ugly //! [CDATA[ trick), but there may be a time when they don't, as the <style> currently does not. 4. Context During a presidential race, we hear phrases spoken by candidates, but out of context. The phrase may have carried meaning in the context of the content that surrounded the phrase, but alone, it carries no meaning or just makes them look bad. The same happens with CSS! To illustrate, let's say we have a block of content that we want to emphasize heavily by placing a 50 pixel black border around it, using inline CSS: <div style="border: 50px solid #000;">This content is so important that mobile users need to suffer!</div> This may present well on a 1024 pixel wide desktop browser, but on a mobile device, the border itself will take up nearly half the screen. To avoid this, we would typically have separate CSS files for mobile and desktop. But, there is no such separation when we use inline CSS. To illustrate in a different way, let's say we have the following inline CSS: <a style="color: #a00;">This is a red link</a> If this content is loaded on a device with a black & white screen, the red link styling is useless and only served to make the content itself take longer to download. 5. Team environment If you work in a team, it's likely that you have one team member dedicated to content (HTML), another to style (CSS), and still another to interactivity (JavaScript). If you are absent version control and a "check-in" procedure as so many small operations are, the logical course of action is to restrict access to HTML files to the person who edits the HTML, CSS files to the person who manages the CSS, etc. This serves to prevent one person from overwriting another's work if they are both accessing the same file at the same time. That system works well, unless you have CSS and JavaScript embedded in your HTML files. In this scenario, the person who manages CSS needs to say, "Hey Bob, can you close the file your working on for 20 minutes while I edit the inline CSS? When I'm done, don't forget to load the file from the server again so you don't overwrite my changes. Thanks Bob, you're the best, sorry for wasting 20 minutes of your day!"

6. Markup to content ratio (bad for search engines) This one has been preached about by SEO wizards for years, so I apologize for duplicating it here. However, the list wouldn't be complete without it. Not only does inline style and script increase page load time, it increases the download time for search engines who are just looking for raw content. In effect, a search engine has downloaded additional information that it needs to discard anyway. This negatively affects how search engines position your site in two ways: The content vs. markup ratio. It has been suggested the search engines frown when the amount of markup exceeds the amount of content by an undetermined amount (the ratio, of course, being dependent on the search engine). Without knowing the ideal ratio, it's a wise practice to keep markup to the absolute minimum required. This includes, of course, eliminating inline style and script when possible. Page load. Recent evidence suggests that Google (and perhaps other SEs) factors your page load time into it's ranking algorithm. Essentially, with all other things being equal, a site with a faster page load will be ranked higher. As touched upon in the point above, inline style and script increase page load time. 7. Performance We've touched on how inline style and script can negatively affect performance, but there's another side to that. Housing all of your CSS and JavaScript in external files can actually improve performance drastically. The magic comes from browser caching. A typical web site frequently updates content, but rarely touches style and interactive areas. With this in mind, most web hosting configurations are set to direct web browsers to cache CSS and JavaScript files. By caching these files in the browser, they do not require another HTTP connection to download them from the server. This post goes into more detail on browser caching. With these seven reasons comes a compelling argument against the use of inline style and script, but by no means am I saying it is incorrect to do so. It is currently valid, and in very simple sites, may actually improve performance. In some cases, you can apply an inline style without coming in conflict with any of the reasons above. But, avoiding inline style and script usually leads to many years of happy and healthy web coding!

9. Using barricades for a more robust website


You hear the term robust thrown around loosely. "Hey Bob, that new app is gonna be robust, right?" "Oh yeah Steve, I'm all over that robustness." But how many people really understand what they're promising? I certainly didn't used to. If you dictionary.com the word robust, you are told that it means strong and healthy. If you try to translate that meaning to software quality, it become a little ambiguous. Strong. Does that mean the software can process a lot of data? Or can support a large amount of concurrent users? Healthy. Are we talking about how many errors occur within the software? Health is perhaps more closely related to robustness, but not exactly. When talking about software, robustness is how well your code deals with errors, and whether or not the software can continue to run in the wake of an error. Using the healthiness analogy: Your software may be in perfect shape and run error free 99.9% of the time, but how well does it cope when it catches a cold? If your software decides who your best friend is on Facebook, no harm done if an error shuts down the program. But, if your software operates a pacemaker, that .1% probability of an error really shouldn't shut anything down! Different web technologies offer different solutions, some not quite as apparent as others. But, beyond syntax and keywords, there are methodologies that provide robustness. The general approach needs to be a little different when working with client-side code as opposed to server-side. On the server side we have more complete error information, as well as logging and notification options that just aren't possible (or are more much more difficult to achieve) on the client side.

Server-Side
On the server side, the first step is to decide what the barricade protects. For instance, if you have a two-column website in which both columns are dynamically generated by your server-side code, you might want the content column to be entirely unaffected by any errors that occur in the sidebar. A popular example of this issue occurs within any given WordPress blog. Depending on your PHP error settings, an error in your sidebar will "take down" the entire page. With this possibility, it's in your user's best interest to barricade the sidebar from the rest of the site. For that matter, perhaps the footer as well. We can do this with our old friend the try/catch block. By wrapping the entire sidebar code in a try/catch, we prevent any and all errors from affecting the rest of the site. This still allows our more "fine-tuned" errors to do their job of properly logging and notifying the user of any errors. But, we also have the added comfort of being able to log errors from within the "master" catch block. This doesn't even mention the level of security gained by not exposing error information to potential hackers.

JavaScript
It seems like every time I come up with a good, solid server-side methodology, it doesn't transfer to JavaScript! With JavaScript, errors are not displayed front-and-center to the user. They are tucked away behind a small warning icon in the corner of the browser. But, that doesn't mean they can't do just as much harm. As with server-side code, one error in your script and that's it, execution stops. Of course, we have the same try/catch capability. We could easily wrap an entire chunk of JavaScript in a nice big try/catch. But, how many of us want to wrap our entire script in a try/catch? JavaScript just doesn't have the useful error reporting that server-side languages have, such as context, line number, etc (some browsers support line number). This would be a debugging nightmare, as the errors would no longer be picked up by our browser console our true friend in the debugging effort. JavaScript does, however, treat it's "turn-me-on" tag a little differently than server-side-languages. "turn-me-on", of course, refers to the <script> tag saying to the browser, "start parsing JavaScript!". What were you thinking? The <script> tag is self-contained, error-wise. It is an error barricade from the rest of the <script> tags. Server languages like PHP or ColdFusion don't provide such a barricade. You can have 30 <? ?> directives in one PHP file, even divide them up across multiple files. But an error in one ruins the whole batch. Whereas in JavaScript, an error in one <script> tag kills the entire script within, but doesn't affect the other <script> tags at all. So, how is this useful? <script type="text/javascript"> var x = something; // 'something' is not defined document.write('Why won\'t my message display, sadness'); </script> <script type="text/javascript"> pacemaker.keepOnWorking(); document.write('I am unscathed by the errors in my document\'s other script tag!'); </script>

10. Bonus: Ad optimization leveraging JavaScript to improve RPM


I love highway billboards, and I think they're really effective, at least on me. I do however, wish they were a bit more dynamic. For one, I've always wondered why they don't include a giant QR code that passengers can try to snag with their phone while passing by. If anyone uses this idea, I want 10%. It's probably been done a thousand times, and I just need to get out more! Okay, digressing from the subject of the article a bit. Billboards are great, but they only work while driving in one direction, and if you don't get a chance to take it all in, there's no going back. On the web, the browser scroll bar is analogous to the highway. Once a user scrolls an advertisement out of view, not only is it no longer visible, but it certainly can't be clicked. But, no asphalt was laid, and there are no laws against scrolling back up. Yet, how many users do you think will actually scroll up to see if they missed any good advertisements? We have more opportunity to keep our ads within the view of our website visitors, by using JavaScript. Some of the techniques are so basic that you'll wonder why you haven't been doing them a long time ago.

Keeping ads in view


You don't need a marketing guru to tell you that an advertisement holds no value if you can't see it. There's absolutely no dispute about that fact that you can't click an advertisement if it is not in view. If you only have one or two ads on your site, it's important to make sure they are always visible, without being intrusive. As many ad optimization techniques suggest, keeping ads close to readable text is a good idea. On this blog, you'll notice that I have one floated in or around the third paragraph. But, what happens when you scroll down beyond the third paragraph. The advertisement becomes useless. Now, I certainly don't want to annoy my readers, so moving the ad within the content area would not be the way to go. It would cause content to shift as line-wrapping changes to support the ad that has been floated next to it. I instead opted to move the ad down below the right sidebar when it is scrolled out of view. This type of movement is accomplished by wrapping the advertisement code in a <div> element, then moving that <div> with jQuery. In the example below, I have wrapped the AdSense ad code in a <div> element with an id of post-inline-ad.

$(window).scroll(function(){ if(siteKickr.isScrolledIntoView($('.entry-content p').first().next().next())) { if($('#post-inline-ad').hasClass('sidebar')) { // if ad is in sidebar, move back to paragraph $('#post-inline-ad').removeClass('sidebar'); $('.entry-content p').first().next().next().after($ ('#post-inline-ad')); } } else { if(!$('#post-inline-ad').hasClass('sidebar')) { // if ad is not in sidebar, move to sidebar $('#post-inline-ad').addClass('sidebar'); $('.widget-container').last().after($('#post-inlinead')); } } }); siteKickr = { isScrolledIntoView: function(elem) { var docViewTop = $(window).scrollTop(); var docViewBottom = docViewTop + $(window).height(); var elemTop = elem.offset().top; var elemBottom = elemTop + elem.height(); return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)); } } This method isn't quite as hardcore as keeping the advertisement in the view regardless of scroll position, but it gives the user another opportunity to view the ad, where it may previously had not been in a recognizable position.

Fixed Positioned Element, the CSS way


Of course, there's always the simple, yet effective CSS solution: div#my-ad-wrapper { position: fixed; top: 100px; left: 0; } The fixed value of the position style specifies that an element remains in the specified position, even if the user scrolls. It's similar to the absolute position, except that an absolute positioned item will scroll with the rest of the static content.

Hey, look over here


Most metrics divide the number of ad impressions by the number of clicks to determine how well optimized your ad placement is. That works well, but there's another metric to consider is the total time-on-page for your visitors in relation to ad clicks. If a visitor sits on one page of your site for an hour that's a measure of success in many ways, but if they don't click on a single ad in that hour, then that visitor may not be as valuable to you as all the other metrics lead you to believe. If you are a door-to-door vacuum salesperson, asking people for 5 minutes of their time, how successful would you be if you spent 1 minute giving your pitch, then just stared at them for the remaining 4 minutes.The same thing happens when a visitor loads a page on your site, sees the advertisements unfold before their eyes, then continues on to read the page content for 5 minutes. You can keep your visitor engaged in the opportunity to click advertisements by displaying them again after a certain period of time, unobtrusively. I emphasize the term unobtrusively, as the best way to annoy your visitor would be to surprise them with an advertisement pop-up right over the text they are reading. But, if you pull a "sidebar surprise", you won't offend your visitor. Check your analytics tool for pages with high "Avg. Time on Page", to determine which pages would most benefit from this method:

Then, let's again put JavaScript to work for us, in this case to reveal an advertisement in the sidebar after the user has been on the page for 60 seconds: The HTML <div id="timed-ad"> <span class="close">X</span> <p>Thanks for your interest in this article. How about a break to check out the awesome deals from our friends at: <a href="http://www.jdoqocy.com/click-6324420-10865503" target="_blank"><img src="http://www.ftjcfx.com/image-632442010865503" width="234" height="60" alt="" /></a></p> </div>

The CSS #timed-ad { position: fixed; top: 300px; right: -270px; /* account for width and padding */ width: 250px; | padding: 0 10px; border: 1px solid #000; border-radius: 5px 0 0 5px; background: #eee; } #timed-ad .close { float: right; margin: 0 -10px 0 0; padding: 5px 8px; color: #fff; background: #555; cursor: pointer; } The JavaScript (jQuery) $('#timed-ad .close').click(function() { $(this).parent().remove(); }); setTimeout(function() { $('#timed-ad').animate({ right: -1 }, 2000); }, 60000); // 60 seconds

Making use of empty real estate


You've no doubt noticed the trend towards wide screen desktop monitors. A website afforded this much width could easily reduce the vertical scrolling necessary to see all of it's content. But, most don't take advantage, and for good reason. Many users are still on 1024768 monitors. And, even if we used a responsive layout, to use whatever width is offered by the screen, we still wouldn't want content to span the full width of a widescreen monitor, it would be difficult to read. So, what do we do with these large "gutters" on either side of the content. Since we can't use them for the site content, we might consider using them for something that doesn't affect the purpose of the site if they can't be seen: advertisements. You could use any number of CSS techniques to force these ads into the widescreen gutters of the site, but JavaScript certainly provides the most flexibility. With JavaScript, you can introduce the condition to only display the gutter ads if the site width is greater than 1400 pixels, for example. This is, arguably, the least intrusive form of banner advertising on a website. It doesn't intrude on the content area at all, and users are more than welcome to reduce their browser width if they don't want to be "bothered" with the advertisements.

The implementation of this method is simpler than the other methods, so I'm going to break my own rules of separating content, css & script, and package it all up into a small piece of jQuery: $(window).resize(function() { if($(window).width() > 1400) { /* widescreen - show gutter ad */ if($('#left-gutter-ad').length === 0) { $('body').append('<div id="left-gutter-ad" style="position: fixed; top: 62px; left: 15px;">My ad code goes here</div>'); } } else { $('#left-gutter-ad').remove(); } }); $(document).ready(function() { $(window).resize(); });

11. Bonus: Optimize your JavaScript, save the environment


I'm not a tree-hugger, but I'm conscious about the environment. I recycle, drive a 4-cylinder, try to eat local/organic, and try not to dump paints and varnishes down the kitchen drain. But, I never really stopped to consider my direct connection to the environment through my coding practices. When we think about abstraction, we usually don't go further than the operating system or the computer processor. We run a high-level language function, it's converted into dozens of low-level language statements, then hundreds of lines of machine code, which is run by the processor. But, all that happens under the condition that the processor has power. Let's take a look at the levels of abstraction that extend beyond your CPU.

Plants
Coal was formed from the remains of vegetation that grew millions of years ago. The plants which formed coal captured energy from the sun through photosynthesis. This energy is used to create the elements within plant tissue. The element most important for us being carbon, which gives coal most of its energy. No environmentally negative factors here.

Coal
Of course, coal is not the only form of energy used to generate electricity, but it's the largest in the US. Coal power stations have machines that convert the heat energy from the combustion of coal into mechanical energy, which then powers the electric generator. It's the byproducts and wasted heat energy from this process that causes the negative environmental effects. The process is not 100% efficient. Those inefficiencies aren't bottled up, they're sent to our air, lakes and rivers. On average, a ton of coal generates 2,460 kilowatt-hours of electricity. Let's make that simpler: 1 kilowatt-hour of electricy = .81 pounds of coal

The Kilowatt
We Americans aren't fluent in the metric system, but we know the Kilowatt better than any other unit of measurement when it comes to electricity. Why? Because that's what we see on our electric bill, the Kilowatt-hour. But, lets not forget that the kilowatt-hours we use at home don't directly translate to the kilowatt-hours generated at the power plant. A certain amount of energy is lost in the transmission over the power lines. So, how does this translate to our computer's CPU power demands? A kilowatt-hour may be enough to power your light bulb for an entire day, but a CPU is vastly more complex. A light bulb performs one operation consistently, from the time you turn it on, to the time you turn it off. Calculating it's energy usage is straightforward. But, your computer's processor is more dynamic.

The CPU
CPU's used to maintain a more steady power consumption, but today's CPU is more energy conscious when idle. The big question is, "how much energy is saved when it's idle, compared to when it's working?" Apparently, this is not an easy question. It, of course, depends on who you ask, what the rest of the system is doing, and which processor. Many forums I visited seemed to suggest that an Intel I7 would drop to 75 watts, from 95 watts when at idle. I also had difficulty finding out exactly what idle means. Is the processor idle between each sequential instruction sent its way? Or does it require a length of time before it settles down into it's idle state? Again, a solid conclusion wasn't reached. So, for this article, I'm going to make the following assumptions: The difference between idle and working = 20 watts = .02 kilowatts Additional Kilowatts used for 1 CPU instruction = the number of hours the instruction takes * .02 I'm emphasizing the word additional, because the CPU uses power whether it's processing an instruction or not. The next question: How long does a CPU take to execute one instruction? It varies of course, so let's again use the Intel I7. Wikipedia says 82 billion instructions per second! You might be thinking, why are we possibly concerned with power consumption when we can process 14.7 quadrillion instructions for just one measly kilowatt-hour! 1 Kilowatt-hour, we remember, is created by the combustion of .81 pounds of coal. 1 pound of coal gets us 18.2 quadrillion instructions. Good job coal, your not so bad after all. But, hold on, we haven't worked our way through the remaining levels of abstraction. How much does 18.2 quadrillion instructions really buy us?

JavaScript
Huh, how did I get to JavaScript? I skipped machine code, assembly language, the OS, the browser environment. I decided to do this for the dramatic effect of showing how many CPU instructions are required for a simple JavaScript statement. var x = 1 + 1; I'm now thinking to myself, "how do I begin to determine how many machine code instructions that little statement took?" I intentionally avoided anything user-interface or input related, to simplify this task. We first need to find out what JavaScript "sits on". Until Google's V8 engine, JavaScript was interpreted, and still is in most browsers, by a JavaScript engine. The first JavaScript engine, SpiderMonkey, was written in C++.

C++
What does it take for C++ to run a JavaScript statement such as the one above. I'd have to imagine that this particular statement is one-to-one. C++ allows us to declare and initialize a variable in one line of code, even if that initialization involves arithmetic. int a = 1 + 1;

Assembly Language
.data x: .word y: .word a: .word add a,x add a,y int 21h 1 1 0

Is the above proper assembly langage? No. Will it work? Probably not. I don't know Assembly Language, I just wanted to illustrate the number of instructions required to perform a simple operation. In this case, it's likely that each assembly code instruction will produce one line of machine code. So, the most basic JavaScript statement might translate to at least 7 lines of machine code. I'm talking about a statement that involves nothing but the processor and RAM (no display, peripherals, disk drive, etc). A more complex statement, such as document.write(), may actually consist of hundreds of machine instructions. So, we can easily see how inefficient JavaScript code is orders of magnitude more inefficient when you look at it from a machine code standpoint. But this still doesn't really mean anything. It's too difficult to relate additional lines of machine code directly to environmental impact! But, what if we convert that into more recognizable metric, time. If a set of poorly optimized JavaScript statements takes 100 milliseconds to run, and the optimized version of that same code takes 50 milliseconds to run, you are keeping that processor busy for 50 milliseconds beyond what is necessary. 50 milliseconds = .05 seconds = .000014 hours .000014 hours * .02 additional kilowatt hours required by the active CPU = .00000028 kilowatt-hours So, an additional .00000028 kilowatt-hours are required by your one inefficient algorithm. Not bad, that only means .00000022 pounds of coal. But, that's just one algorithm, in one page load, by one user. If your website gets 10,000 page loads today, that number hops up to .0022 pounds of coal wasted. Yikes, that's getting a little scary! Over a year, that turns right back into that original .81 pounds of coal, enough to generate 1 kilowatt-hour of electricity, to power the additional CPU cycles required by that same inefficient algorithm. Again, that's just ONE algorithm, on one page on the web. Now, my brain is exhausted from all this math, but multiply this by the number of pages on the web, and the number of poorly written algorithms on a page, and you've got an awful lot of coal! Who votes that the windows task manager should have another column for "Coal Burned"!

You might also like