Difference Between the Different Methods of Putting JavaScript Code in an ≪A≫

What is the difference between the different methods of putting JavaScript code in an <a>?

I quite enjoy Matt Kruse's Javascript Best Practices article. In it, he states that using the href section to execute JavaScript code is a bad idea. Even though you have stated that your users must have JavaScript enabled, there's no reason you can't have a simple HTML page that all your JavaScript links can point to for their href section in the event that someone happens to turn off JavaScript after logging in. I would highly encourage you to still allow this fallback mechanism. Something like this will adhere to "best practices" and accomplish your goal:

<a href="javascript_required.html" onclick="doSomething(); return false;">go</a>

Two different ways of putting the script at the bottom - what are the differences?

1. Script at the bottom

When you use a "synchronous" script tag, it will block the browser from rendering the page until the script is loaded and executed. This method has the following effects:

  • Regardless of where you put the script tag, the browser cannot fire DOMContentLoaded until the script is downloaded and executed.

  • Placing such a script tag at the bottom only ensures that the browsers has rendered all content before getting blocked by the script.

2. Script at the bottom loads external script

When you inject a script tag using JavaScript, it will create an "asynchronous" script tag that does not block the browser. This method has the following effects:

  • Regardless of where you put the JavaScript code that generates the script tag, the browser executes it as soon as it is available without blocking the page. The DOMContentLoaded fires when it should; irrespective of whether the script has downloaded/executed.

The second approach has the following advantages:

  • The script that injects a script tag can be placed anywhere including document head.
  • The script will not block the rendering.
  • DOMContentLoaded event does not wait for the script.

The second approach has the following disadvantages:

  • You cannot use document.write in such scripts. If you do, such statements might wipe the document clean.
  • Asynchronous execution does not mean that browser has finished parsing the page. Keep the script executes as soon as it is available clause in mind.
  • Execution order is not guaranteed. Example: If you load "library.js" and "use-library.js" using injected script tags, it is possible for "use-library.js" to load and execute before "library.js".

Having said all that, there is another method for loading scripts, with three variations:

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

Regarding Steve Souders's work: he proposed 6 techniques for loading scripts without blocking. The async and defer attributes introduced in HTML5 cover the Script DOM Element and Script Defer techniques and their browser support is more than enough for you to worry about the other techniques.

Javascript - inline vs external script - what's the difference?

There is little difference in using one or the other way. The real difference comes from the advantages/disadvantages that each one has.

Inline scripts

  • Are loaded in the same page so is not necessary to trigger another request.
  • Are executed immediately.
  • The async and defer attributes have no effect
  • Can be helpful when you are using a server-side dynamic rendering.

External scripts

  • Gives better separation of concerns and maintainability.
  • The async and defer attributes have effect so if this attributes are present the script will change the default behavior. This is not possible with inline scripts.
  • Once a external script is downloaded the browser store it in the cache so if another page reference it no additional download is required.
  • Can be used to load client code on demand and reduce overall download time and size.

Where should I put <script> tags in HTML markup?

Here's what happens when a browser loads a website with a <script> tag on it:

  1. Fetch the HTML page (e.g. index.html)
  2. Begin parsing the HTML
  3. The parser encounters a <script> tag referencing an external script file.
  4. The browser requests the script file. Meanwhile, the parser blocks and stops parsing the other HTML on your page.
  5. After some time the script is downloaded and subsequently executed.
  6. The parser continues parsing the rest of the HTML document.

Step #4 causes a bad user experience. Your website basically stops loading until you've downloaded all scripts. If there's one thing that users hate it's waiting for a website to load.

Why does this even happen?

Any script can insert its own HTML via document.write() or other DOM manipulations. This implies that the parser has to wait until the script has been downloaded and executed before it can safely parse the rest of the document. After all, the script could have inserted its own HTML in the document.

However, most JavaScript developers no longer manipulate the DOM while the document is loading. Instead, they wait until the document has been loaded before modifying it. For example:

<!-- index.html -->
<html>
<head>
<title>My Page</title>
<script src="my-script.js"></script>
</head>
<body>
<div id="user-greeting">Welcome back, user</div>
</body>
</html>

JavaScript:

// my-script.js
document.addEventListener("DOMContentLoaded", function() {
// this function runs when the DOM is ready, i.e. when the document has been parsed
document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});

Because your browser does not know my-script.js isn't going to modify the document until it has been downloaded and executed, the parser stops parsing.

Antiquated recommendation

The old approach to solving this problem was to put <script> tags at the bottom of your <body>, because this ensures the parser isn't blocked until the very end.

This approach has its own problem: the browser cannot start downloading the scripts until the entire document is parsed. For larger websites with large scripts and stylesheets, being able to download the script as soon as possible is very important for performance. If your website doesn't load within 2 seconds, people will go to another website.

In an optimal solution, the browser would start downloading your scripts as soon as possible, while at the same time parsing the rest of your document.

The modern approach

Today, browsers support the async and defer attributes on scripts. These attributes tell the browser it's safe to continue parsing while the scripts are being downloaded.

async

<script src="path/to/script1.js" async></script>
<script src="path/to/script2.js" async></script>

Scripts with the async attribute are executed asynchronously. This means the script is executed as soon as it's downloaded, without blocking the browser in the meantime.
This implies that it's possible that script 2 is downloaded and executed before script 1.

According to http://caniuse.com/#feat=script-async, 97.78% of all browsers support this.

defer

<script src="path/to/script1.js" defer></script>
<script src="path/to/script2.js" defer></script>

Scripts with the defer attribute are executed in order (i.e. first script 1, then script 2). This also does not block the browser.

Unlike async scripts, defer scripts are only executed after the entire document has been loaded.

According to http://caniuse.com/#feat=script-defer, 97.79% of all browsers support this. 98.06% support it at least partially.

An important note on browser compatibility: in some circumstances, Internet Explorer 9 and earlier may execute deferred scripts out of order. If you need to support those browsers, please read this first!

(To learn more and see some really helpful visual representations of the differences between async, defer and normal scripts check the first two links at the references section of this answer)

Conclusion

The current state-of-the-art is to put scripts in the <head> tag and use the async or defer attributes. This allows your scripts to be downloaded ASAP without blocking your browser.

The good thing is that your website should still load correctly on the 2% of browsers that do not support these attributes while speeding up the other 98%.

References

  • async vs defer attributes
  • Efficiently load JavaScript with defer and async
  • Remove Render-Blocking JavaScript
  • Async, Defer, Modules: A Visual Cheatsheet

What's the difference between a method and a function?

A function is a piece of code that is called by name. It can be passed data to operate on (i.e. the parameters) and can optionally return data (the return value). All data that is passed to a function is explicitly passed.

A method is a piece of code that is called by a name that is associated with an object. In most respects it is identical to a function except for two key differences:

  1. A method is implicitly passed the object on which it was called.
  2. A method is able to operate on data that is contained within the class (remembering that an object is an instance of a class - the class is the definition, the object is an instance of that data).

(this is a simplified explanation, ignoring issues of scope etc.)

var functionName = function() {} vs function functionName() {}

The difference is that functionOne is a function expression and so only defined when that line is reached, whereas functionTwo is a function declaration and is defined as soon as its surrounding function or script is executed (due to hoisting).

For example, a function expression:

// TypeError: functionOne is not a functionfunctionOne();
var functionOne = function() { console.log("Hello!");};

Where to place JavaScript in an HTML file?

The Yahoo! Exceptional Performance team recommend placing scripts at the bottom of your page because of the way browsers download components.

Of course Levi's comment "just before you need it and no sooner" is really the correct answer, i.e. "it depends".

JavaScript - href vs onclick for callback function on Hyperlink

Putting the onclick within the href would offend those who believe strongly in separation of content from behavior/action. The argument is that your html content should remain focused solely on content, not on presentation or behavior.

The typical path these days is to use a javascript library (eg. jquery) and create an event handler using that library. It would look something like:

$('a').click( function(e) {e.preventDefault(); /*your_code_here;*/ return false; } );


Related Topics



Leave a reply



Submit