4

Both Firefox and Chrome is rendering my pages way too early, which results in my a couple of frames where you first see the header, then the content, and then the footer. It's a very very unpleasant page loading experience.

The way I get around this right now is this, which is such a silly workaround I would like to avoid. It also causes the page to flash white in Chrome.

<!DOCTYPE html>
<html>
<head>...</head>
<body>
    <div id="render-all-at-once" style="opacity:0; min-height:100%;">
        content
    </div>
    <script>
        document.getElementById("render-all-at-once").style.opacity = 1;
    </script>
</body>
</html>

The problem is basically this:

<script>
    function sleep(millis) {
        var date = new Date();
        var curDate = null;
        do { curDate = new Date(); }
        while (curDate - date < millis);
    }
</script>

<div>
    This will be rendered in the first frame.
</div>

<script>
    sleep(3000);
</script>

<div>
    And only after that first frame has been rendered will you see this line. You don't see the first line for 3 seconds as 
    you might, but you do see it flash, right before both lines are displayed.
</div>
<!---
    I would like the browser to not render anything until 
    the entire entire document has been processed.
--->

In isolated tests, the above code seem to work as expected - both lines will be rendered at the same time after 3 seconds. But as soon I start adding a couple of random style-sheets to the page, the problem starts occurring.

I can't seem to narrow it down to any particular style-sheet or style. I can't figure out what's causing it. I've both tried loading all styles sheets from , or just having all of them inlined in a style element. This doesn't make any difference. I'm testing this using Chrome as it seems to happen more frequently there.

Does anyone have any experience with this sort of problem, or have any ideas what's causing it, and know of any way to prevent it?

BjarkeCK
  • 5,694
  • 5
  • 41
  • 59
  • 1
    The *sleep* function is likely a cause of some of your issue. It's a seriously flawed approach and will consume as much CPU as it can until the limit is reached. – RobG Feb 18 '19 at 20:18
  • 1
    @RobG It's just to simulate random processing. The problem seem to occur even if there's no javascript involved and there's just a lot of elements to process. – BjarkeCK Feb 18 '19 at 20:21
  • 1
    @BjarkeCK—way back in the early days of dialup, some browsers would not display anything until the entire page was downloaded. Users didn't like it, much preferring to see content as soon as possible and put up with refreshes and layout "jiggles" rather than stare at a blank page wondering if anything was happening. That's why all browsers I know of do progressive display. Much better to adopt an approach where issues with progressive display are minimised rather than hiding the page until it's loaded. – RobG Feb 18 '19 at 20:34
  • 1
    @RobG Ohh, that's actually a really cool insight, it makes sense that they would do it back in the days. But I strongly disagree that progressively loading a website is a good idea today. If you're building a really fast and snappy website, then boy is it annoying that the browser decides to ruin the experience by displaying several frames of an unfinished rendered website, even though everything is ready after only 10ms. I think we should always strive for better website and better user experiences, and the browser should enable us to do so. – BjarkeCK Feb 18 '19 at 20:43
  • 2
    Not everyone has speedy connections Mobile connections can be spotty. And rural communities (Think rural CA North of say, Chico : Trinity in the mountains, for example, all connections are still slow, and cell signals are difficult to find, period.) Even Santa Cruz has numerous cellular dead zones - and it's *really* close to silicon valley. I get your point. But your experience may be one of privilege. I wish you luck on finding a solution, but please Remember to have a good fallback for everyone else. Geography can pay a role in connecting availability and speeds. – SherylHohman Feb 18 '19 at 21:20
  • 1
    @SherylHohman Yeah, I can see I probably shouldn't be so opposed to the idea. Thanks for the insight! Still think the browser could handle it a little better though :) – BjarkeCK Feb 18 '19 at 21:38
  • @BjarkeCK—browser developers have been dealing with it for 20 years or more, they do what they do because they think it's the best approach. You won't find many (any?) of the big players in either browsers or web content that deliberately delay rendering or page display. They try to optimise their HTML for layout (e.g. give things like frames and images a size so the layout engine doesn't have to load the entire content and work it out). I'm sure there are plenty of published strategies. – RobG Feb 18 '19 at 22:29

2 Answers2

3

What I like to do is wrap my content in a div and set it to display:none.

Then, I defer my CSS loading and in my CSS file, and set that wrap div to display:block.

I also compress all my CSS files into one single file (for better loading).

<!DOCTYPE html>
<html>
    <head>
        <style>
            .wrap {
                display: none;
            }
        </style>
    </head>

    <body>
        <div class="wrap">
            content
        </div>
        <noscript id="deferred-styles">
            <link rel="stylesheet" type="text/css" href="compressed.css" />
        </noscript>
        <script>
            var loadDeferredStyles = function() {
                var addStylesNode = document.getElementById("deferred-styles");
                var replacement = document.createElement("div");
                
                replacement.innerHTML = addStylesNode.textContent;
                document.body.appendChild(replacement);
                addStylesNode.parentElement.removeChild(addStylesNode);
            };

            var raf = requestAnimationFrame || mozRequestAnimationFrame ||
                webkitRequestAnimationFrame || msRequestAnimationFrame;

            if(raf) {
                raf(function() {
                    window.setTimeout(loadDeferredStyles, 0);
                });
            } else {
                window.addEventListener('load', loadDeferredStyles);
            }

        </script>
    </body>
</html>
NoxFly
  • 179
  • 1
  • 12
imvain2
  • 15,480
  • 1
  • 16
  • 21
  • Happy to know i'm not the only one with this problem! Will try your approach and see if that works any better. Thanks! Still annoying that you have to do those sort of tricks. – BjarkeCK Feb 18 '19 at 19:56
0

Use the network tab in developer tools to see the process & response of each request. First, the HTML is fully received and parsed by the browser which then looks for remote objects to load top-down: stylesheets, images, javascript, etc.

So, to have complete control over how things appear, send an HTML document that looks exactly as you'd like the initial view to be (ex: a blank white document, achieved with inline CSS or a <style> tag that targets <body>). Then use a line of Javascript to listen for the load event and update your display, for example:

<!doctype html>
<html>
    <link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/stackoverflow/primary.css">
    <body style="display: none;">
        <h1>Headline</h1>
    </body>
    <script>
        window.addEventListener("load", function(event) {
            document.querySelector("body").style.display = "block";
        });
    </script>
</html>
Charlie Schliesser
  • 7,851
  • 4
  • 46
  • 76
  • I've reproduced this with no references to anything, where all styles was inlined and no images was used. Wouln't this exclude all networking related errors? – BjarkeCK Feb 18 '19 at 20:03
  • I'm interested in seeing your file! Specifically, when you mentioned "the header, then the content, and then the footer" – I've never seen a browser behave this way unless the server was sending the response in chunks or the page is using Javascript to intermediately alter the DOM. – Charlie Schliesser Feb 18 '19 at 20:04
  • Sure! Hope this is clear enough :) https://imgur.com/a/1fgwI8a – BjarkeCK Feb 18 '19 at 20:14