0

I am attempting to speed up the responsiveness of my micro-controller based web pages by loading the JavaScript after the page fully loads. I found this method in many places:

if (window.addEventListener)
    window.addEventListener("load", doAfterPageLoad, false);
else if (window.attachEvent)
    window.attachEvent("onload", doAfterPageLoad);
else window.onload = doAfterPageLoad;

The events certainly happen the way I wanted them to, but resources, specifically jQuery, do not appear to be accessible after loaded. This is an examplar script demonstrating what I am facing:

<script type="text/javascript">
    function loadPageData() {
        console.log("DEBUG: Entering: " + arguments.callee.name);
        // Do stuff requiring jQuery here
        console.log("DEBUG: Exiting: " + arguments.callee.name);
    }

    function loadJS() {
        console.log("DEBUG: Entering: " + arguments.callee.name);
        var jq = document.createElement("script");
        jq.type = "text/javascript";
        jq.crossOrigin = "anonymous";
        jq.integrity = "sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=";
        jq.src = "https://code.jquery.com/jquery-3.4.1.min.js";
        document.body.appendChild(jq);
        var pop = document.createElement("script");
        pop.type = "text/javascript";
        pop.crossOrigin = "anonymous";
        pop.integrity = "sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1";
        pop.src = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js";
        document.body.appendChild(pop);
        var bs = document.createElement("script");
        bs.type = "text/javascript";
        bs.crossOrigin = "anonymous";
        bs.integrity = "sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM";
        bs.src = "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js";
        document.body.appendChild(bs);
        console.log("DEBUG: Leaving: " + arguments.callee.name);
    }

    function doAfterPageLoad() { // Load the page's JS elements
        console.log("DEBUG: Entering: " + arguments.callee.name);
        loadJS();   // Load external JS
        if(window.jQuery) {
            loadPageData(); // Load once on page load
        } else {
            console.log("DEBUG: jQuery not loaded.");
        }
        console.log("DEBUG: Leaving: " + arguments.callee.name);
    }

    // Attach the event after the page loads
    window.addEventListener("load", doAfterPageLoad, false);
</script>

From this I get the following console log:

DEBUG: Entering: doAfterPageLoad
DEBUG: Entering: loadJS
DEBUG: Leaving: loadJS
DEBUG: jQuery not loaded.
DEBUG: Leaving: doAfterPageLoad
DEBUG: Entering: loadJS
DEBUG: Leaving: loadJS
DEBUG: jQuery not loaded.
DEBUG: Leaving: doAfterPageLoad

So, jQuery is not available to the rest of the script, specifically loadPageData().

I suspect it's some sort of scope issue, but so far I've not been able to crack this particular nut.

LCB
  • 91
  • 1
  • 11
  • Does the browser "Network" developer tool tell you anything interesting, such as errors from the HTTP requests to load the scripts? – Pointy Mar 24 '20 at 16:05
  • Also it's not a scope issue in any case. It could be a timing issue. Honestly I don't think this is going to speed anything up; your code is trying to do essentially exactly the same thing the browser would do if you simply placed the ` – Pointy Mar 24 '20 at 16:07
  • Upon an initial look at your code, your using a lot of stuff that is out of date. Every browser since IE9 supports `.addEventListener()`. There's no reason to check for it in 2020. Also `type="text/javascript"` hasn't been needed in years. Lastly, unless your code requires the use of downloaded resources, use DOMContentLoaded (JQuery's `document.ready()` is the equivellent) instead of `load`. I really don't see much of what you are doing here as beneficial. – Scott Marcus Mar 24 '20 at 16:08
  • @Pointy: "Does the browser "Network" developer tool tell you anything interesting" - Negative, just the console output I shared above. "It could be a timing issue" - Maybe, but the way I understand the way JS works, the functions which load the scripts should be synchronous and therefore return from loading before the next tries to use it. – LCB Mar 24 '20 at 17:19
  • @ScottMarcus: "Upon an initial look at your code, your using a lot of stuff that is out of dateUpon an initial look at your code, your using a lot of stuff that is out of date" - Fair - that's how the Internet is. Nobody goes back and removes deprecated advice. Even so, that should not impact the functionality because it would never be used. – LCB Mar 24 '20 at 17:20
  • Well the "Network" developer tab tells you about *all* the HTTP requests made when a page loads. It gives you the request info, the response info, and the content if successful. That's what I was talking about, not just the console. – Pointy Mar 24 '20 at 17:22
  • I don't think you quite follow my comment. The code you are using was necessary about 8 years ago. Today it's not. I don't think there is a need for any of the code you have here in 2020. Just add ` – Scott Marcus Mar 24 '20 at 17:56
  • @Pointy: Yes, the console (and all of its tabs including Network) is devoid of errors. For those particular .js files it shows 0k, cached, and 200. I assume the 0k is because it's using the cached version. – LCB Mar 24 '20 at 19:15
  • @ScottMarcus: I do exactly follow your comment. My point is if `window.addEventListener` is viable, it will be preferentially used. I get that I don't need it, but removing it is also not the solution to my issue (having tried it.) Adding the script tag at the end just before I close the body does not give me the same performance, so therefore it's not the same. Finally, removing deprecated advice is != updating deprecated code. My point is that people place advice on the Internet and do not go update THAT, therefore it's relatively easy to find. – LCB Mar 24 '20 at 19:20
  • @ScottMarcus No change removing the "deperecated code." – LCB Mar 24 '20 at 19:37
  • Right, that's the point exactly. And, if you just add the single `script` line I mentioned in my previous comment, you won't notice any change either (other than JQuery will be available throughout your page's code, which is what you state the problem is). That's because all of what you've got here is outdated and unnecessary. I don't see what "performance" you think you're getting with the code you have. – Scott Marcus Mar 24 '20 at 19:45
  • Have you tried with defer? https://www.w3schools.com/tags/att_script_defer.asp – DonkeyKong Mar 24 '20 at 19:52
  • @ScottMarcus When I use the `script src` tag the responsiveness of the page is negatively impacted. I'm not yet sure why, but the page from the controller fails to render more often than not. This is curious, but empirical evidence points to the loading of the JS. That's why I searched for ways to delay the loading of any JS until after the entire page has loaded. `window.addEventListener("load", doAfterPageLoad, false);` [is not outdated according to what I have been able to find](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener). – LCB Mar 24 '20 at 19:53
  • Placing the script just before the closing `body` tag causes it not to run until the DOM has been built and is ready for interaction, but before the `load` event. If your script will not be needing resources that must download, then this is better performing than waiting for `load`. Whatever your responsiveness issues are, they are not because of loading JQuery just before the close of `body` - that is standard and [recommended by the JQuery team](https://learn.jquery.com/about-jquery/how-jquery-works/). – Scott Marcus Mar 24 '20 at 20:34
  • By the way, I never said that `window.addEventListener("load", doAfterPageLoad, false);` was outdated. In fact, I said the exact opposite *"Every browser since IE9 supports .addEventListener(). There's no reason to check for it in 2020."* I'm not trying to be argumentative, but I've been developing and teaching all of this stuff since it was invented and am quite sure that whatever issues you are having, it is not because of loading JQuery. You have come to the conclusion that it is and now you are basing everything on this, but I would bet that the issue is something else. – Scott Marcus Mar 24 '20 at 20:35
  • @ScottMarcus despite my attempts otherwise, I am not being clear. I follow completely what you are saying but my experience so far with my project is different. In my experience, asking "why doesn't my stuff work?" isn't well-received here so I tried what I thought was the right thing. I do appreciate you trying to help. Short of busting out Wireshark (which I am even worse with) I am close to out of ideas. – LCB Mar 24 '20 at 22:14
  • I think what you have here is [an XY problem](https://en.wikipedia.org/wiki/XY_problem). Instead of asking about what you perceive a solution to your problem is, with only a vague reference to the actual issue, you should re-formulate your question with primary emphasis on what you know the problem is. You state that you are trying to speed up the responsiveness of your micro-controller. That is the problem, so focus on that. What ***specific*** issues are you experiencing that make you believe you have a responsiveness issue? Start with that and we can go from there. – Scott Marcus Mar 25 '20 at 13:20
  • @ScottMarcus I hear you - I have had less luck asking "what might the problem be" than "how do I fix this specifc thing" but I'll give it a go. I will try to whittle it down to a specific fail case and post that. – LCB Mar 25 '20 at 16:59

0 Answers0