\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n```\n\n## 2. Различия между async и defer\n\nЭто критически важно для производительности.\n\n```javascript\n// async - загружается параллельно, выполняется как только готов\n// Используй для независимых скриптов (аналитика, трекинг)\n\n\n// defer - загружается параллельно, выполняется после DOM parsing\n// Используй для основного кода приложения\n\n\n// Порядок выполнения важен\n\n\n// app-uses-library.js выполнится после library.js\n```\n\nВизуально:\n\n```\nasync: |--fetch--|\n |execute|\n\ndefer: |----fetch----|\n |parse DOM|execute|\n\nsync: |--fetch--|\n |execute|\n (блокирует parsing)\n```\n\n## 3. Динамическая загрузка скриптов (в JavaScript)\n\n```javascript\n// Функция для динамической загрузки скрипта\nfunction loadScript(src, async = true, defer = true) {\n const script = document.createElement('script');\n script.src = src;\n script.async = async;\n script.defer = defer;\n \n return new Promise((resolve, reject) => {\n script.onload = resolve;\n script.onerror = reject;\n document.body.appendChild(script);\n });\n}\n\n// Используем\nawait loadScript('script1.js');\nawait loadScript('script2.js');\n\n// Или параллельно\nPromise.all([\n loadScript('script1.js'),\n loadScript('script2.js')\n]);\n```\n\n## 4. Code Splitting в современных бандлерах\n\nWebpack, Vite, Next.js позволяют автоматически разбивать код.\n\n```javascript\n// React с Dynamic Import (Lazy Loading)\nimport { lazy, Suspense } from 'react';\n\nconst HeavyComponent = lazy(() => import('./HeavyComponent'));\n\nfunction App() {\n return (\n Loading...
}>\n \n \n );\n}\n\n// Route-based code splitting в Next.js\n// автоматически создает отдельный bundle для каждой страницы\n// pages/home.tsx\n// pages/about.tsx\n```\n\n## 5. Preload и Prefetch для ресурсов\n\n```html\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n```\n\n## 6. Service Worker для контроля кэширования\n\n```javascript\n// service-worker.js\nself.addEventListener('install', (event) => {\n event.waitUntil(\n caches.open('v1').then((cache) => {\n return cache.addAll([\n '/',\n '/css/style.css',\n '/js/app.js'\n ]);\n })\n );\n});\n\nself.addEventListener('fetch', (event) => {\n event.respondWith(\n // Сначала проверяем кэш\n caches.match(event.request).then((response) => {\n return response || fetch(event.request);\n })\n );\n});\n```\n\n## 7. Network Priority Hints\n\nСовременные браузеры поддерживают priority hints.\n\n```html\n\n\n\n\n\"Description\"\n\n\n\"Description\"\n```\n\n## 8. React/Next.js специфичные оптимизации\n\n```javascript\n// next/image - автоматически оптимизирует изображения\nimport Image from 'next/image';\n\n\"Photo\"\n/\n\n// next/script - контроль загрузки скриптов\nimport Script from 'next/script';\n\n\n \n \n \n\n\n```\n\nПравильное управление порядком загрузки ресурсов — это ключ к высокой производительности приложения. Начинаю всегда с профилирования, определяю критичные пути и оптимизирую их.\n","dateCreated":"2026-04-03T11:43:45.554311","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Как можно повлиять на порядок загрузки ресурсов?

2.0 Middle🔥 121 комментариев
#Браузер и сетевые технологии

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Влияние на порядок загрузки ресурсов

Один из важных аспектов оптимизации производительности frontend приложения. Правильный порядок загрузки ресурсов может значительно улучшить Core Web Vitals и пользовательский опыт.

1. HTML атрибуты в тегах script и link

Самый базовый способ — использование специальных атрибутов.

<!-- Синхронная загрузка (блокирует parsing) -->
<script src="script.js"></script>

<!-- Асинхронная загрузка (не блокирует parsing) -->
<script src="script.js" async></script>

<!-- Отложенная загрузка (выполнится после parsing) -->
<script src="script.js" defer></script>

<!-- Для stylesheets: preload (загружает с высоким приоритетом) -->
<link rel="preload" href="style.css" as="style">

<!-- Загрузка font с preload -->
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>

<!-- Prefetch (загружает в background при наличии bandwidth) -->
<link rel="prefetch" href="future-page.js">

<!-- DNS-prefetch (подготавливает DNS lookup) -->
<link rel="dns-prefetch" href="//api.example.com">

<!-- Preconnect (устанавливает соединение заранее) -->
<link rel="preconnect" href="//cdn.example.com" crossorigin>

2. Различия между async и defer

Это критически важно для производительности.

// async - загружается параллельно, выполняется как только готов
// Используй для независимых скриптов (аналитика, трекинг)
<script src="analytics.js" async></script>

// defer - загружается параллельно, выполняется после DOM parsing
// Используй для основного кода приложения
<script src="app.js" defer></script>

// Порядок выполнения важен
<script src="library.js" defer></script>
<script src="app-uses-library.js" defer></script>
// app-uses-library.js выполнится после library.js

Визуально:

async:   |--fetch--|
         |execute|

defer:   |----fetch----|
         |parse DOM|execute|

sync:    |--fetch--|
         |execute|
         (блокирует parsing)

3. Динамическая загрузка скриптов (в JavaScript)

// Функция для динамической загрузки скрипта
function loadScript(src, async = true, defer = true) {
  const script = document.createElement('script');
  script.src = src;
  script.async = async;
  script.defer = defer;
  
  return new Promise((resolve, reject) => {
    script.onload = resolve;
    script.onerror = reject;
    document.body.appendChild(script);
  });
}

// Используем
await loadScript('script1.js');
await loadScript('script2.js');

// Или параллельно
Promise.all([
  loadScript('script1.js'),
  loadScript('script2.js')
]);

4. Code Splitting в современных бандлерах

Webpack, Vite, Next.js позволяют автоматически разбивать код.

// React с Dynamic Import (Lazy Loading)
import { lazy, Suspense } from 'react';

const HeavyComponent = lazy(() => import('./HeavyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <HeavyComponent />
    </Suspense>
  );
}

// Route-based code splitting в Next.js
// автоматически создает отдельный bundle для каждой страницы
// pages/home.tsx
// pages/about.tsx

5. Preload и Prefetch для ресурсов

<!-- Preload - для ресурсов, нужных на текущей странице -->
<link rel="preload" href="main.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="hero-image.jpg" as="image">

<!-- Prefetch - для ресурсов, вероятно нужных в будущем -->
<!-- Браузер загружает в фоне, если есть пропускная способность -->
<link rel="prefetch" href="about.js">
<link rel="prefetch" href="next-page.html">

<!-- DNS-prefetch - для доменов API или CDN -->
<link rel="dns-prefetch" href="//api.example.com">

<!-- Preconnect - установить соединение (DNS + TLS + TCP) -->
<link rel="preconnect" href="//fonts.googleapis.com" crossorigin>

6. Service Worker для контроля кэширования

// service-worker.js
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open('v1').then((cache) => {
      return cache.addAll([
        '/',
        '/css/style.css',
        '/js/app.js'
      ]);
    })
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    // Сначала проверяем кэш
    caches.match(event.request).then((response) => {
      return response || fetch(event.request);
    })
  );
});

7. Network Priority Hints

Современные браузеры поддерживают priority hints.

<!-- High priority для критических ресурсов -->
<link rel="preload" href="critical.js" as="script">

<!-- Low priority для некритичных ресурсов -->
<img loading="lazy" src="image.jpg" alt="Description">

<!-- Importance attribute (экспериментально) -->
<img src="below-fold-image.jpg" importance="low" alt="Description">

8. React/Next.js специфичные оптимизации

// next/image - автоматически оптимизирует изображения
import Image from 'next/image';

<Image 
  src="/photo.jpg"
  width={800}
  height={600}
  priority // загружается с высоким приоритетом
  alt="Photo"
/>

// next/script - контроль загрузки скриптов
import Script from 'next/script';

<Script 
  src="https://cdn.jsdelivr.net/analytics.js"
  strategy="afterInteractive" // после interactive события
/>

// Другие стратегии:
// - "beforeInteractive" - загружается до интерактивности
// - "afterInteractive" (default) - после интерактивности
// - "lazyOnload" - в idle время

9. Webpack конфигурация для контроля порядка

// webpack.config.js
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\/]node_modules[\/]/,
          name: 'vendors',
          priority: 10
        },
        common: {
          minChunks: 2,
          priority: 5,
          reuseExistingChunk: true
        }
      }
    }
  }
};

10. Контроль порядка загрузки в браузере

Все основные способы:

// 1. requestIdleCallback - загрузить в idle время
requestIdleCallback(() => {
  loadScript('non-critical.js');
});

// 2. requestAnimationFrame - выполнить перед перерисовкой
requestAnimationFrame(() => {
  initNonCriticalUI();
});

// 3. setTimeout с нулевой задержкой
setTimeout(() => {
  initAnalytics();
}, 0);

// 4. Intersection Observer для lazy loading
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      loadComponentData(entry.target);
      observer.unobserve(entry.target);
    }
  });
});

document.querySelectorAll('.lazy-component').forEach((el) => {
  observer.observe(el);
});

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

  1. Критические ресурсы - preload (шрифты, главные скрипты)
  2. Некритичные скрипты - async или defer
  3. Изображения below-the-fold - lazy load
  4. API запросы - prefetch или preconnect к доменам
  5. Code splitting - разбивать большие bundles
  6. Сервис воркеры - кэшировать статичные ресурсы

Инструменты для анализа

// Chrome DevTools Performance Tab
// Lighthouse
// WebPageTest
// GTmetrix

// Программно проверить загрузку
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log('Resource:', entry.name);
    console.log('Duration:', entry.duration);
    console.log('Size:', entry.transferSize);
  }
});

observer.observe({ entryTypes: ['resource'] });

Реальный пример оптимизированной HTML

<!DOCTYPE html>
<html>
<head>
  <!-- Критические шрифты с preload -->
  <link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
  
  <!-- DNS-prefetch для API -->
  <link rel="dns-prefetch" href="//api.example.com">
  <link rel="preconnect" href="//cdn.example.com" crossorigin>
  
  <!-- Инлайн критический CSS -->
  <style>
    /* критические стили для выше fold контента */
  </style>
  
  <!-- Остальной CSS -->
  <link rel="stylesheet" href="/css/style.css">
</head>
<body>
  <div id="root"></div>
  
  <!-- Дефер скрипт для основного приложения -->
  <script src="/js/main.js" defer></script>
  
  <!-- Асинхронный скрипт для аналитики -->
  <script src="/js/analytics.js" async></script>
</body>
</html>

Правильное управление порядком загрузки ресурсов — это ключ к высокой производительности приложения. Начинаю всегда с профилирования, определяю критичные пути и оптимизирую их.