Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

document.createElement('script') vs <script src="">

Why is it that services like Google and Facebook use document.createElement('script') instead of just <script>?

The Google Analytics snippet:

<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>

could be written as just:

<script src="//www.google-analytics.com/ga.js" type="text/javascript"></script>

and Facebook's like button:

<script>(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/en_GB/all.js#xfbml=1&appId=xxx";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>

could be simplified as just:

<script src="//connect.facebook.net/en_GB/all.js#xfbml=1&appId=xxx"></script>

I know there's some playing safe in them, but other than that I don't see why we shouldn't use the HTML5 ones?

like image 793
webjay Avatar asked Feb 02 '13 21:02

webjay


People also ask

What does document createElement do?

In an HTML document, the document. createElement() method creates the HTML element specified by tagName, or an HTMLUnknownElement if tagName isn't recognized.

What is script src in HTML?

The src attribute specifies the URL of an external script file. If you want to run the same JavaScript on several pages in a web site, you should create an external JavaScript file, instead of writing the same script over and over again. Save the script file with a .

Which of the following creates the script element?

createElement() to create the script element and add it to the document.


2 Answers

The <script src=...> blocks the browser while document.createElement('script') loads the JavaScript asynchronously; this is the primary reason.


The <script src=...> tag blocks browser from displaying rest of the page until the script is loaded and executed. This ensures that scripts are executed in correct order and any document.write() in that script work as expected. However this creates a laggy browsing experience for the user.

When the script is loaded asynchronously, the browser can download the script without blocking the page display. This improves the browsing experience dramatically.

To load the scripts asynchronously one can use HTML markup:

<script src="..." async defer></script>

The async attribute was introduced in HTML5 while the defer attribute can be added as a fallback for older versions of IE. This document describes how async and defer attribute work.

Alternately, one can use JavaScript to build a script tag:

var s = document.createElement('script');
s.src = "...";
document.getElementsByTagName("head")[0].appendChild(s);

JavaScript generated script tags work in most browsers even if they do not understand the async attribute or .async = true property.


About schemeless URIs (//example.com/script.js): schemeless URIs seem to work almost everywhere (see this question).

About the Google Analytics example: both old and new code use JavaScript to detect the protocol then load http://www. or https://ssl. which is not possible via HTML markup.

like image 189
Salman A Avatar answered Oct 21 '22 05:10

Salman A


In addition to Salman A's excellent point about deferred loading this technique is used when the static solution won't work.

  • I've seen it used when caching is an issue (a unique time based hash is added to the URL)
  • In the case of the google link shown above SSL can be dynamically turned on.
  • In the facebook code it checks if the script already exists (this can avoid bugs where the same script is loaded twice).

There can be other reasons too. All of them have to do with needing a dynamic solution.

like image 40
Hogan Avatar answered Oct 21 '22 03:10

Hogan