0

Working at a company that loads all javascript at the end of the page load. This means I can't do $(document).ready() on my page, because jquery isn't loaded (the scripts are injected into the footer by some template or other). I'm stumped on how to address this. I have one page where I want to run a function that is in a script, but the script is loaded last. If I make a case for moving the script(s) into the <head> I will need to make a compelling argument for it.

I've looked at the current code and every page runs a bunch of methods after the scripts are declared in the footer, which each check that they're on the relevant page and if so they execute. So it will run for example formatSearchResults() which checks to see if we're on the SearchResults page and if so will do some javascript, renderLoginPage(), setupProfilePage() etc. etc. Repeat this one by one for every page that requires javascript in the solution. This seems like a bad idea to me.

Historically I can maybe understand why, because downloading tons of scripts blocks the page loading. But these days I cannot understand why this is an issue.

  • Scripts are tiny and load very fast.
  • Once the script is loaded, it doesn't download it again (unless it changes) as the server simply asks the webserver if the file has changed.
  • Complex javascript libraries for manipulating the page like JQuery etc. did not exist back then.
  • Pages are much more complex these days and javascript is generally used in rendering and styling the page, rather than being something that adds behind the scenes magic at the end.

If I have to put calls to run my desired code in the footer, possibly via some complex callback mechanism then really the scripts aren't being loaded in the footer at all and I just have two bodies.

I wonder if anyone could shed some light on this, and explain if I am misguided, missing something, if there's more to it, etc.

1
  • Another reason: pages nowadays often have no HTML whatsoever between the header and the footer, as everything is generated by Javascript. Commented Oct 24, 2017 at 10:26

3 Answers 3

3

You could always use the javascript pure equivalent of $(document).ready(function(){}) which is document.addEventListener('DOMContentLoaded', function() {}). This way you don't have to put the scripts in the head section of the page.

Running functions for every page even if its not relevent on that page is not a good practice and maybe you should think about separating those and loading every specific function on the related page.

1
  • That's interesting, I wasn't aware that the pure javascript solution was so simple. It would be nicer I think than the current method, and I am happy someone agrees it isn't right to run all that javascript on every page load.
    – NibblyPig
    Commented Oct 24, 2017 at 11:13
1

To address your immediate problem, it seems that methods were arbitrarily appended after scripts load, which might be reasonable for one or two methods, but if you see this commonly happen on every page, another approach should be taken to abstract away the "when".

A good tactic could be simply to convert function calls with an addEventListener that can be placed anywhere on the page, not necessarily after scripts have been loaded. At this point, the only thing that must be executed necessarily after script loads is the event dispatch for that event. Essentially, you're creating your own version of $(document).ready(function(){}) that works with your existing code.

var event = new Event('scriptsLoaded');

// Listen for the event.
elem.addEventListener('scriptsLoaded', function (e) { ... }, false);

// Dispatch the event.
elem.dispatchEvent(event);

The long-term solution would be of course to remove the necessity to be added after page load. If you've applied the above fix, then this change will be simple. You move script loading into the header and call dispatchEvent for 'scriptsLoaded' event yourself in $(document).ready(). Even if you decide not to do the long-term solution, it sets a precedent for future additions and makes your code more flexible.

1

I realize this question is 4 years old but I can't resist answering... there is a reason for putting your scripts in the footer, but it's totally outdated in modern browsers. When a browser encounters a script tag it downloads and executes the JS before continuing to parse the rest of the DOM. You can learn more about how this works by studying what's called the 'critical rendering path.' Admittedly, how this functions in reality is a bit different than described, but you can test it out yourself by placing a slow loading script right in the middle of your HTML like so :

<html>
<body>
  <p>some text</p>
  <script src='/slow/script.js'></script>
  <p>this will only appear after slow script is loaded.</p>
</body>
<html>

... Back in the day when jQuery was king putting all your scripts in the footer was the common way to deal with this issue, ie. show the users the content right away then allow the browser to download and process the JS. HOWEVER! Modern browsers have rendered this practice obsolete by introducing the async / defer script tag attributes.

Another important concept you alluded to in your question is the browser cache, you stated :

Once the script is loaded, it doesn't download it again...

This is only halfway true, because the browser cache is small and temporary. As users navigate around the web cached scripts are purged from memory to make way for newer assets, so they will eventually have to get loaded again.

So to answer the initial question, I'd recommend you do move the scripts to the document head and then leverage the async / defer attributes. If that's not possible for some reason, technical or political, consider placing your script in a separate file in the footer which appears after the other scripts are loaded. I also have to give a shout out to @Sandman's answer - use document.addEventListener instead of jQuery's document/ready.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.