This is absolutely brilliant if the only metric your audience cares about is page load time. For most sites that's only part of the story.
Take the first paragraph, about how Google's homepage of just a textbox should really be a few hundred bytes instead of a megabyte. Google's homepage does a lot more than just enabling you to enter a search - there's the autosuggest feature, there's analytics, the apps tray, G+ integration with live updates, etc. Google's homepage looks basic but under the hood there's a lot going on. Which is the real crux of the matter - Google have designed something that doesn't get in the way of searching but is really a powerful portal to Google's suite of services because that's what gets them the data that makes them money. The fact they might be able to shave a milliseconds off the domContentLoaded time (which is only 394ms on my work PC) wouldn't make anyone happier but it would damage their bottom line because they'd know less about us.
If Jacques blog gets a significant amount more traffic by loading super fast then that's a definite, measurable success. If the only change is that it loads faster, and he doesn't grow his audience, then he hasn't really achieved anything.
There's a good lesson in this that's analogous to startups that spend huge amounts of time and money doing things that get them no additional customers. Optimising things that don't affect the metrics you use to measure how successful you're being is a waste of effort. Put your time in to things that actually matter.
While I agree with your comment about Google, I disagree with this one:
> If the only change is that it loads faster, and he doesn't grow his audience, then he hasn't really achieved anything.
If this makes his readers happier, it is a success nonetheless.
Maybe this is a startup/HN thing that everything must grow and grow. But that isn't the only successful strategy, even from a purely economic point of view.
If you have a niche, and serve that niche very well, you can beat your competitors by quality rather than quantity. Not all niches are large. If you manage to cover 100% of your niche, it is a huge success! - even if 100% means just a few thousand people.
load time is not a success factor in and of itself. Fast load times for bad content will not lead to success as little as really great content with horrible load times. But that being said, I am a proponent of significantly prioritizing load times over everything else. Load time should be a constant multiplier in decisions. If a "great feature" significantly taxes load time it needs to either die or be optimized.
The google homepage doing a lot more was pointed out earlier, I've updated the page to reflect that.
> If Jacques blog gets a significant amount more traffic by loading super fast then that's a definite, measurable success. If the only change is that it loads faster, and he doesn't grow his audience, then he hasn't really achieved anything.
If audience growth were the target, then yes that's true. But what matters too is that the audience that you already have does not spend more money (downloaded bytes on mobile for instance) or time (delay time waiting for stuff to load) than they really need to. On top of that I suspect (but can't prove) that a faster site will lead to people viewing more pages on that same site simply because of the convenience. For ad driven sites (which this is definitely not) that might turn into more turnover, and for e-commerce sites (which there is plenty of proof for) faster load times result in more turnover.
Keeping your users happy is important, even if you don't attract more of them directly. (Retention is a very important factor in a growth strategy...)
Premature optimization is definitely the root of all evil, but bloat is something you can do without. It's a matter of striking the right balance and I think that this blog probably is on the 'wrong' side of that balance but I just wanted to make an example of how much bloat there really is.
"On top of that I suspect (but can't prove) that a faster site will lead to people viewing more pages on that same site simply because of the convenience."
I'm reasonably sure that this theory is backed up by data. I don't have the time to look up the studies just now, but as someone with a professional interest in this, I'm pretty sure I've seen them in the past.
Certainly, page speed has a surprisingly large impact on overall user experience - backed up by studies like Amazon's and Google's, both of which showed a correlation between faster page load and increased user activity.
Just an anecdotal evidence, I open fefe's blog (http://blog.fefe.de/), which is quite popular in the German hacker scene, several times a day, often just to check whether the data connection is working, since it's so basic and loads instantly.
On the other hand, I don’t personally want autosuggest, analytics, G+ integration, live updates, an apps tray, or any of the rest.
For me, Google’s homepage circa 2005 was just as useful as the current one (or more useful even, since their results weren’t as crapped up by SEO spam sites, and the search syntax itself was more power-user friendly and predictable).
I used to occasionally click google ads, but they’ve gotten so obnoxious that I just zap the domain in /etc/hosts. I used to exclusively use google search, but it’s gotten slow and annoying enough that I now mostly use duckduckgo instead.
Clearly that’s not the main part of their user base, but spending a decade chasing money at the expense of user experience isn’t all upside, even for Google.
If you don't want that, make your own Google page. Create a form with get-action to google.com, parameter q, host this on your own site or even locally, and you've got that fast simple page that doesn't register your typing.
Brilliant! I have been planning to do the same with youtube (in combination with youtube-dl) but kept postponing it. Your comment might give me the final motivation I need.
>If the only change is that it loads faster, and he doesn't grow his audience, then he hasn't really achieved anything.
Sure he has achieved something. He has made his readers a little bit happier. Presumably, he has also made himself a little bit happier. It's called progress.
I don't know, bloat is pretty important for mobile users.
I've managed to chisel an entire business out of providing content for a specific population of users that access that information frequently, as well as (due to Mobile data limits) demand small or minimal download sizes.
If there wasn't so much crud being transmitted I would be out an entire business, on the other hand, the entire internet would be a much nicer place
Wow, I read the following: "Have you ever stood behind a novice Internet user and watched how they browse the web and navigate through different sites? Most designers know that seeing their sites through the eyes of an average user is extremely good for spotting usability issues but most don’t spend the time to extend this research across other websites."
Before I had to scroll and the page shoots to the bottom. Talk about not knowing what you write about...
> I’m sure I can do better still, for instance the CSS block is still quite large (too many rules, not minified yet)
CSS doesn't minify particularly well since the class names, tag names, and attributes all have to stay in their full form. Basically it just ends up being removing extraneous whitespace.
However, ever since reading James Hague's post on "Extreme Formatting"[0], I've rather liked CSS without all the extra whitespace. For example, [1]. You can see all the rules at a glance, and while it's a bit weird at first, I think you can get used to it pretty quickly. But then again, I've always sort of thought APL/J/K are beautiful in their own way.
But if everything that could possibly reference a class or tag or attribute is inlined into the same file then you know exactly what the scope of your CSS is for that particular request. So it should be possible to minify even the names.
Hm. A minimizing post-processor for a webpage and all the resources that it loads. That's an interesting idea which means it has probably already been done.
Doesn't mean it's been done well, it's been done to the point it's usable to anyone other than the originator, or it's been done and subsequently published in a way that's available to the general public, though :)
Doesn't render nice in desktop browsers either. Once upon a time, at least that page would actually be a little easier on the eyes (and a bit uglier) thanks to Netscape's gray background. But the real kicker is that user stylesheets have gone the way of the dodo. There's no reason that page (as is) couldn't look better than most pdfs generated from LaTeX or what not. Sad, but true.
> Take the Google homepage. It’s a one liner text field and two buttons. It weighs in at a whopping 1170 kilobytes! That’s more than a megabyte for what technically should not take more than a few hundred bytes.
The Google homepage does a lot more than that. Since it is one of the most important pages for Google, I think that the engineers over there know what they are doing.
I don't think it is a good example of bloat.
>I positively hate bloat in all its forms. Take the Google homepage. It’s a one liner text field and two buttons. It weighs in at a whopping 1170 kilobytes! That’s more than a megabyte for what technically should not take more than a few hundred bytes.
That's because you didn't consider the business reasons behind it being 1170Kb.
If it was your "few hundrend bytes" design it would have sank the company (or only have worked in the early days, when VC money took care of lack of income sources).
I remember first seeing google and it seemed so amazingly clean and fast compared to AltaVista. We were using a 64k leased line into the small college I worked in at that time, and I had a 28k8 modem at home.
As we move to price per Gb of download from 'all you can eat' I think that page payload may become more important.
doesn't inlining the CSS make the page require more data in the long run? Especially if you're not changing it often
Browser caches solve a lot of things for us. Though you're still parsing a bunch of JS, google's front page is "only" fetching 56kb
Granted, this blog post is 13.5kb, but it doesn't have an entire search app embedded into it (with the whole search results automatically appearing thing, I imagine that inside that 56kb is pretty much all the code required for all of google's little widgets in the search results)
Anyways, always fun to see somebody go in and rip out as much cruft as possible
For small datasets[1], latency may dominate bitrate. So it may be advantageous to receive everything with a single request and a single response.
Also, if your blog doesn't change often, it will also be seldom visited[2]. So the browser cache may not help here - either due to cache invalidation, or because you changed a tiny bit of your CSS in the meantime.
[1] And honestly, from that perspective all blogs are small.
There is a small penalty but it does not seem to weigh up against the advantage of having all the data in one shot even on first page view on that site. Total overhead of the CSS 'in flight' is about 6.6K, versus doing another request which would require another round-trip to the server.
Inlining the CSS was considerably faster in all my tests.
> I'd expect in-lining the css to be a slight net loss once the data is cached
I expected that too but it didn't work out that way. I'm not sure why, possibly a cache lookup is still slower than reading the style info out of the same page. I don't know enough about the guts of a modern browser to make the call but the numbers aren't there.
In chrome, I'm getting extremely similar times for the two approaches without caching (I am in-network, so my roundtrips are ~1ms). With the style.css fully cached, I'm getting ~15ms faster on the sideband approach than with inline styles.
Can you expose your methodology, or are you using a common tool for testing these things?
It looks like inline performs better on firefox and not on chrome - I just made a bunch of attempts both ways, and I'm seeing cached sideband as significantly better on Chrome, and only roughly equal on firefox.
I was not expecting to see such a difference between the two browsers, but I'm not familiar enough with firefox to guess what's causing it :-\
>doesn't inlining the CSS make the page require more data in the long run? Especially if you're not changing it often
Browser caches solve a lot of things for us.
Apparently they don't. I remember reading 2-3 articles on the issue, and most things we'd expect to go there, don't even touch the browser cache.
Maybe for Google (a page we visit every day multiple times) that would be different, but for your average site the browser cache could as well be a forbidden zone with all the competition for the same limited resource.
As a data point: I skimmed the article once, clicked no links, and will likely never go to that site again in the next month. Browser caching won't help me.
Very zippy indeed! Have you thought about switching to nginx so you can get SPDY (and soon HTTP/2)? Also, Hugo is cool. I've evaluated it myself, but I have 8 years of WordPress archives -- ~500 posts -- and I worry about things like images, comments, etc.
Things like resource inlining are an antipattern in an HTTP/2 world. The stylesheet for example should not be inlined; the server should instead push the stylesheet out to the user agent proactively (typically three frames—a PUSH_PROMISE telling the client of the request that is being simulated, then a HEADERS and a DATA frame with the response).
The first time, the browser will receive it approximately as fast as the inlined version; subsequent times, there is no overhead, moreover browsers can load the stylesheet only once rather than needing to load it for every page.
Doing an import is hardly going to ruin your existing installation. Back up your blog and do the Jekyll import, and see if it’s worth switching to you. :)
The funny thing is I didn't even try! Just feels like common sense. Maybe since I've been doing web stuff since '95 its in my blood to keep things tiny and simple.
I think one of the major differences is in how the content is generated. The more software that is used to make the content the larger the pages will be. If you hand-craft your page it will automatically be small and fast.
I don't get it. Mine's pretty stripped down but I still get this: :(
PING hliyan.github.io:80 (http://hliyan.github.io):
connected to 103.245.222.133:80 (360 bytes), seq=0 time=525.96 ms
connected to 103.245.222.133:80 (360 bytes), seq=1 time=555.35 ms
Edit: Connecting from Sri Lanka though (not via Loon, just our regular old ISPs :)
7 requests, 300K, the other is 2 requests, 90K, mine is 1 request, 49K.
Your site is definitely better than most though.
Also, with respect to the numbers you quoted, those are much more related to how many hops the traffic has to traverse than how efficient your site is.
Is there that much of a difference between that and telling the browser to download and cache a common CSS file for the site? Assuming the common CSS doesn't have a lot of cruft in it.
It's mind boggling to me, as someone who was first introduced to web development in the days of gopher, that most fresh developers don't adequately understand simplicity, but also believe it's a-ok to glue a bunch of js & css libraries together and call it "good enough".
The first Java version of an internal app we had converted from Progress 4GL used Java Webstart to dynamically load & launch, and because of programmer laziness (and the 93 3rd party Java components they'd included) it literally took 3 minutes to launch. That was the point where the manager -- who was a better programmer than anyone in the team, but who had previously been hands-off -- stepped in and created some rules and instituted code reviews. Still, though, totally insane behavior by so many young web programmers.
Yes, that's what has kept me from minifying the HTML and the CSS, I figured that since gzip is already on on the server the benefit would be minimal anyway. I'll still try it just to see what difference it will make.
robertsky$ ping localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.051 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.042 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.049 ms
You could make it even faster by putting it on CloudFlare and setting a cache rule so that we keep it in cache all around the world. Then you'll get the advantage of fighting the speed of light as well.
I really enjoy trying to make things as bloat free as possible but also retaining some styling, unlike motherfuckingwebsite.com.
Many of my posts use images and I use Google Analytics so I made a text only one and disabled GA to see how it compares. With your trick of the inline stylesheet I got a massive speed improvement[0], down from about 100ms to between 60-70ms.
I too use Hugo. I host the site on a $10 VPS from digital ocean located in London, but I also use Cloudflare to speed up image delivery.
I'm not sure where your site is physically hosted but testing from Amsterdam we're pretty much the same given the 1KB page size difference.
It's really hard to argue with the basic idea. For my blog[1] it'd generally be about 6kB for the html + 1.5kB of CSS that'd be cached for return visitors (typically 15% of pageloads) + Google Analytics almost always from cache.
The "Recent Tweets" part of this site feels somehow at odds with the principles though. It's got nothing to do with the actual page, and has a really bad ratio of markup to content. Those 20 tweets are still 11kB uncompressed! It's also a very heavy visual element.
The goal was not 'minimum size per se' but 'minimum size while retaining all the elements of the old blog'. So yes, the 'recent tweets' (and the older posts) sections are at odds with a total minimalist style. But the whole idea was to not simply strip but to strip while maintaining all the old functionality.
I did some testing using http://yellowlab.tools/ to find the slow parts of http://www.clarkeology.com/blog/ and I'm pleased with the results so far.
Ditching jquery was quite a big win.
Having no content to speak of makes it fast too...
Surely you're throwing away some of the speed benefits of parallel requests by massively-inlining everything?
I'd be interested in seeing some waterfall charts comparing this setup with something that keeps the number of total requests small (say 3-5 requests) and evenly balanced. Particularly as we move toward HTTP2, having lots of small parallel requests will be a more effective way of getting raw page load performance.
The speed gains from eliminating all but the most necessary components is definitely the biggest win here, though - cool to see what you can do when you decide to get focused about what needs to be on the page.
I expected that to be the case but repeated measurements tell me that it is in fact the opposite. The difference was about 50% faster on the version with everything inlined. Counter-intuitive for sure!
For instance, just taking the CSS out and loading that separately doubled the page rendering time (because another resource had to be loaded after the first one).
Now it is just like a 'declare before use' program in a regular programming language, by the time the browser reaches a tag that needs definitions from the CSS the CSS is already there, right there in the page, no need to wait until reading that separate resource is done. And that round-trip to the server is actually more expensive than the entire embedded CSS. Looking at it after going through the whole exercise it makes sense but that was definitely not what I expected. Even more counter-intuitive: this holds even when loading multiple pages on the same site that share the same (small) CSS file.
So in the end the inlining of the CSS was a good thing to test. Presumably, there is some cross over point where if the CSS file gets very large there is a benefit for follow-up pages on the same site to be able to re-use it.
A couple of Hugo questions Jacques, and please don't tell me to RTFM!
Is there a way to instruct Hugo that once a crossover point is reached to unbundle the CSS? That'd be sweet.
Is there a way to concatenate multiple Markdown files into a single post?
The reason I ask is because I've recently started building a site that has weird hand-rolled static Markdown pages served up dynamically by a Rails/Bootstrap combo. The kicker, some of the pages are very long so I've split them up into multiple files to make them cognitively easier to edit. I'd be interested if I could drop the Rails part :)
Thx in advance
ps: I'm now too afraid to measure the page load times of my Wordpress blog now :(
> Is there a way to instruct Hugo that once a crossover point is reached to unbundle the CSS?
Not that I'm aware of, Hugo is pretty much of the 'sausage grinder' variety of blog post generators, not much in terms of decision making during the processing from what I've seen so far. I also ran into a pretty serious bug while doing this and there are likely more. Still, as fresh as it is it performs amazingly well and the authors are super helpful and worked hard to track down and fix that bug.
> Is there a way to concatenate multiple Markdown files into a single post?
Again, not from within hugo but that one should be fixable with some pre-processing. I use a makefile that does some pre and post processing.
> I'm now too afraid to measure the page load times of my Wordpress blog now :(
Do it anyway, that will give you a nice before-and-after benchmark.
> Even more counter-intuitive: this holds even when loading multiple pages on the same site that share the same (small) CSS file.
Did you verify that the cache headers where correct, and that the CSS file was only loaded once? It's certainly possible, but indeed surprising (to me) if the actual overhead of parsing the html (and then the css - 2x render time) is that big?
[ed: Did you see the same pattern using local static files?]
Yes, absolutely. You can easily verify this for yourself if you want with a simple page with embedded CSS and one with the CSS included from a file.
The configuration line reads:
ExpiresByType text/css "access plus 1 week"
And I verified that it worked using a commandline http tool as well as the firefox developer tools (network section), on the second view it only loaded the page and not the CSS.
> Surely you're throwing away some of the speed benefits of parallel requests by massively-inlining everything?
When you're loading less than 20KB of content, I don't think there are any speed benefits of parallel requests. I suppose in theory an extremely slow mobile connection might benefit, but extremely slow mobile connections tend to have very high latency and packet loss that make the cost of additional requests hugely outweigh the benefits.
Also, remember that each request is actually not running in parallel. (for example, the css can not be retrieved until the html has been received by the client and parsed) Also, each of those parallel requests have their own overhead (connection, server response time, then downloading)
So while intuitively, the parallel request seem like the faster option, it's probably likely in this case, that the single page in-lined option is optimal. (Even at the expense of ever so slightly more bandwidth)
> inlined the stylesheet (there is a cache penalty here so you have to trim it down as much as possible but the page starts rendering immediately which is a huge gain at the cost of a little bit of extra data transferred)
I guess you're optimizing for people who only visit one page and bounce away?
Well, come to think of it, the majority of visitors who followed this HN link is never going to navigate past the single page that was linked. So it probably makes sense for optimize for them, at the expense of repeat visitors who will have to download the stylesheet over and over again.
By my measurements (and pagespeed and a couple of other tools like that) it's actually faster for repeat visits and multiple pages on the same site as well (which surprised me but I'll yield when the data is that conclusive).
How does my blog compare? I submitted this link to Hacker News yesterday. It's quite an image heavy page but I think (I hope!) it loads quite fast for most users. It obviously won't be as fast as a text-only page. There are no fancy optimisation tricks. Just plain HTML and CSS and a tiny bit of Javascript (for older browsers). Not responsive either, but readable on mobile.
That's pretty good actually. You're very heavy on visuals but that's to be expected given the nature of the page and the only things you could do to make it faster are to lose the font and inline the CSS, but likely the gains in your case would be minimal so I'd just leave it as it is. Good job!
I've seen this blog, jacquesmattheij.com several times on HN and every time I try to access it I get 403 Forbidden. What gives? It's not very fast either...
It's great to see focus on performance, especially after all the recent stories on web bloat.
I've noted a few techniques I've used on my blog to get pages served in a single request to users, including using SSIs and avoid cloudflare's "rocket loader"
2. Using Hugo instead of Octopress won't make your site any faster to users ¯\_(ツ)_/¯
3. You're almost completely forgetting about server-side performance. I'd recommend looking into GitHub Pages for a free and fast (CDN-backed) way to host a static site.
---
Unrelated, but:
4. I'm not a fan at all of the self-upvoting link at the bottom of your post. Not cool.
> I’m sure I can do better still, for instance the CSS block is still quite large (too many rules, not minified yet)
You could try out Addy Osmani's tool, Critical, for extracting and inlining critical path css. That only leaves out the css in actual use. If you actually want all css in use (also below the fold), then just specify a bigger window size.
@jacquesm are you sending compressed files ? I can't check that myself with my iPad 1. I'm in a camping with a bad WiFi. I can confirm that I saw and felt the difference ! Congratulations.
Plain old apache but tuned very well on a massive server (32 cores, 96G of RAM), the server is actually the production server for a high traffic website and this is just piggy-backed onto the site as a 'servername' entry in the apache config. If I shut down the other site then blog will be quite a bit faster still but that seems counterproductive ;)
That will probably load really fast. You can server-side cache the post comments section fragment (or the render of the entire page really) to get nice results
Make a script that adds the comments to the static page. I made a small static site generator that has comments, search, etc. for my own use. https://github.com/Harri/Spage
I'll have a look to see what the differences are, gzip is already enabled so it might be less than on a site that sends all the data in plaintext over the wire.
Also, you could cut down the size slightly by shrinking div names. Sure, with gzip "aside.sidebar" isn't going to take much extra space, but it will take some.
(That being said, please don't do this. Minified JS is bad enough.)
I think I'm pretty close to the 'sweet spot' where further optimizations are both a waste of time and make the result much less useful in the longer term. But just for the sake of research I'm more than willing to play around to see what happens.
I'm still at the stage of dropping rules that aren't used. CSS tends to get pretty inefficient if enough people have hacked on the file and the one on my site is no exception to that. It'll still need some work. But even that is already in the realm of 'diminishing returns on investment'.
Take the first paragraph, about how Google's homepage of just a textbox should really be a few hundred bytes instead of a megabyte. Google's homepage does a lot more than just enabling you to enter a search - there's the autosuggest feature, there's analytics, the apps tray, G+ integration with live updates, etc. Google's homepage looks basic but under the hood there's a lot going on. Which is the real crux of the matter - Google have designed something that doesn't get in the way of searching but is really a powerful portal to Google's suite of services because that's what gets them the data that makes them money. The fact they might be able to shave a milliseconds off the domContentLoaded time (which is only 394ms on my work PC) wouldn't make anyone happier but it would damage their bottom line because they'd know less about us.
If Jacques blog gets a significant amount more traffic by loading super fast then that's a definite, measurable success. If the only change is that it loads faster, and he doesn't grow his audience, then he hasn't really achieved anything.
There's a good lesson in this that's analogous to startups that spend huge amounts of time and money doing things that get them no additional customers. Optimising things that don't affect the metrics you use to measure how successful you're being is a waste of effort. Put your time in to things that actually matter.