Show HN: JS library to make your website instant
It seems the internet architecture won't bring us instant websites anytime soon. So here is a hack.
I released this JS library last month (today is version 2.0 release, fixing v1.0's rough edges), it makes use of HTML5's pushState and preloading to make a website instant.
It works like this: before clicking on a link, you'll hover over it. And there's a delay of 200-300 ms between these two events. InstantClick uses this delay to preload a page, when you click on a link it will display instantly in most case. (You can test on the website.)
That's similar to pjax and Turbolinks, for it uses HTML5's pushState and Ajax. And preloading is thrown into the mix.
In case preloading all the links that a user hover over is too much work for the server, there's also an option to set a delay before preloading kicks in, or to preload on "mousedown". Mousedown is when you press your mouse button (a click is when you release it). This way you still get a slight "magical" speed advantage, and pjax's benefits (notably, no recalculation of scripts/styles on every page change).
For mobile it preloads on touchstart, so you get 400 ms to preload. This is different from FastClick: with InstantClick a user can still double tap to zoom without triggering a link.
As said in the first sentence, the internet architecture can't bring us instant websites today or tomorrow. So I think this — InstantClick — could be a pretty big thing to improve the situation at scale.
The main challenge I see is that existing JS scripts may not work with it out of the box. I don't do much web development nowadays though, so I don't know how big of a problem that is, and I don't know if there isn't any other major barrier in the way to make this mainstream.
That's why I'm awaiting your opinion, smart folks of HN.
180 comments
[ 19.0 ms ] story [ 834 ms ] threadWell, in a way all sites already do that by embedding resources from different urls.
And probably a ton of other application bugs as style and script stuff wont load. like they normally would
Maybe blacklist any links with the words logout, delete, etc anywhere inside the a tag or in the attributes?
If one is worried about preloading links that triggers an action, there is a whitelist mode to enable links as you review them.
But i do concur.
What's your point? Google must be incapable of poor design? Everything a big company does is good?
Also, full disclosure: I work for Google.
"X-Frame-Options" is used to defend against click-jacking attacks, not to defend against CSRF.
This is the very essence of the problem.
Someone sends you a link, you click it, it loads in your web browser telling you that you've sent them $5000. That is why POST, PUT, OPTIONS, and all the other methods exist.
This is most certainly poorly designed. Just because most web apps and web app developers suck doesn't mean that the freaking HTTP Standard should be changed.
Just no... please stop.
It definitely should not be a GET, since good practice says that GET is idempotent (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html)
Nobody ever follows this since we all want stuff like www.example.com/articles/latest to respond to GET and also have different content depending on time. The distinction is at the core of the REST abstraction and it's an art.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1...
Oh, but as a postscript, one little HATEOAS bonus tweak:
It would be great to not have to start from scratch of every web project (even if you you are using a library as you should you often are coming up with the urls for each action.)
Can you expand this with support for password recovery, oauth-like flows, JWT, etc?
Roy Fielding thinks that server-side sessions violate the REST constraint. https://groups.yahoo.com/neo/groups/rest-discuss/conversatio...
Some people (maybe you) think he's wrong; why can't sessions just be a resource? (And this just goes to show that nobody knows what "REST" really means, and that this question doesn't matter.)
But if you're willing to treat sessions as resources, there are good security reasons to use cookies to refer to them, ideally in addition to a separate non-cookie ID parameter, to prevent CSRF attacks.
Cookies have some performance benefits, too: they can save you round trips to the server. If I want to display fresh personalized session-specific content on my /home page, why should I force the client to download a generic /home page, then download my JS, then run an AJAX request, when she could just send a cookie in the initial request for /home and get back an (uncacheable) personalized response?
Your server shouldn't have to do O(N) units of work to serve a static page to N people. The entire point of GET-idempotency is that you can reduce serving your home page to O(1) units of work for you: you render the page, once, and it gets cached by a CDN, like Cloudflare. This necessitates customization either on the client-side, or not at all. Doing anything other than these is breaking the web[1].
(Besides, you don't necessarily have to do an AJAX request for every previously-would-have-been-customized page. Edge-side-include type stuff (e.g. username+id, viewing preferences) is, literally, what localStorage was created to store. You only have to get that type of stuff once.)
> Session fixation. Users might try to share links containing session IDs. Session IDs leak out via URL history and referrers; URLs show up in the darndest places.
As I said, proper TLS and CORS (where things like adding "noreferrer" to all external links is as much a requirement for proper CORS as not loading external images) generally takes care of this.
But you're right, there is a use for cookies. It's not to hold your session token, though. Instead, it's to hold a client fingerprint token, given to the client the first time they speak to you.
A client fingerprint is anything that authenticates a session token. If you say "give me /sessions/foo/..." and you don't send foo's associated fingerprint, the server 403s you at the load-balancer level.
Session fingerprints are already a common concept: some people use the user's IP address, or their browser UA string, or something, as a fingerprint. These have a pretty horrible UX, though, because these things can change unintentionally (e.g. a mobile connection switching cells.) But users expect that clearing their cookies will log them out of things, so the cookie store is a pretty good place to put these. Then, leaking a URL with the session token does nothing, because it doesn't share session secret (the fingerprint), just the identifier.
How is this different from just putting the session token in the cookie store? Mainly in that the client fingerprint doesn't represent you, it represents your machine. The point of it is to pair your browser to the server. You can log in and out as many times as you like, but it'll all happen under the same "client."
Note that if browsers actually chose to start emitting a unique, persistent, per-site client fingerprint as a header (like the iOS "Vendor/Advertising ID"), this would supplant the client fingerprint token -- but do nothing to replace the session token. They're separate things.
Note also that while the session token is part of the URL (and thus part of determining cacheability), the client fingerprint isn't. This should be obvious, but its implication isn't, necessarily: past your load balancer (which authenticates sessions against client fingerprints) cookies cease to exist; they should not be passed to your backend servers. The client, and your backend, operate on pure resources; the client fingerprint becomes a transparent part of the HTTP protocol, invisible to both sides. Gives a much stronger meaning to "HTTPOnly."
---
[1] And it's not that it's bad to break the web, really; you're not hurting anyone else's site than your own when you do this. It's just that HATEOAS gives you some really great guarantees, and pretty much everyone who throws these guarantees away finds themselves re-building the web on top of itself to try to get these guarantees back.
Matryosh...
Client fingerprinting (with cookies) does address session fixation. But but but didn't you just get through saying how wonderful your solution is because it doesn't use cookies?
If you're happy to use cookies and link them with server-side sessions, then just do that. (Just don't tell Roy.)
And when you need maximum performance, don't force the client to do multiple round trips.
> You only have to get that type of stuff once.
Most visits to public-facing web pages have a cold cache. Maximizing for warm-cache performance at the expense of multiple round trips for cold-cache performance is probably the wrong thing, but only A/B testing and RUM will tell you for sure.
OK, here it is: http://instantclick.io
Also you might want add some kind of tracking to avoid making repeat requests (probably within a timeframe). For e.g. hovering one link, then changing your mind, then going to another link. The browser will smartly pull it from its cache but this lib is still making the requests.
It doesn't feel that much faster, but I'd love a way to verify speed changes with data.
Sorry, my copy was previously unclear about that point.
I had already viewed a couple pages (to read what it is about) before I started looking for a demo, and by then I wasn't sure if it was my browser caching or your script that made the pages load snappy.
Maybe also provide a 10-page Lorem ipsum "before" example, clearly marked that it does not use your library, to demonstrate the difference. I can't really tell if maybe your server is just really fast.
The actual HTML is only going to add another few KB.
But caching the skeleton of the page will work. We need browser to do it for us, just like browsers already caches the images.
I've always hated menu dropdowns where it would close if you try to skip to the next submenu you've opened, since you hovered on the other parts on your way to the submenu.
So you'd end up having to perfectly 'trace' the menu so it won't close down on you.
The coolest approach given was when a user types in the search box, kick off the request for the full results page if they move their mouse on a motion curve towards one of the results, with some machine learned data on how people move their mouse: Not quite in a straight line, and with some acceleration.
edit: @devgutt else already mentioned this. I had this page open for a while before posting.
More than scaling, the larger headaches come from migrating all your existing logging to account for preloading versus impression hits.
The main differences are that InstantClick preloads just before you need a page, so you can be more liberal in what you preload. Also pages are more recent, useful if you’re serving dynamic content.
One interesting reaction I had: things loaded so fast that I didn't notice one of the page changes and thought it was stuck. For sites like this one where different pages look very similar, maybe it could be worth experimenting with some sort of brief flashing animation (to make it look like a real page load)?
(Not talking about this project in specific as it seems stats can be made to work with it, just replying to the idea in your comment.)
If not the case, note that it’s just HTML we’re wasting. In the grand scheme of things it seems to me it would not have that much of an impact on bandwidth usage.
Works great! I hope I won't have too many accidents with it.
I remember using 10 years ago a similar Windows program that preloaded all links.
That's about 33KB for 9 blog posts (not including attachments). So about 4KB per post. I could have a hundred articles and it would still be under half a MB. To put things into perspective, the cover photo of my pup is about 818KB. There are also numerous resource files, like JS, HTML, CSS that needs to be downloaded before the site will even be ready.
can you provide some specific definitions? thank you
[1] https://github.com/rails/turbolinks/pull/253#issuecomment-21...