Playing HTML Jenga

I recently had a peek at Google's source code and was surprised to see that their HTML seemed invalid!

The first thing I noticed was the lack of closing tags on both the <body> and the <html> tags!

I tried this out myself and ran it through a validator. The following code passed as being valid HTML5:

<!DOCTYPE html>
<html>
<head>
<title>Lorem Ipsum</title>
</head>
<body>
  <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>

  <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in</p>

This piqued my curiosity enough for me to ask: How many tags can I remove without the whole thing falling apart? A game I like to call HTML Jenga

Next, I removed the closing tags on the two paragraphs. Again, the following code still passes as valid HTML5:

<!DOCTYPE html>
<html>
<head>
  <title>Lorem Ipsum</title>
</head>
<body>
  <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

  <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in

Next thing to go was the closing tag for the head. Again, still valid!

Cut to the chase!

In the end, I removed the <html>, <head> and <body> tags completely and this still passed as valid html! Surprisingly, the only two tags that were required were the doctype definition and the <title>.

<!DOCTYPE html>
<title>Lorem Ipsum</title>


  <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

  <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in

Even more surprising was the fact that Chrome and Safari both knew what to do with this code and were smart enough to insert the missing tags into the DOM as the page was loaded. (You can check this yourself using the Developer tools). Any tags that usually appear in the head, for example <script>, <meta> or <link> tags were all wrapped in a <head> tag by the browser. Similarly, as soon as a page content tag such as a <div> or <p> tag was encountered, the browser was smart enough to close the head and open the body.

Playing HTML Jenga with your own website.

Playing HTML Jenga was a fun learning exercise and encouraged me to read more about both HTML5 standards and also how modern browsers work. I would have reservations about applying it to a live website though... Google strip out their closing <body> and <html> tags and I guess if Google does it you can be sure that it will be safe for most browsers. However, I've yet to test out the rest of the tag-pruning in older browsers and would not be surprised if they resulted in some strange rendering issues. Also, unless you're dealing with massive volumes of traffic like Google do, there's really nothing to gain from hacking back your HTML for the sake of a few bytes.

Also, having written XHTML for so long, I've grown comfortable with closing all of my tags and having markup that is easier to read and follow. Moving back to open HTML tags will take some getting used to.

Give this a try and check out the HTML5 specification too!

0 comments

Link Prefetching with HTML 5 and jQuery

HTML5 offers a cool new feature called link prefetching. Link Prefetching allows developers to specify resources (such as another page or an image) that can be preloaded when a user visits a page, so that they can be rendered faster when/if they are requested.

If, for example, you have a blog then you can logically assume that when someone visits your blog's homepage, they'll probably click on one of the first few links to posts too. In your blog's homepage HTML code, you could simply add the following tag for each blog post you would like to prefetch:

<link rel=prefetch href="http://myblog.com/posts/blog-post-url.html" />

When a compatible browser loads the homepage it will also try to load http://myblog.com/posts/blog-post-url.html too!

However, hard-coding links for each post like this is not ideal. If, like a blog, your website serves dynamic content then it may not be possible to know the urls in advance and constantly updating your HTML when a change is made would be tiring.

Instead, it would be better if we could do this dynamically using Javascript and jQuery.

Check out the following snippet:

// create an object named "app" which we can define methods on
var app = {
    // returns an array of each url to prefetch
    prefetchLinks: function(){
        // returns an array of each a.prefetch link's href
        var hrefs = $("a.prefetch").map(function(index, domElement){
            return $(this).attr("href");
        });
        // returns the array of hrefs without duplicates
        return $.unique(hrefs);
    },

    // adds a link tag to the document head for each of prefetchLinks()
    addPrefetchTags: function(){
        // for each prefetchLinks() ...
        this.prefetchLinks().each(function(index,Element){
            // create a link element...
            $("<link />", {
                // with rel=prefetch and href=Element...
                rel: "prefetch", href: Element
                // and append it to the end of the document head
            }).appendTo("head");            
        });
    },
}
// when the document is ready...
jQuery(function(){
  // call the method we defined above.
    app.addPrefetchTags();
}

I'll explain what's happening here in order of when it happens:

Once the DOM is ready, we look for each link ( <a> tag ) with class "prefetch". Next we stick each <a> tag's href (the url of the page we want to preload) in to an array. Because a link to the same page may appear more than once per page, we call $.unique() to remove any duplicates from this array.

Now we have an array of urls to prefetch, we simply create a new link tag for each on with rel="prefetch" and href="url-to-prefetch" and append it to the end of the head tag.

Now, within your code, simply add class="prefetch" to any link which you would like to improve the load speed on.

Ruby On Rails Helper Method

If you're using Ruby on Rails, I've written a simple helper method to make light work of adding prefetch links to your templates:

# add me to application_helper.rb
# <%= prefetch_link_to("click me", root_url) %> # => <a href="/" class="prefetch">click me</a>
def prefetch_link_to(name, path, options = {})
  options[:class] = options[:class] ? "#{options[:class]} prefetch" : "prefetch"
  link_to(name, path, options)
end

This can be used just like Rails's link_to method to create links with class="prefetch".

Some tips and caveats.

Prefetching can be a really effective way of speeding up your web page but, like Uncle Ben said "With great power...". Here are a few things to keep in mind:

  • Only use prefetching to fetch pages that you believe will receive most traffic. Things like a Terms of Use or Legal page will be rarely visited and, if they are, it will be by someone who is intent on reading and wont mind waiting an extra few milliseconds.
  • Prefetching can be used behind the scenes to load large images that are not immediately visible. For example, if you're using lightbox then you can prefetch full-sized images ahead of their thumbnails being clicked on.
  • Prefetching can screw up your visitor stats. If every page your visitors load also prefetches two or three other pages you can expect your visitor stats to grow. This will produce unreliable data. Because only the HTML is fetched though, I believe Google Analytics and other JS-based stat-reports should not be effected.
  • Don't prefetch external pages. You're not a charity (unless you are a charity)! Using prefetching on links that take visitors away from your site is only helping to take visitors away from your site faster!
1 comment