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

Делает ли JavaScript перерендер всей страницы

1.8 Middle🔥 191 комментариев
#JavaScript Core#Браузер и сетевые технологии

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

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

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

Перерендер страницы в JavaScript / React

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

Чистый JavaScript (Vanilla JS)

При обновлении DOM чистым JavaScript браузер не перерендеривает всю страницу:

// Обновление одного элемента
const element = document.getElementById('counter');
element.textContent = '42';
// Браузер перерисовует только этот элемент (reflow + repaint)
// Остальная страница не затрагивается

Процесс:

  1. JavaScript обновляет DOM
  2. Браузер вычисляет измененные элементы (Reflow/Layout)
  3. Браузер перерисовывает только измененные части (Repaint)
  4. Композитинг (Compositing) - финальная комбинация слоев

Это называется Incremental rendering - браузер обновляет только то, что изменилось.

React

В React ситуация сложнее. React использует Virtual DOM и reconciliation алгоритм:

// Компонент
function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <h1>Счетчик: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Увеличить</button>
    </div>
  );
}

// Когда кликнешь на кнопку:
// 1. setState вызывает rerender компонента
// 2. React пересоздает Virtual DOM
// 3. React сравнивает старый VirtualDOM с новым (Diffing)
// 4. React обновляет только измененные части в реальном DOM

Ключевой момент: React НЕ перерендеривает всю страницу, только компоненты, которые изменились.

Детали процесса перерендера

Шаг 1: State изменяется

setCount(count + 1); // Новое состояние

Шаг 2: React запускает перерендер компонента

// Функция компонента вызывается заново
// Это создает новое Virtual DOM дерево
const vdom = (
  <div>
    <h1>Счетчик: {count}</h1> {/* count = 1 */}
    <button>Увеличить</button>
  </div>
);

Шаг 3: Diffing (сравнение)

// Старый VirtualDOM:
<div>
  <h1>Счетчик: 0</h1>
  <button>Увеличить</button>
</div>

// Новый VirtualDOM:
<div>
  <h1>Счетчик: 1</h1> // <- ИЗМЕНИЛОСЬ
  <button>Увеличить</button>
</div>

// React видит: только текст <h1> изменился

Шаг 4: Обновление реального DOM

// React обновляет только нужный элемент
document.querySelector('h1').textContent = 'Счетчик: 1';

// Остальное не трогается

Когда React перерендеривает компоненты

Перерендер происходит, когда:

  1. Props изменились
function Child({ text }) {
  return <div>{text}</div>;
}

// Если text изменится - переренлер
<Child text="new" />
  1. State изменился
const [value, setValue] = useState(0);
setValue(value + 1); // перерендер
  1. Parent перерендеривается
function Parent() {
  const [count, setCount] = useState(0);
  
  return (
    <>
      <button onClick={() => setCount(count + 1)}>+</button>
      <Child /> {/* Child тоже перерендеривается! */}
    </>
  );
}

Проблема: Ненужные переренлеры

Ситуация: Child перерендеривается, даже если его props не изменились

function Parent() {
  const [count, setCount] = useState(0);
  
  return (
    <>
      <button onClick={() => setCount(count + 1)}>+</button>
      <Child text="Hello" /> {/* Перерендеривается каждый раз! */}
    </>
  );
}

Решение 1: React.memo

const Child = React.memo(({ text }) => {
  console.log('Child render');
  return <div>{text}</div>;
});

// Теперь Child не перерендеривается, если props не изменились

Решение 2: useCallback для функций

function Parent() {
  const [count, setCount] = useState(0);
  
  const handleClick = useCallback(() => {
    console.log('Clicked');
  }, []); // зависимости
  
  return (
    <>
      <button onClick={() => setCount(count + 1)}>+</button>
      <Child onClick={handleClick} />
    </>
  );
}

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

React DevTools Profiler

// Покажет:
// - Какие компоненты перерендеривались
// - Сколько это заняло времени
// - Почему произошел перерендер (props/state изменения)

console.log для отслеживания

function MyComponent() {
  console.log('MyComponent rendered'); // Видно в консоли каждый раз
  return <div>Content</div>;
}

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

  1. Не все переренлеры плохие - большинство браузеров справляются хорошо
  2. Оптимизируй только если есть проблемы - используй DevTools Profiler
  3. Группируй state обновления - батчинг (React 18+)
  4. Используй React.memo и useCallback осторожно - они тоже имеют стоимость
  5. Проверяй dependencies в useEffect - может вызвать лишние обновления

Батчинг в React 18+

function handleClick() {
  setCount(prev => prev + 1); // state update 1
  setName('John');              // state update 2
  
  // React 18 делает ONE перерендер для обоих обновлений
  // А не два отдельных перерендера
}

Заключение

На вопрос "Делает ли JavaScript перерендер всей страницы":

  • Чистый JS: Нет, браузер обновляет только измененные элементы
  • React: Нет, React обновляет только компоненты с измененными props/state
  • Важно: Понимать, почему происходят переренлеры, и оптимизировать только при необходимости

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