A couple years back
when I started getting interested in Single Page Application [buzzword
detected] techniques I was looking at using templates and sending JSON data in
order to separate fixed markup from volatile data. In the context of what I was
working on this reduced the amount of data going over the wire. There was a lot
of repeated markup and using a single template bound to JSON meant the markup
was sent once as opposed to once per data object in the JSON.
One thing I wanted
to do, but didn't have time for, was to take the next step. To store those
templates in local storage and cache them so subsequent requests wouldn't have
to refetch the templates. So I have started to look a little at Silo and I felt
like I would blog some of my thoughts about web performance.
How do you improve
web performance? Big question, but there are two main answers. One, make fewer
requests. Two, cache stuff. The fewer request answer includes things like
combining your images (CSS Sprites) and bundling your JavaScript and CSS. Cache
stuff includes thing like moving your JavaScript and CSS into js and css files
and setting up your cache headers correctly. Pretty basic advice you will find
if you look at Yahoo's (Yslow) and Google's (PageSpeed) recommendations.
So maybe you detect
a fundamental problem? You should make fewer requests by combining everything
together. But you should also make lots of fine grained requests to maximize
what you can cache. Doh! The essential issue is that caching is based on requests.
So you have fighting goals of maximizing cacheability and minimizing requests.
Hey, how about we control the caching ourselves?!?!? HTML5 web storage is
supported in almost every browser, and if you are dedicated to supporting IE6
and IE7 (browsers that Microsoft has told people not to use) there is a funky
data storage thing you could potentially use. Personally I am of the camp that
you shouldn't try to support every browser. But that is a vitriolic rant for
another day…
James Micken (Google
"Funniest man at Microsoft Research") has been doing research around
this and has come up with a Silo system. So his idea is that you combine
everything on your page into one big file and you do a single request. You then
have an automated tool divide this giant page into chunks and you store your
chunks. You send chunk ids in a cookie when you request the page and the server
creates a new page, but then only sends back the chunks that are needed. So
this is very cool and James is a goofy presenter so his presentations are worth
watching, but I have a couple issues with this.
One is that going
down to a single request may not be that great. Browsers tend to use four
request threads and I have seen some evidence that multiple downloading threads
increase the efficiency of your download. The other is that the biggest
advantage of caching certain requests is that they can be reused on other
pages. I am mainly thinking about JavaScript and CSS, but like I mentioned at
the beginning templates could also be stored. Most sites I have worked on have
JavaScript and CSS files that are used on multiple pages. Combining them into a
snigle page via Silo means they are going to be sent more than is necessary.
So Silo is cool
because you don't really have to worry about the caching. You just build a page
with everything on it and then an automated system will take care of the
caching mechanism, but I think you can get better results if you ask the web
developer to do some thinking and divide their project. You can also get a lot
of improvements if you view a webpage as a SPA and separate fixed markup from
volatile content. Silo has a system which caches non-volatile chunks, but it
has no real notion of which chunks are volatile. Also Silo ignores savings
between pages. For example, most web site have a header that appears on every
page. This basically static header is
often sent over and over and this really is a waste.
So imagine dividing
your page up into 4 categories: JavaScript, CSS, Templates of Markup, Volatile
Data as JSON. So you can see that three of those things do not change much and
three of them may be used by multiple pages.
You can also use
interesting techniques of loading the pieces of the next page while you are on
the first page. Or if you are using a pure SPA approach you can delay loading
pieces of the page that may not initially appear. Okay I will walk through the
basic pattern.
Client: Request with Empty Cookie
Server: Page returns with JavaScript
shim and a series of Templates, JavaScript sections, Style sections. Each
section has and associated ID
Client: JavaScript shim constructs
page from sections and stores sections in web storage and tells cookie what
sections it has stored. After the page is built the client starts loading
sections for other pages and stores them in web storage and their ids in the
cookie.
Server: Responds to these behind the
scenes request with sections.
Client: User decides to navigate to a
new page and sends a request with a cookie full of Ids.
Server: Server again passes back a
JavaScript shim and a series of sections whose ids are not present in the
cookie
Now, it is fairly
trivial to attach version identifiers the the ids in question to handle updates
in your code.
I think techniques
like this will become more and more common and I will work more on the nuts and
bolts later.
No comments:
Post a Comment