Skip to main content

Two simple JavaScript functions for loading JavaScript and CSS Stylesheet files async in the browser.

/**
 * loadJS - Load js files async.
 *
 * Usage:
 *
 * Place the loadJS function inline in the head of your page (it can also be
 * included in an external JavaScript file if preferable).
 *
 * <head>
 * ...
 * <script>
 *   // include loadJS here...
 *   function loadJS( src ){ ... }
 *   // load a file with loadJS
 *   loadJS( "path/to/script.js" );
 * </script>
 * ...
 * </head>
 *
 * NOTE: `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.
 *
 * @param  {String} src URL of JS file.
 * @return {DOMElement} The script DOM element.
 *
 * Repository: https://github.com/filamentgroup/loadJS
 * Article: [How we make Responsive Web Design sites load fast as heck](http://filamentgroup.com/lab/performance-rwd.html)
 * [c]2014 @scottjehl, Filament Group, Inc. Licensed MIT
 */

function loadJS(src) {
  "use strict";
  var ref = window.document.getElementsByTagName("script")[0];
  var script = window.document.createElement("script");
  script.src = src;
  ref.parentNode.insertBefore(script, ref);
  return script;
}

/**
 * loadCSS - Load stylesheets async.
 *
 * @param  {String} href URL of stylesheet
 * @param  {Element}  before Optionally Element used as reference for
 * injecting our <link>.
 *
 * By default, `before` uses the first <script> element in the page. However,
 * since the order in which stylesheets are referenced matters, you might need
 * a more specific location in your document.
 *
 * If so, pass a different reference element to the `before` argument and
 * it'll insert before that instead. note: `insertBefore` is used instead of
 * `appendChild`, for safety
 *
 * @param  {String} media  The target media type. If not set, defaults to
 * `all`.
 *
 * @return {DOMElement} The stylesheet DOM element.
 *
 * Repository: https://github.com/filamentgroup/loadCSS
 * Article: [How we make Responsive Web Design sites load fast as heck](http://filamentgroup.com/lab/performance-rwd.html)
 * [c]2014 @scottjehl, Filament Group, Inc. Licensed MIT
 */
function loadCSS(href, before, media) {
  "use strict";
  var ss = window.document.createElement("link");
  var ref = before || window.document.getElementsByTagName("script")[0];
  ss.rel = "stylesheet";
  ss.href = href;
  // temporarily, set media to something non-matching to ensure it'll fetch
  // without blocking render
  ss.media = "only x";
  // inject link
  ref.parentNode.insertBefore(ss, ref);
  // set media back to `all` so that the styleshet applies once it loads
  setTimeout(function () {
    ss.media = media || "all";
  });
  return ss;
}