Skip to content
This repository has been archived by the owner on Oct 21, 2022. It is now read-only.

Commit

Permalink
add parameter for ordered script execution
Browse files Browse the repository at this point in the history
  • Loading branch information
aFarkas committed Dec 28, 2015
1 parent 99ba4d8 commit 4781c9d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
37 changes: 35 additions & 2 deletions README.md
Expand Up @@ -42,18 +42,51 @@ You can execute code after the Script has loaded via a callback:
</head>
```

You can ensure ordered execution of multiple asynchronous by passing `true` as the second or third parameter. Only supported in browsers that support the [`async` attribute](http://caniuse.com/#search=async) (No IE8/IE9 support).:

```js
loadJS( "path/to/library.js", true );
loadJS( "path/to/plugins.js", true );
loadJS( "path/to/last.js", function() {
//all scripts loaded
}, true );
```

## Why not just use `<script src="..." async defer>`?

The `async` and `defer` attributes enjoy broad browser support. They're great options when all you need to do is load a script for all users, ideally in a non-blocking manner. The limitations with these attributes are:

1. Some older browsers do not support `async` ([though defer has broader support so it's typically not a problem](https://www.igvita.com/2014/05/20/script-injected-async-scripts-considered-harmful/))
2. There's no way to use these attributes to *conditionally* load a script, depending on feature or environmental conditions.
2. There's no way to use these attributes to *conditionally* load a script, depending on feature or environmental conditions.
3. There is (still) no declarative way to load scripts `async`, but in order.

Number 2 above is the main reason we use `loadJS`. Say you want to check if `querySelector` is supported before requesting your entire DOM framework and UI scripting - you'll need to use a script loader to do that. But again, if you just want to load a script unconditionally, these attributes are recommended.

## Limitations

`loadJS` does nothing to manage execution order of requested scripts, so we do not advise using it to load multiple javascript files that depend on one another. It simply fetches a script and executes it as soon as possible. You can certainly use `loadJS` to load multiple scripts as long as those scripts are designed to execute independently of any other scripts being loaded by `loadJS`.
* Ordered execution does not work in IE9-, so we do not advise using it to load multiple javascript files that depend on one another. It simply fetches a script and executes it as soon as possible. You can certainly use `loadJS` to load multiple scripts as long as those scripts are designed to execute independently of any other scripts being loaded by `loadJS`.
* If placed below external blocking scrips or stylesheets the download starts only after these files are downloaded and parsed. A good workaround for `async` script loading of crucial scripts is to inline `loadJS` before any other stylesheets and scripts and use it either immediately or within a `setTimeout`/`requestAnimationFrame`.

```html
<script>
// include loadJS here...
function loadJS( src ){ ... }
setTimeout(function(){
loadJS( "path/to/library.js", true );
if ( !hasFeature ) {
loadJS( "path/to/polyfill.js", true );
}
loadJS( "path/to/app.js", true );
});
</script>

...

<link rel="stylesheet" href="path/to/styles.css" />
```

#### Contributions and bug fixes

Expand Down
13 changes: 11 additions & 2 deletions loadJS.js
@@ -1,12 +1,21 @@
/*! loadJS: load a JS file asynchronously. [c]2014 @scottjehl, Filament Group, Inc. (Based on http://goo.gl/REQGQ by Paul Irish). Licensed MIT */
(function( w ){
var loadJS = function( src, cb ){
var loadJS = function( src, cb, ordered ){
"use strict";
var tmp;
var ref = w.document.getElementsByTagName( "script" )[ 0 ];
var script = w.document.createElement( "script" );

if (typeof(cb) === 'boolean') {
tmp = ordered;
ordered = cb;
cb = tmp;
}

script.src = src;
script.async = true;
script.async = !ordered;
ref.parentNode.insertBefore( script, ref );

if (cb && typeof(cb) === "function") {
script.onload = cb;
}
Expand Down

0 comments on commit 4781c9d

Please sign in to comment.