Frage

Normally, external-file javascripts block window's load and DOMContentLoaded events, like, for instance, if we were to have:

<script src="http://so.me/file.js"></script>

...then the DOM renderer would pause work as http://so.me/file.js downloaded and executed.

Now, let's suppose that instead of the above, we have:

<script type="not-js" src="http://so.me/file.js"></script>

I know that it would download but not execute the resource, but as it downloaded, would the page renderer halt as above, or not?

War es hilfreich?

Lösung

There was a talk on Google I/O 2012 from Ryan Fioravanti called Building High Performance Mobile Web Applications where he used this exact technique to download scripts but prevent them from being executed. He would then execute the scripts by appending them to the DOM.

See the part where he explains it here.

He explains that the page rendering time got significantly faster and that was because the JavaScript did not execute and prevent the page rendering procedure.

would the page renderer halt as above, or not

My answer is no. Maybe someone with more detailed knowledge about browser internals could give you a definitive answer.

Andere Tipps

You might give it a try, but my guess is that it would. You could get around this the same way that Google Analytics and Facebook Connect write async script references to the DOM.

For example:

<!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
<script>
    var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview']];
    (function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
    g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
    s.parentNode.insertBefore(g,s)}(document,'script'));
</script>

You could use the same approach if you're worried about your script reference blocking.

Are you looking for: <script defer="defer"></script> so that the script doesn't suspend loading the rest of the website?

Kernel's solution is probably what you are looking for

you can either use <script src="http://so.me/file.js" defer></script> or <script src="http://so.me/file.js" async></script>

  • defer : load in parallel and execute in order
    • supported in almost all browsers including older versions of IE ..however execution order is not always respected even though it should be..
  • async: load in parallel and execute as soon as possible
    • supported in almost all browsers browsers except IE where support was only added in IE10

Landon's solution is the same as using async, except you are controlling things programmatically.

...that said, almost all modern browsers will default to the defer method, whether you specify something or not. Try loading a bunch of scripts in a classic manner in FF or Chrome while looking at the waterfall chart in their developer tools (or Fiddler), and you'll see that they load everything in parallel even though you didn't even ask them to :)

Refined solution (should work in any browser):

<html>
   <head></head>
   <body>


      <script>
         window.onload = function() {
            var s  =  document.createElement("script");
            s.type = "text/javascript";
            s.src  = "http://so.me/file.js";

            document.getElementsByTagName("head")[0].appendChild(s);
         }
      </script>
   </body>
</html>

Then again if you're willing to do this, you can just as well stick your scripts at the end of your document right before </body>.

Anything you stick in your <head> or before </body> will cause rendering to halt, but that doesn't mean it's a problem ..a page is rendered from top to bottom, so once you get to </body> even if onload hasn't fired yet, your page is already visible to the end user.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top