← Назад к вопросам

Как оптимизировать приложение в контексте JS?

1.6 Junior🔥 121 комментариев
#Оптимизация и производительность

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

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

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

Оптимизация JavaScript приложений

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

1. Code Splitting и Lazy Loading

Делите код на части и загружайте их по требованию:

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

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

const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));

const routes = [
  { path: '/dashboard', element: <Dashboard /> },
  { path: '/settings', element: <Settings /> }
];

Это уменьшает первоначальный размер бандла и улучшает время загрузки.

2. Минимизация и Bundling

Используйте современные бандлеры с оптимизацией:

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  mode: 'production',
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin()]
  }
};

3. Мемоизация и избежание ненужных re-renders

const UserProfile = React.memo(({ userId }) => {
  return <div>User: {userId}</div>;
}, (prevProps, nextProps) => prevProps.userId === nextProps.userId);

function ExpensiveComponent({ data }) {
  const sortedData = useMemo(() => {
    return data.sort((a, b) => a.value - b.value);
  }, [data]);

  return <ul>{sortedData.map(item => <li key={item.id}>{item.name}</li>)}</ul>;
}

function Form({ onSubmit }) {
  const handleSubmit = useCallback((e) => {
    e.preventDefault();
    onSubmit(formData);
  }, []);

  return <form onSubmit={handleSubmit}>...</form>;
}

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

Перемещайте тяжелые операции в отдельный поток:

self.onmessage = (e) => {
  const largeArray = e.data;
  const result = largeArray
    .map(x => x * 2)
    .filter(x => x > 100)
    .reduce((sum, x) => sum + x, 0);
  
  self.postMessage(result);
};

function HeavyCalculation({ data }) {
  const [result, setResult] = useState(null);

  useEffect(() => {
    const worker = new Worker('/worker.js');
    worker.postMessage(data);
    worker.onmessage = (e) => {
      setResult(e.data);
      worker.terminate();
    };
  }, [data]);

  return <div>Result: {result}</div>;
}

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

for (let i = 0; i < 100; i++) {
  element.style.width = i + 'px';
}

const styles = Array.from({ length: 100 }, (_, i) => i);
element.style.cssText = styles.map(i => `width: ${i}px;`).join(';');

function optimizedUpdate() {
  requestAnimationFrame(() => {
    div1.textContent = 'Updated 1';
    div2.style.color = 'red';
    div3.classList.add('active');
  });
}

6. Virtual Scrolling для длинных списков

import { FixedSizeList } from 'react-window';

function LargeList({ items }) {
  return (
    <FixedSizeList
      height={600}
      itemCount={items.length}
      itemSize={35}
      width='100%'
    >
      {({ index, style }) => (
        <div style={style} key={items[index].id}>
          {items[index].name}
        </div>
      )}
    </FixedSizeList>
  );
}

7. Кэширование и Service Workers

self.addEventListener('install', (e) => {
  e.waitUntil(
    caches.open('v1').then((cache) => {
      return cache.addAll(['/index.html', '/styles.css', '/app.js']);
    })
  );
});

self.addEventListener('fetch', (e) => {
  e.respondWith(
    caches.match(e.request).then((response) => {
      return response || fetch(e.request);
    })
  );
});

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

performance.mark('operation-start');
const result = expensiveOperation();
performance.mark('operation-end');
performance.measure('operation', 'operation-start', 'operation-end');

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

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

getLCP(metric => console.log('LCP:', metric.value));
getFID(metric => console.log('FID:', metric.value));

Ключевые метрики

  • FCP (First Contentful Paint) < 1.8s
  • LCP (Largest Contentful Paint) < 2.5s
  • FID (First Input Delay) < 100ms
  • CLS (Cumulative Layout Shift) < 0.1
  • TTFB (Time to First Byte) < 600ms

Чеклист оптимизации

  • Code splitting по роутам
  • Tree shaking неиспользуемого кода
  • Минимизация бандла
  • Мемоизация компонентов
  • Виртуальная прокрутка для списков
  • Кэширование ответов API
  • Мониторинг Core Web Vitals
Как оптимизировать приложение в контексте JS? | PrepBro