首页 > 解决方案 > 防止浏览器在加载文档时部分呈现页面

问题描述

Firefox 和 Chrome 都过早地渲染我的页面,这导致我在几个框架中首先看到页眉,然后是内容,然后是页脚。这是一个非常非常不愉快的页面加载体验。

我现在解决这个问题的方法是这样,这是一个我想避免的愚蠢的解决方法。它还会导致页面在 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>

问题基本上是这样的:

<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.
--->

在独立测试中,上面的代码似乎按预期工作 - 两行将在 3 秒后同时呈现。但是一旦我开始向页面添加几个随机样式表,问题就开始出现了。

我似乎无法将其缩小到任何特定的样式表或样式。我不知道是什么原因造成的。我都尝试从 加载所有样式表,或者只是将它们全部内联在样式元素中。这没有任何区别。我正在使用 Chrome 对此进行测试,因为它似乎在那里更频繁地发生。

有没有人对这种问题有任何经验,或者有任何想法是什么原因造成的,并且知道有什么方法可以防止它?

标签: javascripthtmlcss

解决方案


我喜欢做的是将我的内容包装在一个 div 中并将其设置为display:none.

然后,我推迟我的 CSS 加载并在我的 CSS 文件中,并将包装 div 设置为display:block.

我还将所有 CSS 文件压缩到一个文件中(以便更好地加载)。

<!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>

推荐阅读