We have JS that loads like <script src="/static/react-stuff.sj"> but we might benefit from adding defer and load them the <head> instead.
E.g. https://flaviocopes.com/javascript-async-defer/
Can You please clearly mention out the file we need to look in for this issue?
There are a couple of places. First, the files that use {% javascript '...' %} in various *.html jinja files.
Then, in the PIPELINE_JS there's the option for extra_context (I think it's called) that needs to have defer: True or something.
@peterbe I want to contribute in this issue, can you assign me this issue. Thanks
@peterbe I want to contribute in this issue, can you assign me this issue. Thanks
We don't do that unless you're a core contributor. Make a pull request and hope that your PR came in first.
Can You please list all the files so that I can work and complete this issue....Please let me know soon
@peterbe Thanks for the help.
Hi @peterbe little help. How to do changes on {% javascript '...' %} in various *.html jinja files.
The {% javascript 'some-thing' %} tag in a Jinja template basically corresponds to what's in PIPELINE_JS in kuma/settings/common.py.
For example, look at: https://github.com/mozilla/kuma/blob/f28dd92eab09dd3fbabc927b0e15da9ea8d98229/kuma/settings/common.py#L953-L963
What this means it the key is banners so you'd type: {% javascript 'banners' %} and would turn that into <script src="/static/build/js/banners.js" async></script>
So in your case wouldn't use 'async': True but 'defer': True instead.
Hi @peterbe I see that some of these has been deferred but some are not, like 'main', 'jquery-ui', 'payments'. These are not meant to be deferred or I should defer them.
How to know which should be deferred and what shouldn't?
Thanks.
I'm sorry that this is so tricky. But one learns from doing what's not easy.
Before it was like this:
<script src="a.js" defer></script>
<script src="b.js"></script>
<script src="c.js" async></script>
<script src="d.js"></script>
<script src="e.js" defer></script>
<script src="f.js" async></script>
Indpendent of where in the DOM these are, this is the expected exection order:
Actually, when c.js and f.js executes is 100% unreliable. They executes when it feels like it's ready. You basically can't guarantee that their order. Not even between themselves.
All the ones that don't use async are executed in the order they appear from top to bottom.
The question is, for each and every file, Is it OK to execute it AFTER the DOM has been downloaded, parsed, and built?
For example, imagine you had this:
<script src="a.js"></script>
<script src="b.js"></script>
And
// a.js
var div = document.createElement('div')
div.id = 'foo'
document.body.appendChild(div)
// b.js
console.log(document.querySelect('#foo').textContent);
...
If b.js requires that a.js is loaded first. So what happens if you put a defer on <script src="a.js"></script>?
If聽you聽put it聽on聽both聽a.js and聽b.js, then聽it聽will聽be聽fine, but聽for聽a.js, document.body聽might聽be聽undefined when it聽executes, unless聽they聽both do聽that in聽a聽DOMContentLoaded event聽listener.
Note that DOMContentLoaded event listeners are executed in the registered order, so聽b.js鈥檚聽event listener would be聽called before聽a.js鈥檚 if聽only聽a.js has聽defer, which聽would still聽break聽things.
Also, the聽DOMContentLoaded event is聽only聽fired after all聽deferred scripts are聽executed, so聽you聽can聽do聽the聽following in聽a聽deferred script:
window.registerEventListener("DOMContentLoaded", event => {
... // Hydrate the聽DOM
});
You're ruining the exercise by giving away the answer @ExE-Boss :)
Most helpful comment
You're ruining the exercise by giving away the answer @ExE-Boss :)