Перейти к основному содержимому

📄 Процесс загрузки веб-страницы

1. Объясните, как браузер получает HTML от сервера и отображает его на экране

Опишите, как браузер запрашивает HTML у сервера и рендерит его на экране.

1. Инициация запроса

  • Ввод URL: Когда пользователь вводит URL в браузере или нажимает на ссылку, браузер начинает разбор URL, чтобы определить, на какой сервер отправить запрос.
  • DNS-запрос: Браузер выполняет DNS-запрос для разрешения соответствующего IP-адреса сервера.
  • Установка соединения: Браузер отправляет запрос на IP-адрес сервера через интернет, используя протокол HTTP или HTTPS. Если это HTTPS, также необходимо установить SSL/TLS-соединение.

2. Ответ сервера

  • Обработка запроса: После получения запроса сервер считывает соответствующие данные из базы данных на основе пути запроса и параметров.
  • Отправка ответа: Затем сервер отправляет HTML-документ как часть HTTP-ответа обратно в браузер. Ответ также включает информацию, такую как коды состояния и другие параметры (CORS, content-type и т.д.).

3. Разбор HTML

  • Построение DOM Tree: Браузер читает HTML-документ и преобразует его в DOM-узлы на основе HTML-тегов и атрибутов, строя DOM Tree в памяти.
  • Запрос вложенных ресурсов: При разборе HTML, если браузер встречает внешние ресурсы, такие как CSS, JavaScript или изображения, он отправляет дополнительные запросы на сервер для получения этих ресурсов.

4. Рендеринг страницы

  • Построение CSSOM Tree: Браузер разбирает CSS-файлы для построения CSSOM Tree.
  • Render Tree: Браузер объединяет DOM Tree и CSSOM Tree в Render Tree, который содержит все видимые узлы и их соответствующие стили.
  • Layout (Компоновка): Браузер выполняет компоновку (также называемую Reflow), рассчитывая позицию и размер каждого узла.
  • Paint (Отрисовка): Наконец, браузер проходит этап отрисовки, рисуя содержимое каждого узла на странице.

5. Взаимодействие с JavaScript

  • Выполнение JavaScript: Если HTML содержит JavaScript, браузер разбирает и выполняет его. Это может модифицировать DOM и обновить стили.

Весь процесс носит прогрессивный характер. Теоретически пользователи сначала увидят частичное содержимое страницы до полной загрузки. В ходе этого процесса может быть вызвано несколько reflow и repaint, особенно когда страница содержит сложные стили или интерактивные эффекты. Помимо собственных оптимизаций браузера, разработчики обычно используют различные техники для обеспечения более плавного пользовательского опыта.

2. Опишите Reflow и Repaint

Reflow

Reflow означает, что изменения в DOM веб-страницы заставляют браузер пересчитать позиции элементов и разместить их в правильных местах. Проще говоря, макет необходимо сгенерировать заново для переупорядочивания элементов.

Триггеры Reflow

Reflow возникает в двух сценариях: один — глобальное изменение, затрагивающее всю страницу, другой — частичное изменение, затрагивающее определённые области компонентов.

  • Начальная загрузка страницы — самый значительный reflow.
  • Добавление или удаление DOM-элементов.
  • Изменение размеров элемента, например, увеличение содержимого или изменение размера шрифта.
  • Корректировка макета элемента, например, изменение margin или padding.
  • Изменение размера окна браузера.
  • Срабатывание псевдоклассов, таких как эффекты hover.

Repaint

Repaint происходит, когда внешний вид элемента изменяется без влияния на макет. Поскольку элементы содержатся внутри макета, reflow всегда вызывает repaint. Однако repaint сам по себе не обязательно вызывает reflow.

Триггеры Repaint

  • Изменение цвета или фона элемента, например, добавление цвета или изменение свойств фона.
  • Изменение box-shadow или border элемента также считается repaint.

Как оптимизировать Reflow и Repaint

  • Избегайте табличных макетов. Свойства таблиц склонны вызывать пересчёт макета при изменении. Если таблицы неизбежны, рассмотрите добавление свойств table-layout: auto; или table-layout: fixed; для рендеринга по одной строке за раз и ограничения затронутой области.
  • Вместо манипуляций с DOM для изменения стилей по одному, определите необходимые стили в CSS-классе и переключайте его через JavaScript.
    • Например, во Vue можно использовать привязку классов для переключения стилей, а не напрямую менять стили через функцию.
  • Для сценариев, требующих частого переключения (например, переключение вкладок), предпочитайте v-show вместо v-if. Первый просто использует CSS display: none; для скрытия элементов, тогда как второй запускает жизненный цикл компонента, создавая или уничтожая элементы, что приводит к большим затратам производительности.
  • Если reflow неизбежен, используйте requestAnimationFrame для оптимизации (поскольку этот API предназначен для анимаций и синхронизируется с частотой кадров браузера). Это позволяет объединить несколько reflow в один, уменьшая количество repaint.
    • Например, если анимации нужно двигаться к цели на странице, можно использовать requestAnimationFrame для расчёта каждого шага движения.
    • Аналогично, определённые CSS3-свойства могут задействовать аппаратное ускорение на стороне клиента, улучшая производительность анимаций, такие как transform, opacity, filters и Will-change.
  • По возможности изменяйте стили на узлах DOM нижнего уровня, чтобы избежать запуска каскадных изменений стилей родительских элементов на все дочерние.
  • Для анимаций используйте элементы с позиционированием absolute или fixed. Это минимизирует влияние на другие элементы, вызывая только repaint без reflow.

Пример

// плохо
const element = document.querySelector('.wrapper');
element.style.margin = '4px';
element.style.padding = '6px';
element.style.borderRadius = '10px';
// хорошо
.update {
margin: 4px;
padding: 6px;
border-radius: 10px;
}

const element = document.querySelector('.wrapper');
element.classList.add('update');

Ссылки

3. Опишите, когда браузер отправляет OPTIONS-запрос на сервер

Объясните, когда браузер отправляет OPTIONS-запрос на сервер.

В большинстве случаев это применяется к сценариям CORS. Перед отправкой фактического запроса выполняется предварительная проверка (preflight), при которой браузер сначала отправляет OPTIONS-запрос, чтобы узнать у сервера, разрешён ли межсайтовый запрос. Если сервер отвечает разрешением, браузер переходит к отправке фактического запроса. В противном случае браузер выдаёт ошибку.

Кроме того, если метод запроса не является GET, HEAD или POST, это также вызывает OPTIONS-запрос.