First of all, the title is perhaps misleading. Basically, don't put plain script
tags that are not async
in the head
tag.
If you put a piece of javascript in the head of HTML page, the browser will start to download that and proceed down the lines of HTML and download other resources too as it encounters them such as the CSS files.
Then, when all javascript and CSS has been downloaded it will start rendering the page and when it does that it will download any images referenced in the HTML. At roughly the same time it will start to display things on the screen. But it won't do this until the CSS and Javascript has been downloaded.
To repeat: The browser screen will appear blank. It won't start downloading any images if downloading a javascript URL referenced in the head gets stuck.
Here are two perfectly good examples from this morning's routine hunt for news:
Wired.com is guilty
getharvest.com is guilty
Here's what getharvest.com does in their HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript">var NREUMQ=NREUMQ||[];NREUMQ.push(["mark","firstbyte",new Date().getTime()]);</script>
<script type="text/javascript" src="http://c761485.r85.cf2.rackcdn.com/gascript.js"></script>
...
Why it gets stuck on connecting to c761485.r85.cf2.rackcdn.com
I just don't know. But it does. The Internet is like that oftentimes. You simply can't connect to otherwise perfectly configured web servers.
Update-whilst-writing-this-text! As I was writing this text I gave getharvest.com a second chance thinking that most likely the squirrels in my internet tubes will be back up and running to rackcdn.com
but then [this happened!/static/cache/bd/02/bd02367be6bbe6d16444051619d88bee.jpg)
So, what's the right thing to do? Simple: don't rely on external resources. For example, can you move the Javascript script tag to the very very bottom of the HTML page. That way it will render as much as it possibly can whilst waiting for the Javascript resource to get unstuck. Or, almost equally you can keep the script
tag in the <head>
but then but in async
attribute on it like this:
<script async type="text/javascript" src="http://c761485.r85.cf2.rackcdn.com/gascript.js"></script>
Another thing you can do is not use an external resource URL (aka. third-party domain). Instead of using cdn.superfast.com/file.js
you instead use /file.js
. Sure, that fancy CDN might be faster at serving up stuff than your server but looking up a CDN's domain is costing one more DNS lookup which we know can be very expensive for that first-time impression.
I know I'm probably guilty of this new on some of my (now) older projects. For example, if you open aroundtheworldgame.com it won't render anything until it has managed to connect to maps.googleapis.com
and dn4avfivo8r6q.cloudfront.net
but that's more of an app rather than a web site.
By the way...
I wrote some basic code to play around with how this actually works. I decided to put this up in case you want to experiment with it too: https://github.com/peterbe/slowpage