Closed khrome83 closed 7 years ago
🤔 AFAIK If you defer the parsing of common.js and main.js and try to parse (and execute) the code for your view you are going to have an error because your view code depends on common.js and main.js code to work
First page load is server rendered. So do need common.js and main.js to run until, after the site downloads? I am just curious.
@khrome83 You are correct. We can't async those scripts since they need to be load in sequence. But we can defer them.
@arunoda the most bulletproof solution to deferring scripts that I've come across is this:
https://varvy.com/pagespeed/defer-loading-javascript.html
As the article explains, adding the the defer
or async
attributes to script tags doesn't actually allow the page to fully load. You can see the results of different approaches in the various demos he's put together.
Hope this helps :)
@wagerfield thanks.
defer
is all what we need. Since we are not supporting IE9 that's work for us great.
Thank you @arunoda for getting this in.
@arunoda did you read the article? Adding the defer
attribute doesn't actually solve the problem.
This isn't an archaic method for supporting IE9—this is a behaviour that the latest version of Chrome and other modern browsers experience.
If you take a look at the various examples he put together, you will see that adding the defer
attribute doesn't prevent a loaded script from blocking the critical rendering path. If a deferred script starts executing as soon as it loads, it will stop the page from fully loading.
https://varvy.com/pagespeed/defer/defer-example-defer.html
In Chrome you will see the loading spinner on the tab where the favicon normally is persist for 2-3 seconds while the deferred script setTimeout
is waiting to return—and is thus blocks the critical rendering path.
Furthermore if you open Chrome dev tools and go to the Network tab, you will also see that the page doesn't Load
for ~2-3secs.
If you then take a look at the 'solved' example you will see that a) the browser tab loading spinner doesn't stall and b) that the Load
event fires in the dev tools Network
tab after ~3-400ms.
@wagerfield yep. I didn't read the article well. What's available here is correct.
I don't like it's use of window.onload but I'll try to use 'DOMContentLoaded'. I'll re-work my PR.
@wagerfield Actually, I had to use setTimeout(fn, 0)
hack to make it work with DOMContentLoaded
.
I think, it's not started rendering yet at that point. Here's the code:
<html>
<head>
<script type="text/javascript">
// Add a script element as a child of the body
function downloadJSAtOnload() {
setTimeout(function() {
var element = document.createElement("script");
element.src = "/defer-example-solved_files/defer.js";
document.body.appendChild(element);
}, 0)
}
// Check for browser support of event handling capability
document.addEventListener("DOMContentLoaded", downloadJSAtOnload, false);
</script>
</head>
<body>
<h1>I wait 2 seconds then ...</h1>
<p id="inner"></p>
</body>
</html>
In what way would it be better to use setTimeout, 0 with DomContentLoaded than relying onLoad @arunoda ?
What is there not to like about onLoad? Its been proven since 1999 or something.
onload is working properly and it runs after all the resources in the page completed. That's good for external scripts.
But this for our main JS bundle. We need to load as soon as possible without rendering the bundle.
I face an issue currenly because I nees to load two scripts in sequence. But I can't download them in parallel. I am thinking ways to do it now
I think react server uses LABjs. Load and block for them to get correctly sequenced. You might take a look at that. It's from yahoo.
Thanks @ptomasroos Yeah! Labjs is kind a interesting and something I was looking for. But the thing is, we need to test a bit more and it'll take time.
So, I'm going with the defer
attribute for now.
Should next.js defer parsing of JS for the common.js and main.js bundles?
Not familiar with the architecture or how to do this, but it came up as a performance issue.
All but 1.5kb was from common.js and main.js code.