4

I have to load a third party script that is not critical for displaying the body (say for simplicity that it adds a red background on ".red" divs).

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

I need to execute function myRedify(){ $(".red").redify(); } after the script is loaded.

The script is huge and takes long time (say 3 seconds) to load, but once finished I need to see my .red divs became red.

<script src="redify.js" async defer onload="myRedify()"></script>

Is that the recommended way to do it?

Remarks

  • redify.js is a third party script that I can't modify
  • I don't mind if the divs became red not immediately, but after a delay(when the script is loading, 3 seconds - ok)
serge
  • 9,891
  • 17
  • 84
  • 142

1 Answers1

0

Your approach works, and by that it has merrit. Is it recommended? Maybe. Your approach has some advantages and some disadvantages:

  • performance: loading of the redify script starts immediately
  • readability: just looking at the HTML it's pretty obvious what's going on
  • the disadvantage is that, if you were to add another library (for example: blueify.js) you have to duplicate the mechanism.

Right now your code is tightly coupled through the myRedify function. You can decouple it by building a simple require strategy:

var libraries = {
    redify: "redify.js",
    blueify: "blueify.js"
};
var lib_bookkeep = {};

function require(library_name, callback) {
    if (lib_bookkeep[library_name]) {
         if (lib_bookkeep[library_name].status === "loaded") {
             callback();
         } else {
             lib_bookkeep[library_name].elem.addEventListener("load", callback);
         }
    } else {
        var script = document.createElement("script");
        script.src = libraries[library_name];
        script.addEventListener("load", function () {
            lib_bookkeep[library_name].status = "loaded";
        });
        script.addEventListener("load", callback);
        document.head.appendChild(script);
        lib_bookkeep[library_name] = {
            elem: script
            status: "loading"
        }
    }
}

require("redify", function () {
    $(".red").redify();
});

require("redify", function () {
    $(".also-red").redify();
});

require("blueify", function () {
    $(".blue").redify();
});
require("blueify", function () {
    require("redify", function () {
        $(".purple").redify().blueify();
    });
});

This allows you to expand on the libraries that you have, and it allows you to use them arbitrarily. This would by the approach that I recommend. If however you just have this once instance, it's probably find to do it like you have, with asynch/defer and onload.

Halcyon
  • 54,624
  • 10
  • 83
  • 122
  • what exactly do you mean by "add a script include and call any callbacks once it's loaded" is it an ajax call? – serge Nov 19 '15 at 17:42
  • @Serge I added a sample implementation. I haven't tested it but it should work in theory. – Halcyon Nov 20 '15 at 00:12