Использование dns-prefetch
==========================

**`DNS-prefetch`** (предзагрузка DNS) - это попытка определить IP адрес по имени домена до того, как ресурс с этого домена будет фактически запрошен. Это может быть загрузчик файлов, который используется позже или ссылка, по которой, вероятно, перейдёт пользователь.

Зачем использовать dns-prefetch?
--------------------------------

Бывают случаи, когда в вашем приложении используются ссылки на домены, отличные от основного домена приложения. Например, внутри вашего приложения на "a.com" есть ссылка на домен "b.org". Для того, чтобы пройти по этой ссылке, пользовательский клиент должен сначала выяснить, какой адрес в интернете соответствует доменному имени "b.org". Этот процесс называется `DNS resolution.` И хотя механизмы кеширования DNS помогают сократить время запросов, DNS Resolution заметно влияет на время ожидания запроса из-за того, что первый клиентский запрос уходит сначала на DNS сервера и дожидается ответа от них. Для приложений, которые открывают соединения ко многим сторонним доменам, влияние DNS Resolution может сильно уменьшить производительность загрузки.

`dns-prefetch` помогает разработчикам замаскировать ожидание DNS resolution. HTML `<link>` элемент предлагает подобную функциональность с помощью атрибута `rel` (en-US), значение которого может содержать `dns-prefetch`. В этом случае, предзагрузка DNS произойдёт для домена, указанного в атрибуте href:

Синтаксис
---------


```html
<link rel="dns-prefetch" href="https://fonts.gstatic.com/" />
```

Примеры
-------


```html
<html>
  <head>
    <link rel="dns-prefetch" href="https://fonts.gstatic.com/" />
    <!-- and all other head elements -->
  </head>
  <body>
    <!-- your page content -->
  </body>
</html>
```


Вы должны помещать `dns-prefetch` подсказки в элемент `<head>` для каждого уникального стороннего домена, с которого могут быть запрошены ресурсы, но нужно держать некоторые детали в голове.

Лучшие практики
---------------

Необходимо учитывать 3 вещи:

**Во-первых,** `dns-prefetch` эффективен только для выполнения DNS запросов на сторонние cross-origin домены, поэтому следует избегать этой инструкции при попытке загрузить ресурсы с текущего домена. Связано это с тем, что IP вашего домена уже был определён к тому времени, когда браузер увидел эту инструкцию.

**Во-вторых,** существует возможность добавить `dns-prefetch` (и другие подсказки) как HTTP заголовок с помощью HTTP Link field (en-US):
```

Link: <https://fonts.gstatic.com/>; rel=dns-prefetch
```


**В третьих,** хорошей практикой считается использование `dns-prefetch` в паре с `preconnect`. В то время, как `dns-prefetch` срабатывает только при DNS поиске, `preconnect` устанавливает соединение к нужному серверу. Этот процесс включает в себя DNS resolution, установку TCP соединения и установление безопасного соединения (TLS рукопожатие), если оно доступно. Комбинирование этих двух инструкций даёт возможность ещё больше сократить время ожидания для кросс-доменных запросов. Вы можете использовать их вместе таким образом:


```html
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin />
<link rel="dns-prefetch" href="https://fonts.gstatic.com/" />
```


**Примечание:** если приложению необходимо установить соединение со множеством доменов, использование preconnect контрпродуктивно. `preconnect` лучше использовать для наиболее критических соединений. Для менее важных достаточно использовать `<link rel="dns-prefetch">` для сокращения времени DNS запроса.

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

Некоторые ресурсы, например, шрифты, загружаются в анонимном режиме. В подобных случаях вы должны указывать crossorigin атрибут с инструкцией preconnect. Если вы пропустите её, то браузер выполнит только DNS запрос.

Смотрите также
--------------

* <link>
* HTML атрибут: rel (en-US)
* crossorigin
* Cross-Origin Resource Sharing (CORS)
* HTTP заголовки
* HTTP заголовок Link (en-US)