Когда браузеры начинают отображать частично переданный HTML? - PullRequest
7 голосов
/ 05 февраля 2010

У меня есть длительный отчет, и я хочу показать спиннер пользователю во время его генерации. Я уже сделал эту работу, но не уверен, что делаю это наилучшим или правильным способом.

Это использует ColdFusion, но я думаю, это может быть любой язык. В верхней части страницы у меня есть некоторый Javascript (jQuery), который показывает спиннер ожидания плюс есть обработчик documentReady, где я убираю спиннер. Я сбрасываю вывод (если это имеет значение), а затем остальная часть кода работает с содержимым отчета. Это никогда не отображало счетчик, и я предположил, что, хотя я и сбрасывал данные на сервере, по пути происходила некоторая буферизация, и браузер никогда не видел код счетчика, пока не стало слишком поздно. Итак, я добавил цикл прямо перед тем, как выплеснуть несколько сотен строк HTML-комментариев. После тонкой настройки количества строк, это добилось цели. Тогда я предположил, что так делают другие сайты.

Но: сегодня, когда я смотрел на другую мою страницу, которая выдает построчное состояние давно выполняемого задания, мне пришло в голову, что эта страница мигает после каждой строки, и браузер отображает ее постепенно по желанию. Это не соответствует моему заключению сверху, и теперь я не знаю, каковы правила. Есть ли предсказуемый способ сделать это? Это зависит от браузера?

УТОЧНЕНИЕ: я ценю ответы, которые пытаются объяснить правильный способ создания счетчика ожидания, но я просто использую счетчик ожидания в качестве примера, чтобы проиллюстрировать мой реальный вопрос: существуют ли надежные способы предсказать, когда браузеры начать рендеринг HTML, как он передается по сети? Из наблюдения видно, что браузеры не ждут начала работы тега / html. Этот вопрос не обязательно имеет отношение к Javascript. Например, та вторая страница, которую я описываю, показывает статус чистого HTML.

Ответы [ 4 ]

2 голосов
/ 05 февраля 2010

Если я вас правильно понимаю, вы хотите, чтобы изображение «загрузки» отображалось, пока страница все еще загружает контент.

Что я делаю, и что я считаю лучшим способом, это добавить разделитель.тег в верхней части вашей страницы, ближайший к тегу body, который содержит изображение / текст загрузки.Вы можете поместить этот div в другом месте с помощью некоторого css.

Затем попросите Jquery удалить этот div при загрузке страницы.Вместо использования $ (документ) .ready , как некоторые рекомендовали, я бы вместо этого использовал $ (окно) .load , поскольку он активируется, когда полная страница полностью загружена, включая всерамки, объекты и изображения.
Se ссылка здесь;http://4loc.wordpress.com/2009/04/28/documentready-vs-windowload/

Пример;

<body>    
<div id="loading" style="z-index:200; width:100%; height:40px; border-top:2px #D4D4D4 solid;  background:#E8E8E8; color:#000; position:fixed; bottom:0; left:0;">
    <div align="center">
        <img src="load.gif" alt="Loading...">
    </div>
</div>
<script type="text/javascript">
    $(window).load(function() { $("#loading").remove(); });
</script>
[...]

...

1 голос
/ 08 февраля 2010

Кроме встроенной задержки для Firefox, есть и другие области, которые заставляют браузер ждать перед рендерингом.

Когда HTML-страница отправляется в браузер, она должна сначала решить, куда пойти, прежде чем она сможет нарисовать экран. Например, таблицы печально известны тем, что вызывают задержки рендеринга. Чтобы нарисовать таблицу, браузер должен вычислить размеры столбцов. Если вы используете проценты в качестве ширины столбцов или не указываете их вообще, браузер должен получить всю таблицу перед рендерингом.

Однако, если вы используете что-то вроде атрибута table-layout: fixed; css, браузер может просто прочитать первую строку и начать рисовать, когда к ней поступают данные.

Другие теги могут вызывать похожие проблемы. По сути, всякий раз, когда браузер должен вычислить размер контента, он должен иметь весь контент для отображения. Если вы можете дать ему подсказки заранее с помощью элементов фиксированного размера (ширины / высоты), тогда браузеру не нужно ничего выяснять, и он может рисовать элементы по мере их загрузки.

Как правило, я никогда не позволяю браузеру определять что-либо. Вместо этого я даю своим элементам фиксированные размеры. В результате сайты, на которых я работаю, обычно имеют молниеносный рендеринг.

1 голос
/ 05 февраля 2010

--- Пост-разъяснение Ответ ---

Мой оригинальный ответ должен быть кому-то полезен (надеюсь), но это не прямой ответ на вопрос, поэтому я выложу другой ответ

Ответ на ваш вновь сформулированный вопрос "нет". В случае FF существует предварительно определенная начальная задержка рендеринга, но другие браузеры будут другими. Эту задержку рендеринга FF также можно настроить.

Используя FF в качестве примера, эти начальные 250 мс - время для FF найти хотя бы некоторую полезную информацию перед попыткой первого рендеринга. Затем он периодически делает дополнительные рендеры, когда узнает больше.

Невозможно определить, когда браузер начал отображать HTML-документ.

--- Оригинальный ответ ---

Чтобы прямо ответить на ваш вопрос, я полагаю, что Firefox ждет 250 мс, прежде чем действовать на основании первых полученных данных, но это можно изменить. Для других браузеров я не знаю.

Однако вы не хотите идти по этому маршруту.

Когда jQuery будет готов применить свою магию, он сообщит вам, запустив $(document).ready(). До этого любая попытка использовать jQuery потерпит неудачу. Другими словами, ваш счетчик не появляется, потому что jQuery еще не готов обработать этот запрос.

Рассмотрим следующий пример, где на экране отображаются два заполнителя, и мы будем использовать jQuery, чтобы скрыть их.

<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
        <script>

            // We're not ready yet.  This will fail.
            $(".placeholder").hide();

            $(document).ready(function(){
                // This won't fail
                $("#one").hide();
            });

        </script>
    </head>
    <body>
        <div id="one" class="placeholder">Placeholder One</div>
        <div id="two" class="placeholder">Placeholder Two</div>
    </body>
</html>

Сначала может показаться, что $("#one").hide(); избыточен, но это не так. $(".placeholder").hide(); вызывается до того, как jQuery будет готов, поэтому он не имеет никакого эффекта, поэтому вы увидите «Placeholder Two» (а не «Placeholder One»), если вы запустите разметку выше в веб-браузере.

Теперь, когда мы имеем это в стороне, решение более крупной проблемы («правильный путь») - AJAX.

  1. Загрузить базовую страницу, содержащую код счетчика. Убедитесь, что код для загрузки счетчика работает как часть $(document).ready().
  2. Используйте функциональные возможности jQuery AJAX , чтобы получить нужный отчет.
  3. Когда он вернется, скройте счетчик, вставьте отчет на свою базовую страницу.

Удачи!

0 голосов
/ 05 февраля 2010

Я ожидаю, что это будет зависеть от браузера: некоторые начнут рендериться до того, как страница будет полностью получена; другие будут ждать весь HTML-файл перед запуском.

Хочу отметить, что в спецификации HTTP Response предусмотрен заголовок «206 Partial Content», который может дать некоторую надежду на кросс-браузерное решение, которое стоит изучить.

Почти наверняка есть несколько способов его обрезать, но моей непосредственной идеей было бы доставить заглушку, а затем использовать ajax для извлечения и рендеринга фрагментов по требованию. Например, многие большие сайты, по-видимому, изначально предоставляют минимальное представление, тогда, если вы прокрутите достаточно вниз, он сгенерирует запрос ajax, чтобы получить больше данных и добавить их на страницу. например: facebook, slashdot.

Я не могу представить, что это слишком сложно реализовать; даже при простуде Вы запускаете счетчик, когда запускаете запрос ajax, и останавливаете его, когда вызывается обратный вызов.

...