Глядя на индикатор выполнения браузера, который иногда замедляется ближе к концу загрузки веб-страницы, я задался вопросом, отображает ли браузер прогресс на основеразмерэлементов, присутствующих на странице илинет.элементов или чего-то еще?
Может быть, кто-то, кто проверял исходный код Firefox или какого-то другого браузера, знает об этом немного подробнее?
решение1
Чтоявляетсязагрузка веб-сайта?
Загрузка веб-страницыявляетсяболее или менее похоже на загрузку файла. То, что вы получаете от сервера, в большинстве случаев — это просто HTML-файл, переданный по HTTP. Сначала вы делаете HTTP-запрос на URL-адрес сайта, например GET http://superuser.com
.
Как сказал Уильям Джексон, HTTP используетContent-Length
поле заголовка, чтобы заранее показать вам размер этого файла. Это то, что браузер может оценить, чтобы предположить, насколько продвинулась загрузка всего сайта.
Однако это не охватывает все ресурсы, которые HTML-файл может загрузить, ссылаясь на них. Они могут включать:
- Внешние изображения
- Внешние таблицы стилей
- Внешние скрипты
- Рамки
- AJAX-загрузки
Как браузер узнает, сколько данных нужно загрузить?
Теперь задача браузера — найти эти ссылки и запросить их. Поэтому для каждой внешней ссылки браузер либо обратится к своему кэшу, либо отправит новый HTTP-запрос. Для Super User это будут следующие файлы, размещенные в сетях распространения контента для более высокой производительности:
GET http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js
– основной файл jQueryGET http://cdn.sstatic.net/js/stub.js
– некоторые функции JSGET http://cdn.sstatic.net/superuser/all.css
– таблица стилей- ...
Вы можете увидеть это с помощью Firebug или отладчика Chrome, когда вы включите отслеживание временной шкалы. Это временная шкала загрузки Super User, отфильтрованная так, чтобы отображались только запросы. Нажмите для увеличения:
Как мы видим, основной сайт Super User будет загружаться дольше всего, но каскадно от него идут другие загрузки страниц (например, HTTP-запросы или запросы кэша). Все они также раскрывают свои Content-Length
, поэтому браузер может сделать хорошее предположение о том, сколько времени потребуется для загрузки всех этих файлов.
И поскольку все это происходит в течение очень короткого промежутка времени, вы не заметите небольших неровностей в полосе прогресса. Иногда вы увидите, что полоса прогресса зависает на двух третях — это может быть, когда браузер не может загрузить внешний ресурс так же быстро, как другие.
Как браузеры это реализуют?
Гугл Хром
Я заглянул в исходники Google Chrome (он же Chromium) и нашел этот класс под названиемProgressTracker.cpp. На самом деле, это написано Apple, так что, скорее всего, это происходит отВебкитдвижок рендеринга. Включает в себя следующие поля:
ProgressTracker::ProgressTracker()
: m_totalPageAndResourceBytesToLoad(0)
, m_totalBytesReceived(0)
Таким образом, как я уже сказал, будет определено общее количество байтов ресурсов, и прогресс будет изменен соответствующим образом. Есть интересный комментарий, который показывает, как повышается фактическая важность первой загруженной страницы:
// Для документов, использующих систему макетов WebCore, рассматривать первый макет как промежуточную точку.
Таким образом, если первая страница загружена (а ее внешние ресурсы еще не загружены), прогресс составит 50%.
Firefox (надстройка Fission)
Теперь есть еще немного более простая метрика. Я рассмотрелДеление, расширение прогресс-бара для Firefox. Если я правильно понял, оно делает то, что можно легко придумать.
Каждый веб-сайт состоит из рядаЭлементы DOM. Анализируя первый HTML-сайт, можно оценить общее количество элементов DOM, которые необходимо загрузить.
Для каждого загруженного элемента DOM увеличивайте счетчик и просто отображайте индикатор выполнения в соответствии с ним.
решение2
Когда браузер запрашивает файл с сервера, сервер имеет возможность заранее сообщить браузеру, насколько велик файл. Сервер делает это, отправляяЗаголовок Content-Length.
Есть и другая информация окак браузер может определить размер загружаемого файла.