开发者

I didn't know that would happen when 'lazy loading' JavaScript

开发者 https://www.devze.com 2023-03-21 15:22 出处:网络
I created the example below where the page loads the temp.js dynamically at the bottom of the HTML page. The temp.js has a little sleep function which binds up browser for 3 seconds before logging \'S

I created the example below where the page loads the temp.js dynamically at the bottom of the HTML page. The temp.js has a little sleep function which binds up browser for 3 seconds before logging 'Script Loaded'. At the very bottom of the HTML page it logs a 'Page Loaded'

Now, knowing what I know about browsers, downloading resources and the single threaded nature of JS I thought this would happen.

  1. HTML is displayed
  2. console.log 'Page Loaded'
  3. About a three seconds wait whilst temp.js does it stuff
  4. console.log telling me 'Script Loaded'

but what in fact happens is this

  1. console.log 'Page Loaded' (almost instantly)
  2. Blank page for about three seconds
  3. HTML is displayed and console.log telling me 'Script Loaded'

Is this the behaviour you would have expected?


function sleep (ms) {
  var now = (new Date()).getTime ();
  while ((now + ms) > ((new Date()).getTime ())) {
  }
}
sleep (3000);
console.log ('Script Loaded');

<html lang="en-US">
  <head>
    <meta charset="UTF-8">
    <title>querySelectorAll</title>
  </head>
  <body>
    <ul>
      <li><a href="">One</a></li>
      <li><a href="">Two</a></li>
    </ul>

    <div id="nick">
      <img src="image.png" alt="" width="10" height="10" />
      <img src="image.png" alt="" width="10" height="10" />
      <img src="image.png" alt="" width="10" height="10" />
    </div>
    <!-- <script type="text/javascript" src="temp.js"></script> -->
    <script type="text/javascript">
      (function() {
        var e = document.createElement('script');
        e.src = 'temp.js';
        e.async = true开发者_开发百科;
        document.getElementsByTagName("head")[0].appendChild(e);
      })();
    </script>
    <script type="text/javascript">
      console.log('Page Loaded');
    </script>
  </body>
</html>


What happens

  • Some HTML is parsed
  • <script> block 1 is parsed and it adds a new script tag to the <head>
  • <script> block 2 is parsed and it logs page is loaded
  • <script> block in head is parsed and it runs your blocking sleep function
  • 3 seconds pass
  • Script loaded is logged
  • <head> block has finished parsing and it renders the <body>
  • Page is displayed.

Change

document.getElementsByTagName("head")[0].appendChild(e);

To

document.getElementsByTagName("body")[0].appendChild(e);

And the HTML page will load first.

The problem is that all scripts in the <head> have to be loaded and run before the HTML body is rendered


I don't know what the support or behaviour of async is across browsers, but I suspect the main problem is with your sleep function.

Usually a sleep function will do exactly what it says - pause the currently executing thread and wake it up again in x seconds. Your sleep function is doing anything but - it is executing the while loop conditional (now + ms) > ((new Date()).getTime ()) as many times as the browser is capable of. This will certainly lock up any other Javascript execution, and depending on the browser would presumably affect page rendering as well.

You want to use setTimeout to emulate sleep in Javascript:

setTimeout(function() {
console.log ('Script Loaded');
}, 3000);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号