Реализация Resource Hints (preload, prefetch, preconnect, dns-prefetch) для сайта

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация Resource Hints (preload, prefetch, preconnect, dns-prefetch) для сайта
Средняя
от 1 рабочего дня до 3 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация Resource Hints (preload, prefetch, preconnect, dns-prefetch) для сайта

Resource Hints — это директивы браузеру: начни делать эту работу прямо сейчас, не жди, пока парсер до неё доберётся. Разница между правильно расставленными подсказками и их отсутствием — 300–800 мс на реальном мобильном устройстве. Неправильно расставленные подсказки могут навредить: занять полосу пропускания нужными запросами или вытеснить критичные ресурсы из кеша.

Четыре директивы и их смысл

dns-prefetch — заранее резолвит DNS для домена. Стоит копейки по ресурсам, даёт 20–120 мс экономии при первом запросе к домену.

<link rel="dns-prefetch" href="//cdn.example.com">
<link rel="dns-prefetch" href="//fonts.googleapis.com">
<link rel="dns-prefetch" href="//www.google-analytics.com">

preconnect — резолвит DNS + устанавливает TCP-соединение + TLS-хендшейк. Экономия 100–500 мс. Дороже чем dns-prefetch, поэтому только для ресурсов, которые точно понадобятся на странице.

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

Атрибут crossorigin нужен для ресурсов, которые запрашиваются с CORS (шрифты, скрипты с другого домена).

preload — загружает ресурс с высоким приоритетом до того, как браузер обнаружил его в DOM. Критично для LCP-изображения, основного шрифта, критичного CSS.

<!-- LCP-изображение -->
<link rel="preload" href="/hero-image.webp" as="image" fetchpriority="high">

<!-- Шрифт -->
<link rel="preload" href="/fonts/Inter-Regular.woff2" as="font" type="font/woff2" crossorigin>

<!-- Критичный JS-чанк -->
<link rel="preload" href="/assets/main.js" as="script">

Атрибут as обязателен — без него браузер загружает ресурс с низким приоритетом и без кеширования по типу.

prefetch — загружает ресурс с низким приоритетом для использования на следующей странице. Браузер делает это только в простое.

<!-- Следующая страница, на которую, вероятно, перейдёт пользователь -->
<link rel="prefetch" href="/checkout">
<link rel="prefetch" href="/assets/checkout-chunk.js" as="script">

Что и когда использовать

Директива Когда Домен Ресурс
dns-prefetch Сторонние домены, не 100% нужные Любой сторонний
preconnect Сторонние домены, точно нужные Любой сторонний
preload Критичные ресурсы текущей страницы Любой LCP-img, шрифты, critical CSS
prefetch Ресурсы следующей страницы Любой JS-чанки, HTML, данные

Реализация в Laravel (серверная сторона)

// app/Http/Middleware/ResourceHints.php
class ResourceHints
{
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);

        $hints = [
            '<https://fonts.googleapis.com>; rel=preconnect',
            '<https://fonts.gstatic.com>; rel=preconnect; crossorigin',
            '</fonts/Inter-Regular.woff2>; rel=preload; as=font; type="font/woff2"; crossorigin',
        ];

        // Для страниц каталога — prefetch страницы продукта
        if ($request->routeIs('catalog.*')) {
            $hints[] = '</assets/product-page-chunk.js>; rel=prefetch; as=script';
        }

        $response->headers->set(
            'Link',
            implode(', ', $hints)
        );

        return $response;
    }
}

HTTP-заголовок Link работает так же, как тег <link> в HTML, но браузер получает его раньше — до начала парсинга HTML.

Реализация в React/Next.js

В Next.js используем компонент <Head>:

import Head from 'next/head';

export default function ProductPage({ product }) {
  return (
    <>
      <Head>
        {/* Preconnect к API и CDN */}
        <link rel="preconnect" href="https://cdn.example.com" />
        <link rel="dns-prefetch" href="//analytics.example.com" />

        {/* Preload LCP-изображения */}
        {product.heroImage && (
          <link
            rel="preload"
            href={product.heroImage}
            as="image"
            fetchpriority="high"
          />
        )}
      </Head>
      {/* ... */}
    </>
  );
}

Для динамического preload на основе данных:

// Компонент определяет, что будет LCP-элементом
function HeroImage({ src, alt }) {
  return (
    <>
      <Head>
        <link rel="preload" href={src} as="image" fetchpriority="high" />
      </Head>
      <img src={src} alt={alt} loading="eager" fetchpriority="high" />
    </>
  );
}

Preload для Google Fonts без flash of unstyled text

<!-- 1. Preconnect -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<!-- 2. Загружаем CSS шрифта асинхронно -->
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap">
</noscript>

Или хостим шрифты самостоятельно — лучше и для performance, и для GDPR:

<link rel="preload" href="/fonts/inter-400.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/inter-600.woff2" as="font" type="font/woff2" crossorigin>

Автоматический prefetch на основе поведения пользователя

Умный prefetch: предзагружаем ресурсы при hover на ссылку, а не заранее для всей страницы.

// Prefetch при наведении с задержкой 100ms
const prefetchCache = new Set();

document.addEventListener('mouseover', (e) => {
  const link = e.target.closest('a[href]');
  if (!link || prefetchCache.has(link.href)) return;

  // Только внутренние ссылки
  if (link.origin !== location.origin) return;

  const timeout = setTimeout(() => {
    const prefetch = document.createElement('link');
    prefetch.rel = 'prefetch';
    prefetch.href = link.href;
    document.head.appendChild(prefetch);
    prefetchCache.add(link.href);
  }, 100);

  link.addEventListener('mouseleave', () => clearTimeout(timeout), { once: true });
});

Библиотека quicklink делает это системно с учётом Network Information API:

import quicklink from 'quicklink';

// Prefetch всех видимых ссылок в зоне видимости
quicklink.listen({
  ignores: [
    /\/logout/,
    /\/admin/,
    (url) => url.includes('?'),
  ],
});

Частые ошибки

Preload без использования — браузер предупреждает в консоли (The resource ... was preloaded using link preload but not used within a few seconds). Preload-ресурс должен быть использован на той же странице.

Слишком много preconnect — больше 6 preconnect-директив начинают мешать основным запросам. Выбираем только реально критичные домены.

Preload шрифтов без crossorigin — шрифт загрузится дважды: один раз по preload, второй раз при реальном запросе.

dns-prefetch и preconnect для одного домена — это избыточно. preconnect включает в себя DNS resolution.

Сроки

Аудит текущих resource hints и внедрение базового набора (preconnect для сторонних доменов, preload для LCP-изображения и шрифтов) — 4–8 часов. Реализация динамических подсказок через HTTP-заголовки на серверной стороне + умный prefetch на основе навигации — 1–3 рабочих дня.