nooshu - Matt Hobbs' Web Development Blog

Kneeling on the shoulders of giants

Plotting the Lorenz Attractor using three.js

It’s been a while since I dabbled with three.js. There have been a few API changes, so it’s slightly different from what I remember. That being said it’s still as fun to use, and there are even a few API docs available (not sure if they are fully up to date though)! I happened to be reading an article on Chaos Theory and the “butterfly effect” which mentioned a lovely set of equations; the Lorenz Equations, also known as the Lorenz oscillator. So I decided to investigate further. Here they are in all their glory:

\begin{aligned}\dot{x} & = \sigma(y-x) \\ \dot{y} & = \rho x - y - xz \\ \dot{z} & = -\beta z + xy \end{aligned}

So what exactly is the Lorenz oscillator? Well to quote from Wikipedia “The Lorenz oscillator is a 3-dimensional dynamical system that exhibits chaotic flow, noted for its figure eight shape.”. What this really boils down to is how even very small change in the equations initial conditions (x, y and z) causes large changes over time, in a complex and non-repeating pattern. There’s a famous title of a talk given in 1972 by Philip Merilees:

Does the flap of a butterfly’s wings in Brazil set off a tornado in Texas?

The butterfly flapping its wings introduces slight changes to the initial conditions, creating a chain of events that lead to a tornado in Texas. The Lorenz butterfly is a graphical way of showing these changes over time on a much smaller scale.

I’ve created a demo that allows you to change variables related to the Lorenz butterfly and observe the effect it has on the system.

Example of my Lorenz attractor demo in action

Adjust the demo variables to see how the Lorenz butterfly changes.

There are a few variables you can play to change how the Lorenz attractor is rendered:

  • rhoValue: Called the Rayleigh number. Rho of value 28 shows chaotic behavior. Other values show periodic orbits.
  • showAxis: Allows you to turn the x, y, z (red, green, blue) axis on for reference.
  • randomStart: Picks a random initial conditions, rather than 0, 0, 0.
  • totalTime: The total time (or number of iterations performed) when generating the graph. Higher numbers equals more lines and increases the render time.
  • timeIncriment: The accuracy of the graph depends on the number of points plotted. A lower number creates a smoother graph but increases render time.
  • colorModifier: Simply changes the colo(u)r. Pointless but pretty!

While rendering a larger number of points, I noticed the browser lock-up for a second or so. This was because the points were being calculated on the browsers UI thread. Luckily modern browsers support thread like message passing in the form of the Web Workers API. By offloading the point calculation to its own thread (lorenzPoints.js), I was able to stop the nasty UI freeze. Unfortunately you are fairly limited with what you can pass back and forth between workers. It was possible to generate the three.js geometry in the worker thread thanks to the importScripts() method. I tried passing the three.js geometry back to the browser but all the methods were stripped out, leading to lots of errors (JSON issues). In the end I dropped back to calculating the points in the worker, pushing them into an array and generating the geometry on the main browser thread.

It was good fun dabbling with three.js, Web Workers and dat.gui again. Now on to my next project… View the demo here.

Writing efficient CSS selectors

With modern browsers getting quicker with every new version number it’s easy to fall into the trap of writing inefficient code. A page will run super quick on the latest version on Chrome or Firefox, but you also have to consider older browsers and mobile devices. That shiny new web application that uses some super fancy CSS selectors may be unusable on certain devices due to its limited hardware. That’s not to say you shouldn’t be using super fancy selectors; you just have to be careful to consider your target audience, and use them in the most efficient way possible.

The first thing to note about CSS selectors is they don’t work in the way you’d expect. In the west we read a page from left to right. Reading a CSS selector, you’d expect that’s what the browser does as well. Wrong! The browser actually reads a selector from right to left (in Mozilla’s case anyway, and most likely in others too). So take the following CSS as an example:

1
2
3
4
5
body #wrapper .article ul.meta li a {
    font-weight: 700;
    text-decoration: none;
    font-family: Arial;
}

The browser first looks for all the anchor tags (called the “key” as it’s the rightmost selector), then looks at the list items, it evaluates those and throws away the results that don’t match. Next the browser moves onto elements with a class of “meta”, throwing out results that don’t match and so on… you get the idea! There’s so much redundancy in the above selector, it could easily be cut down to:

1
2
3
4
5
.meta a {
    font-weight: 700;
    text-decoration: none;
    font-family: Arial;
}

This example is much more efficient. There are less rules for the browser to evaluate, it’s much easier to read and if you apply minimal selectors across your whole stylesheet you will notice a big difference in file size. The key to writing efficient selectors is to be as specific as possible. Whatever you do don’t write this:

1
2
3
4
body * {
    margin: 0;
    padding: 0;
}

The universal selector(*) is bad (even body isn’t needed)! You are targeting every single element in the DOM and setting it’s padding and margin to zero. For a large page that could easily be thousands of elements!

I actually inspected the stylesheet for this website and went over it with a fine tooth comb. I found many additional selectors that just weren’t needed. The size of my stylesheet went from 18.3kB down to 16.5kB, a saving of 1.8kB. It doesn’t sound a lot in terms of file size, but that’s a whole lot of selectors the browser no longer has to evaluate to render the page.

Luckily there are tools available that can help you make your CSS more efficient, as well as many other areas of your website too. The first tool I’d recommend is called Page Speed, created by Google. The Page Speed extension is available on both Chrome and Firefox. Once installed you have the option to run it on any page; it will give you an overall score for that page and recommendations on how to improve it.

Google Page Speed results for Nooshu.com.

Page Speed results for this site. Note the "Use efficient CSS selectors" drop down.

The second tool I’d recommend is Opera’s Dragonfly. Dragonfly (similar to Firebug, in name at least) is Opera’s developer toolkit, much like Web Inspector for Chrome. An awesome feature that Dragonfly has, that other toolkits don’t is “style recalculation”. Style recalculation gives you a breakdown of all the selectors that were run on the page, how long they took to evaluate and how many elements they hit along the way (hits).

Opera's Dragonfly debugger in action on nooshu.com.

Dragonfly gives you an extremely useful breakdown of what selectors were used and how long they took to evaluate.

If you look closely at the results in the image above, you will see that the selectors with the most number of hits are the ones involving the universal selector(*), as you would expect. You may also notice that most of the timings say 0.0ms which isn’t very helpful. This is due to the fact that the size of the DOM being tested is very small, and timing to 1 decimal place isn’t accurate enough to show the actual time it took to evaluate. If you were to run this test on a huge page, say the HTML5 Specification for example, you would really be able see the difference in CSS selector efficiency.

This feature of Dragonfly is very new and is still in testing. There are a few issues still to be ironed out in future releases but it’s definitely a tool to keep in your bookmarks.

A word of warning when it comes to writing efficient selectors. I found myself trying to make the selectors so efficient it was becoming quite hard to pin-point where exactly on the site they were being used. If you have a very specific area of a site you are trying to target, it is easier to read if you have the selectors starting with an ID reflecting that area. You then know for certain that the changes you make won’t affect other parts of the site. Also remember that removing “unused” selectors will affect the specificity of the rule. You could end up breaking something, as what you thought was an unused selector was actually used in overriding another rule.

Having too many descendent selectors is something that Page Speed frowns upon, but as with all things in life it’s a case of finding that happy medium. In this case it’s between efficient selectors and CSS that is easy to read and maintain (for you and other developers).

Design for Developers

As a developer I must admit I find design hard! Open up a blank PSD in Photoshop and I come out in a cold sweat. More often than not a developer will quickly construct an application, get it working and dump everything on a page. The application works, but it’s horrible to look at and is very unintuitive to use. Thankfully, a designer by the name of Johan Ronsse has put together a presentation aimed at developers who are looking to improve their design skills.

The presentation has some excellent content on what you should (and shouldn’t) do with an interface design. Basics on fonts, colours, shadows and icons are all explained in a clear and concise way. For those wishing to continue with their new-found design skills, slide number 179 has a long list of links and books to read. My personal favourite is the simple, yet effective Grid Calculator tool. I’ve read many articles on the grid system, but have never used it. This handy website does all the mundane maths for you, allowing you to get back to making your application look pretty!

Big thank you to Johan for the presentation, every developer should read it at least once (or bookmark it to read later)!

Embracing Git for version control

For many years I’ve been using Subversion (SVN) as my version control of choice. It’s been a part of my deployment process, all of my work is in Subversion, even the small demos I’ve created are in a repository. It’s a good feeling to know that if your laptop dies (or is stolen), all your work is backed up on a remote server.

Recently I’ve heard many developers raving about Git, and I’ve looked at libraries and code snippets that are using it, so I thought I’d check it out and see what all the fuss is about. After a couple of hours reading up and watching a few tutorials I’m genuinely excited about using it in future projects. It really is that good! So, what’s so good about it then you may ask? Well here are a few points that stood out for me:

  • Easy to install and start using (Windows has a simple installer)
  • Distributed version control, so no need for a central server
  • Runs on your local machine, no need to connected to the internet to commit(!)
  • Very clean, it only creates one git directory for the whole repository (no hidden .svn’s everywhere)
  • Incredibly easy to branch and merge your code (this is a big plus!)
  • It’s simple to use Git with SVN, no need to abandon your SVN repositories. Git can pull & push directly into an existing SVN repository!

I’d heard developers saying how easy it was to branch and merge your code using Git, I assumed they were exaggerating. But no, it really is simple:

1
2
3
4
5
6
7
8
#create a new branch in my repository
git branch my_new_branch

#move to the new branch for commits etc
git checkout my_new_branch

#finished with the branch, so lets merge it back into master
git merge my_new_branch

One of the most amazing parts of Git that blew me away: when you jump between branches it automatically updates your file structure accordingly! So lets say you have a new set of files in a new branch, and you need to jump back to master (trunk) to make some changes. Simply run ‘git checkout master’, the new branch files will be ‘removed’ and stored away until you are back on the new branch where they were added. Amazing!

The feature that really sold Git to me was the stash command. So many times I’ve been working on a project and got half way through some changes, only to have to fix a bug in the original version. So you copy the modified files somewhere, undo all your changes, fix the bug, copy the files over and start where you left off. Not fun! Git and the stash command come to the rescue:

1
2
3
4
5
6
#store your current changes in a 'clipboard' so they can be seen again later
git stash

#you are now working on the unmodified version of the branch
#after you've fixed the issue, start from where you left off by applying the stash
git stash apply

Another huge advantage Git has is how simple it is to share code between developers. It only takes a couple of commands to clone another repository. Once you have a local copy (clone), you can change whatever you like. Make the project better (or break it horribly, it’s up to you). For an example of how powerful social coding is take a look at Github. The 3D JavaScript library three.js for example has over 4000 people watching and 400+ people have forked (cloned) the repository. If your version adds a cool new feature or fixes a bug, it can easily be merged back into the original project!

If you are interested in learning how to use Git there are some superb resources available. For people who like screencasts I highly recommend watching the one created by Peepcode. It’s only $9 (US), 1 hour-long and will get you up and running with Git in no time at all! Here are some other resources I found useful:

Right, I’m off to start committing to a repository while travelling on a train to work when I don’t have an internet connection (warm fuzzy feeling enabled)!

Remote Loading HTML5 Elements with jQuery

I ran into a rather annoying problem a few months ago while developing my travel blog; the problem of course was involving Internet Explorer. I’m used to working with WordPress as I use it all the time, but I wanted to get away from the standard pagination you find on a blog. So I decided to use jQuery 1.6.4 to pull in articles from other pages (blogname.com/page/2, blogname.com/page/3 etc). Now this is all fairly simple using the handy jQuery .load() method; point it to a URL, pull in the page, pick the bits you need and reinsert into the page. Simple! Unfortunately once I got a prototype working in ‘good’ browsers, IE8 and below was having non of it!

After a little head scratching to work out what was failing, I worked out it was because I was using HTML5 elements such as ‘article’, ‘header’ and ‘footer’. There was no problem displaying them on the page, as I’d used Remy Sharps excellent HTML5 Shiv script. It only failed when trying to pull in these ‘new’ elements via Ajax.

Note: Before you read on you’ll be happy to hear that this issue no longer occurs in jQuery 1.7.0. Horray!

If you can’t upgrade, for whatever reason, I hashed together a little work-around for browsers IE8 and below, so read on. I admit the work around isn’t pretty, but it works. I tried for a few hours to get IE8- to recognise the ‘new’ elements after an Ajax request, but to no avail. Eventually I had to wrap the HTML5 tags in a div using conditionals:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--[if lt IE 9]><div id="ieHackContainer"><![endif]-->

<article id="html5Content">
    <header>
        <h2>H2 wrapped in a header element</h2>
    </header>
    <!-- Other HTML here... -->
    <footer>
        <p>This is the footer element</p>
    </footer>
</article>

<!--[if lt IE 9]></div><![endif]-->

The div is added for browsers IE8 and below, you can then use it as a hook to pull in the elements inside the div. I was hoping that wrapping the HTML5 elements in a standard div would be the end of it, I’m afraid not. The .load() method still didn’t work, IE just ignored the elements it didn’t recognise. I used jQuerys much more customisable .ajax() method to fix the issue in IE6, 7 and 8:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//IE8- work around to load HTML5 elements into a page
$("#loadHTML5LinkOld").click(function(){
        $.ajax({
                url: "page_to_load.html",
                cache: false,
                success: function(html){
                        var HTML;
                        //Clear before load
                        $("#html5LoadHolder").empty();
                       
                        //IE: Look for the hacky wrapper before insertion
                        HTML = $(html).filter("div#ieHackContainer").html();
                       
                        //If HTML var is empty assume using newer browsers
                        if(!HTML){
                                HTML = $(html).filter("#html5Content").html();
                        }
                       
                        //Append to page
                        $("#html5LoadHolder").append(HTML);
                }
        });
       
        return false;
});

This method works in all browsers I’ve tested in as I’ve added a fall back (or should that be forward?) for newer browsers. The solution isn’t ideal (I really hate the conditional comments), but older versions of IE aren’t going away any time soon, and it works. Maybe there’s a more obvious solution that I missed? Leave a comment if there is, I’d love to know!

You can see a working example here. The page I’m loading from is here and the JavaScript in full here.

Currently on page 1 of 2312345Last »