\n\n```\n\n## 10. Инструменты для анализа\n\n```bash\n# Анализ размера bundle\nnpm install --save-dev webpack-bundle-analyzer\n\n# Проверка производительности\nspeed insights url\n\n# Lighthouse CI\nnpm install --save-dev @lhci/cli@latest\nlhci autorun\n```\n\nОптимизация скриптов - это не одноразовое действие, а постоянный процесс мониторинга, анализа и улучшения производительности приложения.","dateCreated":"2026-04-03T17:51:57.670881","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Как оптимизировать скрипты?

2.0 Middle🔥 171 комментариев
#Оптимизация и производительность

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

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

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

Оптимизация скриптов в браузере

Оптимизация JavaScript скриптов критична для производительности веб-приложений. Это включает минимизацию размера кода, уменьшение времени выполнения и оптимизацию работы с памятью.

1. Минификация и Code Splitting

Минификация удаляет ненужные символы без изменения функциональности:

// До минификации
function calculateTotal(items) {
  let total = 0;
  for (let i = 0; i < items.length; i++) {
    total += items[i].price * items[i].quantity;
  }
  return total;
}

// После минификации (Terser/UglifyJS)
// function calculateTotal(a){let b=0;for(let c=0;c<a.length;c++)b+=a[c].price*a[c].quantity;return b}

// Code splitting - динамический импорт
const Dashboard = lazy(() => import('./Dashboard.js'));
const Analytics = lazy(() => import('./Analytics.js'));

2. Ленивая загрузка (Lazy Loading)

Загружайте скрипты и компоненты только при необходимости:

// Динамический импорт при клике
document.querySelector('#load-btn').addEventListener('click', async () => {
  const module = await import('./heavy-module.js');
  module.initialize();
});

// React Suspense для ленивой загрузки компонентов
import { lazy, Suspense } from 'react';

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

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

// Vue 3 - асинхронные компоненты
import { defineAsyncComponent } from 'vue';

const HeavyComponent = defineAsyncComponent(() =>
  import('./Heavy.vue')
);

3. Кеширование в памяти (Memoization)

Храните результаты дорогостоящих вычислений:

// Простое кеширование
const cache = new Map();

function expensiveCalculation(n) {
  if (cache.has(n)) return cache.get(n);
  const result = fibonacci(n);
  cache.set(n, result);
  return result;
}

// React useMemo
import { useMemo } from 'react';

function Component({ data }) {
  const sortedData = useMemo(() => {
    console.log('Sorting...');
    return data.sort((a, b) => a - b);
  }, [data]);

  return <div>{sortedData}</div>;
}

// Vue computed (автоматически кешируется)
import { computed } from 'vue';

const sortedData = computed(() => {
  return props.data.sort((a, b) => a - b);
});

4. Оптимизация DOM манипуляций

Минимизируйте обращения к DOM, используйте батчинг:

// ❌ Плохо - множество переголосовок DOM
for (let i = 0; i < 1000; i++) {
  const element = document.createElement('div');
  element.textContent = `Item ${i}`;
  document.body.appendChild(element);
  // После каждого appendChild происходит reflow/repaint
}

// ✅ Хорошо - батчинг обновлений
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
  const element = document.createElement('div');
  element.textContent = `Item ${i}`;
  fragment.appendChild(element);
}
document.body.appendChild(fragment);
// Один reflow/repaint

// ✅또는использовать requestAnimationFrame
let batch = [];
function scheduleUpdate(element) {
  batch.push(element);
  if (batch.length === 1) {
    requestAnimationFrame(() => {
      batch.forEach(el => document.body.appendChild(el));
      batch = [];
    });
  }
}

5. Уменьшение размера Bundle'а

// vite.config.js
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'vendor': ['vue', 'vue-router', 'pinia'],
          'utils': ['lodash-es', 'date-fns']
        }
      }
    },
    minify: 'terser',
    terserOptions: {
      compress: {
        drop_console: true, // Удалить console.log из production
        pure_funcs: ['console.log', 'console.info']
      }
    }
  }
};

// Избегайте импорта целых библиотек
// ❌ import _ from 'lodash';
// ✅ import debounce from 'lodash-es/debounce';

// Используйте tree-shaking
// package.json
{
  "sideEffects": false
}

6. Оптимизация асинхронных операций

// Дебаунс для API запросов
function debounce(fn, delay) {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn(...args), delay);
  };
}

const debouncedSearch = debounce(async (query) => {
  const results = await fetch(`/api/search?q=${query}`);
}, 300);

// Параллельные запросы с Promise.all
async function fetchUserData(userId) {
  const [user, posts, comments] = await Promise.all([
    fetch(`/api/users/${userId}`).then(r => r.json()),
    fetch(`/api/posts?userId=${userId}`).then(r => r.json()),
    fetch(`/api/comments?userId=${userId}`).then(r => r.json())
  ]);
  return { user, posts, comments };
}

// Ограничение параллельных запросов
function promisePool(tasks, poolSize) {
  const results = [];
  let inProgress = 0;
  
  return new Promise((resolve) => {
    async function process() {
      while (tasks.length > 0) {
        if (inProgress >= poolSize) {
          await new Promise(r => setTimeout(r, 10));
          continue;
        }
        inProgress++;
        const task = tasks.shift();
        task().then(result => {
          results.push(result);
          inProgress--;
        });
      }
      if (inProgress === 0) resolve(results);
    }
    process();
  });
}

7. Web Workers для тяжёлых вычислений

// main.js
const worker = new Worker('worker.js');

worker.postMessage({ data: largeArray });
worker.onmessage = (e) => {
  console.log('Result from worker:', e.data);
};

// worker.js
self.onmessage = (e) => {
  const result = performHeavyCalculation(e.data);
  self.postMessage(result);
};

function performHeavyCalculation(data) {
  // Тяжёлые вычисления без блокировки main thread
  return data.reduce((acc, val) => acc + val, 0);
}

8. Профилирование и мониторинг

// Performance API
performance.mark('start');
expensiveOperation();
performance.mark('end');
performance.measure('operation', 'start', 'end');

const measure = performance.getEntriesByName('operation')[0];
console.log(`Operation took ${measure.duration}ms`);

// Web Vitals
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';

getLCP(console.log);  // Largest Contentful Paint
getFID(console.log);  // First Input Delay
getCLS(console.log);  // Cumulative Layout Shift

// Анализ памяти
if (performance.memory) {
  console.log('Used JS heap:', performance.memory.usedJSHeapSize);
  console.log('Total JS heap:', performance.memory.totalJSHeapSize);
}

9. Оптимизация критического пути рендеринга

<!-- Минимизировать blocking ресурсы -->
<head>
  <!-- Критические стили inline -->
  <style>body { margin: 0; }</style>
  
  <!-- Отложить некритические стили -->
  <link rel="stylesheet" href="style.css" media="print" onload="this.media='all'">
  
  <!-- Отложить скрипты -->
  <script src="app.js" defer></script>
</head>

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

# Анализ размера bundle
npm install --save-dev webpack-bundle-analyzer

# Проверка производительности
speed insights url

# Lighthouse CI
npm install --save-dev @lhci/cli@latest
lhci autorun

Оптимизация скриптов - это не одноразовое действие, а постоянный процесс мониторинга, анализа и улучшения производительности приложения.