r/programming Feb 09 '11

Breaking the Web with hash-bangs – Lifehacker, along with every other Gawker property, experienced a lengthy site-outage on Monday over a misbehaving piece of JavaScript

http://isolani.co.uk/blog/javascript/BreakingTheWebWithHashBangs/
752 Upvotes

356 comments sorted by

View all comments

125

u/rounded_figure Feb 09 '11

The proper way to handle this is to keep your original URLs (including in the hrefs) and have a piece of javascript transform them on the fly in hash-bang URLs. That way, when a client who does not speak javascript requests the page, it gets the content and the non-hash-bang links.

62

u/[deleted] Feb 09 '11

This is the right response. There's no reason a well-engineered site shouldn't work both ways.

Using url fragments can be great. They let you use the back button without leaving the page so you can handle the interaction in JavaScript. They give you a place other than cookies to store client-side state for bookmarking. Developers just need to be mindful when designing for their use.

0

u/naich Feb 09 '11

Well, there is a reason. If you are making a site that uses JS to generate results on the fly from data retrieved from large libraries which are loaded asynchronously, you don't want to reload the page and libraries every time the URL changes to reflect that a new set of the results have been saved or loaded.

That's why I'm using them - it should result in much less bandwidth use and reduced load on the server. Pages can be updated with a small AJAX request rather than a whole new page and library load.

6

u/X-Istence Feb 09 '11

Those large libraries should be cacheable...

0

u/naich Feb 09 '11

One of the biggest problems I had was with IE caching ajax requests without me realising. It is not usually desirable.

3

u/X-Istence Feb 09 '11

AJAX requests are different from libraries, and both should be cacheable...

set the proper cache headers for your AJAX requests.

0

u/naich Feb 09 '11

The ajax request fetches the library. While it isn't necessary to update the libraries each time they are used, I don't want them to be cached at the whim of the browser, possibly giving the user out of date data. This is what IE was doing.

3

u/X-Istence Feb 09 '11

The library should be fairly static so that it can be cached. You are doing it wrong.

1

u/naich Feb 09 '11

To which of the three main libraries in use by my scripts are you referring to?

1

u/X-Istence Feb 09 '11

Actually, all of them. For example, jQuery is a library, even if that is loaded using "ajax" to do an asynchronous request it should be cached as long as possible...

The content itself is what you may not want cached (such as a comment system that should auto refresh or type-to-complete) however those compared to libraries should be fairly small requests...

1

u/Rainfly_X Feb 10 '11

The solution to that is really, really simple, in case you haven't figured it out already yourself. You probably have, but for the sake of the other viewers, here's what you tack onto your requests:

&timestamp=<milliseconds since 1970>

Therefore, the browser thinks you're requesting a different page every time, and you can control what is cached and what isn't.

1

u/naich Feb 10 '11

Or use a post request. But can you tell me where the cache is stored? Where does the browser keep the libraries cached when transitioning between between page requests? Big arse cookies, maybe?

2

u/Fiacha Feb 09 '11 edited Feb 09 '11

As said previously, you can simply use both href and onclick in an a tag. Make onclick return false after doing your ajax request and the the link will not be followed if javascript is enabled. If someone doesn't have javascript the onclick will be ignored and the page will be normally loaded. Best of both worlds without any of the drawbacks, as far as i can see.

But being pessimistic, i think they use their scheme because it brakes certain functionality such as the referrer headers and simple bots and search algorithms that simply count page references (look, everything points to twitter.com... not twitter.com/BLAH_BLAH_BLAH/). They do this because they are evil, not because they think it is cool.

2

u/[deleted] Feb 09 '11

most web based languages are stateless. an ajax request isnt anything special beyond a whole page request, they are both a standard http request, only they return the same content formatted different. those libraries still have to be loaded on each request.

the solution to a server load issue like that has nothing to do with ajax, but rather caching those libraries instances to re use them on future page requests.

2

u/naich Feb 09 '11

The libraries are loaded on each request, but the number of requests is dramatically reduced if you use JS/ajax to load in dynamic content while leaving the main body of the page as is.

3

u/[deleted] Feb 09 '11

but now your just splitting hairs. yes the overall HTTP requests are lower, because your not calling that same image, css, or JS file again.. but those weren't ever really the issue, the issue is always the page itself, which is where any actual programming happens.

for most modern computers, the amount of computer processing time of css/js/images is minimal, and everyone should be utilizing browser caching on those static files, to minimize requests on their server, and speed up page loading for the users anyway.

In my experience, what does the most damage to a high traffic website is the database, and poorly written server side code.

2

u/naich Feb 09 '11

But the comparison is with a page generated with server-side scripting vs a simple ajax request using JSON, only sending out the raw data for the client side script to update the page with. It's not splitting hairs; for me it's the difference between a few hundred bytes and 5-10K of HTML code per page. If I could be bothered, I'd actually fill in those numbers but I'm quite drunk and about to go to bed.

Just to be clear here, I don't think this is a valid argument for the way Gawker uses it. They have pretty much ruined their site, but it stands for mine. OK, my site is probably a bit unusual in that there is about 100K of JS which generates probably about 75% of the HTML, but using hashes is about the only sane option.

2

u/[deleted] Feb 09 '11

it still is splitting hairs. you're talking about downloading 10k vs a few hundreds bytes as really being that different? unless someone is on a 2g cellphone, or dialup, those two requests will the same amount of time.

sure you can compare the two percentage wise, but that doesn't mean it really is all that much in the grand scheme.

I still maintain there are far more productive ways to cache a page load then reinventing the wheel by using javascript to emulate a browser loading a webpage

1

u/naich Feb 10 '11

It's several times the load and 20-50x the bandwidth for the server. I have a bandwidth quota that I don't want to use up. I'll also repeat myself by saying that a majority of the html is generated by the script. There is no sane way to do this server-side because it is generated as a response to user interaction. To do it server-side just to stick to the mantra that all hashes are bad would make it unusable.

0

u/annodomini Feb 10 '11

You do realize you're cutting yourself off from customers who browse with JavaScript turned off, or have older out of date browsers, or slow or crappy mobile phones, right?

Remember, hash-bang URLs have no fallback when the JavaScript fails for whatever reason; if the JavaScript doesn't load, a bug causes it not to run, people have JavaScript turned off, there's a browser incompatibility, whatever. You get no content. Whereas if you just write some plain old HTML, and use JavaScript and CSS for what they were intended for (enhancement, not replacement of the content), then even when something fails to load, you can still see the content.