kubetail-org / loadjs

A tiny async loader / dependency manager for modern browsers (899 bytes)
MIT License
2.58k stars 150 forks source link

Able to get js to work, but not css. #43

Closed KerryRuddock closed 7 years ago

KerryRuddock commented 7 years ago

As more people discover page insights they will be coming here to resolve render-blocking js and css and this is the reason why I am trying out your software. I tried implementing load.js on my javascript which worked great, but then I added links to my css in 1st two lines of loadjs and my website is now unstylized. Here is how I am using your loadjs software in my section: <-- <script> window.addEventListener('load', function() { loadjs(["https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css", "styles/style.css", "https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.2.4.min.js", "https://cdnjs.cloudflare.com/ajax/libs/waypoints/4.0.1/jquery.waypoints.min.js", "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js", "scripts/djmarketing.js"], { success: function djMain() { /* loaded in series */ }, async: false }); }); </script> -->

amorey commented 7 years ago

What problems are you running into? Here's a JSFiddle example based on your code snippet (but without the window.addEventListener call): https://jsfiddle.net/muicss/13w43zbx/2/

The example loads the Bootstrap CSS file successfully but can't find styles/style.css which is expected.

KerryRuddock commented 7 years ago

Hi Amorey,

Thanks for getting back to me. I removed what I posted yesterday as I thought it was human error, but I am experiencing FOUT after I placed my css links withing loadjs. Is there a way to get a private message to you so that I may give you my website?

amorey commented 7 years ago

Are you loading the CSS after the window load event fires? If so, that would explain the FOUT.

KerryRuddock commented 7 years ago

I am loading the css just the way I posted it here a few days ago all within my <head> section. What am I missing?

amorey commented 7 years ago

The browser will render the page (and then fire the window load event) after all the HTML, CSS, images and scripts that are present in the DOM to that point have been loaded. If you load CSS after the widow load event fires then that it will cause FOUT if it modifies the style of an element that is visible on the page.

Personally, I would recommend using plain old <link rel="stylesheet"> tags in the <head> for CSS that is required on pageload. To optimize pageload times you can serve static files from a CDN gzipped and served with the appropriate cache headers set.

KerryRuddock commented 7 years ago

I appreciate your feedback, so I am missing the interpretation of how loadjs works? I thought the window load event would not fire until loadjs completely processed all css and js passed to it?

amorey commented 7 years ago

loadjs adds elements to the DOM immediately so if you use it before window load then the browser will delay the firing of that event until those files have finished downloading as well.

I just ran some tests and confirmed that this is the behavior of loadjs but it appears that Chrome will sometimes display FOUT when a CSS file is loaded dynamically even if the file is loaded before the window load event fires. I'm not sure how to prevent this other than loading CSS files the old fashioned way.

amorey commented 7 years ago

@KerryRuddock Any updates on the FOUT issue?

KerryRuddock commented 7 years ago

Thanks Amorey for a follow up. Just to recap where we left off.

The workaround I am using came from this article and viewing his source on github which showed me that I could dynamically insert the bootstrap.min.css and then inline my own css afterwards seems to have resolved the FOUT.

.IE

 <script>
  var cb = function() {
    var l = document.createElement('link'); l.rel = 'stylesheet';
    l.href = 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css';
    var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
  };
  var raf = requestAnimationFrame || mozRequestAnimationFrame ||
  webkitRequestAnimationFrame || msRequestAnimationFrame;
  if (raf) raf(cb);
  else window.addEventListener('load', cb);
  </script>

I am closing this issue. Thank you for your help.

amorey commented 7 years ago

Great, thanks for the follow up. That's actually what loadjs does under the hood (with the added benefit of success/error callbacks and simple dependency management) so this is the equivalent with loadjs:

<script>
  var cb = function() {
    loadjs('//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css');
  };

  var raf = requestAnimationFrame || mozRequestAnimationFrame || webkitRequestAnimationFrame || msRequestAnimationFrame;
  if (raf) raf(cb);
  else window.addEventListener('load', cb);
</script>

I'm actually still seeing intermittent FOUT using the requestAnimationFrame method. I think this is because the first animation frame occurs after the window load event fires.

If your page requires the bootstrap CSS styles on page load why not load the stylesheet using a <link> tag in the <head>?

KerryRuddock commented 7 years ago

Oh I did have it that way originally, but my page speed scores were not great due to render blocking. I wish there was a way to private message you directly so that I could give you my web site linkages showing to demonstrate page speed scores before and after

amorey commented 7 years ago

Sure you can reach me here: contact@muicss.com