Что могут спросить на фронтенд собеседовании?

2 месяца назад·2 мин. на чтение

Рассмотрим вопросы, которые вполне могут спросить на фронтенд-собеседовании.

Чтобы пройти успешно собеседование, необходимо быть готовым ответить на ряд сложных вопросов, которые помогут оценить ваш уровень знаний и опыта. В этой статье мы рассмотрим несколько интересных и полезных вопросов, которые могут быть заданы на собеседовании.

1. Объясните различия между JavaScript и TypeScript.

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

2. Расскажите о различных подходах к организации кода в JavaScript.

В JavaScript существуют различные методологии и паттерны для организации кода, такие как модульный подход, паттерн MVP (Model-View-Presenter), паттерн MVVM (Model-View-ViewModel) и другие. Каждый из них имеет свои преимущества и недостатки, и правильный выбор зависит от конкретной задачи и проекта.

3. Что такое Event Loop в JavaScript?

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

4. Какие инструменты и технологии вы использовали для оптимизации производительности веб-приложений?

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

5. Расскажите о своем опыте работы с адаптивным и отзывчивым дизайном.

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

6. Какой метод можно использовать для передачи данных между компонентами в React?

В React можно использовать различные методы для передачи данных между компонентами, такие как прокидывание props сверху вниз, использование контекста и Redux для управления состоянием приложения. Фронтенд разработчик должен иметь хорошее понимание этих методов и уметь выбрать правильный подход в зависимости от конкретной ситуации. На собеседовании могут быть заданы вопросы, направленные на оценку вашего понимания и применения этих знаний. Подготовка и самообразование в этих вопросах помогут уверенно пройти собеседование и достичь желаемой должности.

Что такое Батчинг в ReactJS

2 месяца назад·4 мин. на чтение

В данной статье мы рассмотрим понятие "батчинг" в ReactJS и посмотрим, как он может повысить производительность и улучшить пользовательский опыт веб-приложений.

React 18 включает в себя улучшения производительности «из коробки» путем использования более частых операций пакетной обработки по умолчанию, что устраняет необходимость вручную объединять обновления в коде приложения или библиотеки. Это функциональность, о которой большинству пользователей можно не думать. Однако она может быть актуальна для преподавателей и разработчиков библиотек.

Что такое пакетная обработка (batching)?

Пакетная обработка (batching) - это когда React группирует несколько обновлений состояния в одно перерисовку для повышения производительности. Например, если у вас есть два обновления состояния внутри одного события клика, React всегда собирает их в одну перерисовку. Если вы выполните следующий код, вы увидите, что каждый раз, когда вы кликаете, React выполняет только одну перерисовку, хотя вы устанавливаете состояние дважды:
function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    setCount(c => c + 1); // Пока не происходит повторное отображение
    setFlag(f => !f); // Пока не происходит повторное отображение
    // React перерисует только один раз в конце (это пакетная обработка!)
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
}
Это отлично для производительности, потому что это позволяет избежать ненужных повторных рендеров. Это также предотвращает отображение компонента в "незаконченном" состоянии, где была обновлена только одна переменная состояния, что может вызвать ошибки. Это может напомнить вам о том, как официант ресторана не бежит на кухню, когда вы выбираете первое блюдо, а ждет, пока вы закончите заказ. Однако, React не всегда одинаково объединял обновления. Например, если вам нужно загрузить данные, а затем обновить состояние в указанном выше handleClick, то React не будет объединять обновления и будет выполнять два независимых обновления. Это происходит потому, что React раньше выполнял пакетную обработку только во время события браузера (например, нажатия кнопки), а здесь мы обновляем состояние после обработки события (в callback-функции fetch):
function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    fetchSomething().then(() => {
      // React 17 и более ранние НЕ объединяют эти обновления, потому что
      // они запускаются ПОСЛЕ события в callback-функции, а не ВО ВРЕМЯ события
      setCount(c => c + 1); // Вызывает повторное отображение
      setFlag(f => !f); // Вызывает повторный рендеринг
    });
  }

  return (
   <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
}
До React 18 мы объединяли обновления только в обработчиках событий React. Обновления внутри Promise, setTimeout, нативных обработчиков событий или любых других событий по умолчанию не объединялись в React.

Что такое автоматическая пакетная обработка?

Начиная с React 18 с использованием createRoot, все обновления будут автоматически объединяться, независимо от их происхождения. Это означает, что обновления внутри таймеров, Promise, нативных обработчиков событий или любых других событий будут объединяться так же, как и обновления внутри событий React. Мы ожидаем, что это приведет к уменьшению работы по отрисовке и, следовательно, к лучшей производительности в ваших приложениях:
function App() {
  const [count, setCount] = useState(0);
  const [flag, setFlag] = useState(false);

  function handleClick() {
    fetchSomething().then(() => {
      // React 18 и позднее ОБЪЕДИНЯЕТ эти обновления:
      setCount(c => c + 1);
      setFlag(f => !f);
      // React перерисует только один раз в конце (это пакетная обработка!)
    });
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
    </div>
  );
}
Примечание: Ожидается, что вы начнете использовать createRoot вместе с переходом на React 18. React будет автоматически объединять обновления, независимо от того, где они происходят, так что это:
function handleClick() {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React перерисует только один раз в конце (это пакетная обработка!)
}
и равносильно этому:

setTimeout(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React перерисует только один раз в конце (это пакетная обработка!)
}, 1000);
и равносильно этому:

fetch(/*...*/).then(() => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React перерисует только один раз в конце (это пакетная обработка!)
})
и равносильно этому:

elm.addEventListener('click', () => {
  setCount(c => c + 1);
  setFlag(f => !f);
  // React перерисует только один раз в конце (это пакетная обработка!)
});
Примечание: React объединяет обновления только тогда, когда это обычно безопасно. Например, React гарантирует, что для каждого события, инициированного пользователем, такого как клик или нажатие клавиши, DOM полностью обновляется перед следующим событием. Это гарантирует, например, что форма, которая отключается при отправке, не может быть отправлена дважды.

Что, если я не хочу использовать пакетную обработку?

Обычно пакетная обработка безопасна, но некоторый код может зависеть от считывания чего-либо из DOM сразу после изменения состояния. Для таких случаев вы можете использовать ReactDOM.flushSync(), чтобы отключить пакетную обработку:
import { flushSync } from 'react-dom'; // Обратите внимание: react-dom, а не react

function handleClick() {
  flushSync(() => {
    setCounter(c => c + 1);
  });
  // React уже обновил DOM
  flushSync(() => {
    setFlag(f => !f);
  });
  // React уже обновил DOM
}
Подробнее в оригинальной статье на GitHub