Brooke Holmes
Brooke Holmes

Reputation: 1622

Negate inconsistent (and late) page rendering in safari

The situation

I have been attempting to create a react application. The index page that is loaded first contains a basic CSS and HTML loading animation and then the external scripts and CSS in a blocking order right before </body>, with the last script removing the loader animation and showing the page.

The intended purpose of this is to load a very small page (2KB in total) containing a loading animation and then load the 8MB of scripts, stylesheets and images, creating a more seamless user experience.

<html>
  <head>
    ...
    [loader css]
  </head>
  <body>
    <div id="loader">...</div>

    <script src="..."></script>
    <script src="..."></script>
    <link href="..." type="text/css" rel="stylesheet" />

    <script> [remove #loader] </script>
  </body>
</html>

The problem

This works great in Chrome, as it immediately renders the page (loading animation) and then the external dependencies. But because safari has weird, inconsistent, and ostensibly non-deterministic loading practices:

Safari starts loading the contents of the new web page, but does not start rendering it until it has loaded a sufficient amount of information.

this approach does not work; it'll just show the address bar loading indicator (for the dependencies above the closing body tag) and a blank page instead of rendering the HTML straight away.


If anybody has a solution that:

that would be enormously appreciated. Thank you!

Upvotes: 5

Views: 1117

Answers (1)

Owen
Owen

Reputation: 1547

The real problem is that browsers cannot be certain your JavaScript is safe to skip over until it's been loaded, parsed, and executed. If you were to add the defer attribute to your scripts the page will load and display without waiting for the assets to download - but the removal of the loader will also execute without waiting.

Consider a combination of adding defer to the external scripts and making the loader removal script itself an external defer script. According to some defer scripts are supposed to execute in the order they were specified. (Also take note of the references to async and DOMContentLoaded on that comment.)

React.js might also provide come callbacks that could be used more reliably than DOMContentReady.

Upvotes: 1

Related Questions