HTML6 Should Have Composeable Elements

Even in a well configured web-app that caches all static content appropriately, the vast majority of sites go back to the server to retrieve the HTML for a page every time. This seems like a flaw to me, as we are continually serving elements in the page that don’t change often and could be cached; but currently you can’t - it’s an all or nothing affair. So if there is something dynamic on the page, back to the server we go. I wish we could do this:

<!DOCTYPE html> 
<html> 
	<body> 
		<header src="/header"></header>
		<article src="/articles/1"></article>
		<footer src="/footer"></footer>
	</body>
</html>

It seems nuts that we treat all the elements on the page as a single unit. The contents of my header, article and footer may have different cacheability requirements; for instance my header may contain my name, which means that only I should be able to cache it, whilst an article could be cached for a few hours, whilst my footer changes infrequently and could be cached for a longer time. Our requests in the above example could have cache-control headers like this:

/header
Cache-Control: private, max-age=600

/articles/1
Cache-Control: public, max-age=7200

/footer
Cache-Control: public, max-age=86400

Now that that HTML page mainly contains placeholder elements, it could be cached too, as it doesn’t contain any user specific data. This is essentially donut caching – we’re caching all the bits around the bit that changes (in our example, the <header>)

To speed things up some more, if you route all your traffic through a CDN like Akamai, then you increase the chance of a first time visitor being served content from a cache (one of their edge servers, potentially located near them), meaning less traffic on your servers and a better experience for users. Even without a CDN, using a reverse proxy like nginx can help reduce load on your web-servers.

Can’t we just use IFrames?

No, this wouldn’t be the same thing. An IFrame is a completely isolated document hosted within another document, with it’s own DOM. What I want here is that all the composed elements forms a single document, with one DOM. If this was standardised, search engines could also treat all the content as one, i.e. it would fetch all the dependent content and treat the merged result as a single page.

Can’t we just use JavaScript?

Kind of. We could simulate composeable elements with the following;

<!DOCTYPE html> 
<html> 
	<head> 
	    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
	    <script src="composeable-elements.js"></script>

	</head>
	<body> 
		<header data-src="/header"></header>
		<article data-src="/articles/1"></article>
		<footer data-src="/footer"></footer>
	</body>
</html>
composeable-elements.js
$(document).ready(function(){
	// Find all elements that have a data-src attribute
	var elements = $("[data-src]");

	// For each one, perform a GET request and replace the element with the HTML in the response
	elements.each(function(){
		var element = $(this);
		$.get(element.data("src"), function(html){
			element.replaceWith(html);
		});
	});
});

This approach works, but has some down-sides:

  • A user without JavaScript will just see blank page.
  • A search engine will just see (and index) a blank page
  • To cater for both non-JS users and search engines, you would have to detect them and return a single HTML document in the traditional method.
  • The $(document).ready() event would loose it’s meaning. If you controlled every bit of JS on the page you could work around this by firing an event when all the dependant elements have been received, but if you used any external scripts or plugins that used $(document).ready, they would break.

I really do think this would be better handled by browsers in a standard way, and in a way to maintain backward compatibility. It’s in the spirit of the web, embraces http cacheability and would speed up the web by making more of the bytes that fly around cacheable.

Comments (2)

Paul
Interesting concept, but the backwards compatibility piece is going to be terrible. Despite Chrome and Firefox's hourly releases, there's still a large enough chunk of legacy traffic which makes this being truly usable only years after its release, which means no one will bother using it.
Thursday, 30 August 2012 23:53
Jono
Cheers for the comment Paul. You're right that there would be compatibility issues with older browsers, but isn't that the case now with some of the HTML5 elements that older version of IE don't support?

For many of them, we can provide reasonable work-arounds with JavaScript based polyfills, which I think we could do in this case, using script similar to that in my post (although there are draw-backs as I mention).

Another possibility would be to detect older browsers on the server and serve them the fully resolved content. Not the best solution, but it is doable.
Friday, 31 August 2012 08:10
Add a Comment