Иван Акулов про разработку


Гео и язык канала: Россия, Русский
Категория: Технологии


JS · React · веб-перформанс · разработка и архитектура
Твитер: https://twitter.com/iamakulov
Помогу с производительностью: https://3perf.com
По всем вопросам (рекламу не продаю): @iamakulov
Чатик канала: @iamakulov_channel_chat


Гео и язык канала
Россия, Русский
Категория
Технологии
Статистика
Фильтр публикаций


4) Что с этим делать
— Если вы делаете приложение с нуля, не помещайте API на отдельный сервер ¯\_(ツ)_/¯

— Если у вас приложение уже запущено, перенесите API-сервер с, например,
api.my-app.com/*
на
my-app.com/api/*

Делать это во фронтенд-сервере часто неудобно — но зато это легко сделать на уровне CDN (инструкция для Cloudflare и CloudFront).

— Не обходите CORS ради перформанса, а то получится как у Zoom

***

(Также сообщаю, что до воркшопа по React-перформансу осталась неделя. Приходите, если ещё не!)


3) Кеши помогают, но слабо
— DNS resolution (из первого пункта) кешируются на уровне браузера, OS и даже вайфай-роутера. Кеш живёт так долго, как прикажет DNS-сервер — обычно это час или всего 5 минут
— TCP-соединения (тоже из первого пункта) браузер тоже держит открытыми — но всего несколько минут
— Preflight-запросы можно кешировать надолго, но это работает для каждого URL в отдельности

Кешами проблему не решить.


​​2) 2× при каждом запросе
Помните CORS? Каждый раз, когда запрос с одного домена идёт на другой домен, браузер ради безопасности проверяет, разрешен ли такой запрос.

Стандартный способ проверить «разрешён ли запрос» — это сделать preflight-запрос. Перед тем, как отправить настоящий запрос (например, GET api.my-app.com/users/me), браузер делает пробный OPTIONS-запрос (OPTIONS api.my-app.com/users/me) и смотрит, что приходит в ответ.

Такое происходит с любым API-запросом (за редким исключением). Результат — любой запрос на сервер теперь занимает в два раза больше времени ↓

Самое плохое — preflight-запрос нужен на каждый новый URL. То есть если вам для открытия приложения нужно загрузить /users/me, /settings/me и /memes/me, каждый из этих запросов будет в два раза медленнее.

2.9k 1 40 10 22

​​Любовь и ненависть к API-доменам
Когда я был просто фулстеком, мне нравилось разносить фронтенд и бекенд по разным доменам (например, my-app.com и api.my-app.com). Когда я стал заниматься перформансом, мне это резко разонравилось. Вот почему.

1) +600 мс при первой загрузке
Каждый раз, когда браузеру нужно загрузить что-то с нового домена, он тратит время на подключение к этому домену. Это относится и к запросам с my-app.com на api.my-app.com.

На обычной 4G-сети подключение к новому домену занимает аж 600 мс. Вот как это выглядит у приложения Typefully ↓

Если у вас нет сервер-сайд-рендеринга, это значит, что посетитель увидит данные на 600 мс позже. И это никак не обойти.

3.3k 2 77 12 33

Циферки: обучил уже 130 человек, 50 сказали «воркшоп превзошёл ожидания».

Ключевые слова: Chrome DevTools · React Profiler · why-did-you-render · useCallback/useMemo · Redux · useContext · requestAnimationFrame · useTransition (React 18) · Suspense · throttling/debouncing · Web Workers · CSS-in-JS · lazy hydration · update batching · isInputPending()

Приходите. $350 (билет «ранняя птичка»™) или $450 (как только по $350 закончатся). Снова на английском, да. https://smashingconf.com/online-workshops/workshops/ivan-akulov-july

4k 1 24 11 21

​​Ещё после каждого дня воркшопа у нас будет читлист для каждой проблемы — типа вот такого:


​​🧱 Следующий (восьмой!) поток воркшопа по React-перформансу пройдёт 28 июля — 11 августа у Smashing Magazine.

В воркшопе 10 часов, и все 10 часов мы будем работать с кодом. Выглядит это примерно так:

Берём медленное приложение → Разбираемся, почему тормозит → Чиним → Повторяем

Мы посмотрим на пять видов проблем в React-аппах, поймём, как их отличить, и продебажим и починим каждый кучу раз:


7) Ах, да, где почитать больше:

Suspense SSR Architecture in React 18 — огромный обзор всех новых фич Suspense: https://github.com/reactwg/react-18/discussions/37
Selective Hydration — что произойдёт, если кликнуть по негидрированной кнопке в середине гидрации: https://github.com/reactwg/react-18/discussions/130


6) Также спешу сообщить, что теперь в этом канале включены премиум-реакции

(Апд: теперь точно да)

3.7k 1 12 25 335

​​5) Окей, но если этот рендеринг такой полезный, почему он тогда не используется по умолчанию?

Я не знаю всех причин! Но, предполагаю, потому, что в целом такой рендер занимает большо времени. Например, в моём тестовом приложении гидрация с Suspense занимает в три раза дольше времени, чем без — видимо, потому, что React вынужден всё время отдавать контроль браузеру и забирать его обратно:


4) Это, кстати, тот же подход к рендерингу, который React 18 применяет, когда вы используете useTransition или useDeferredValue.

Благодаря такому рендерингу приложение остаётся интерактивным. Если пользователь нажмёт что-то на странице, страница отреагирует сразу же, не дожидаясь, пока рендер закончится.


​​3) Под капотом React использует API типа performance.now() и navigator.scheduling.isInputPending(), чтобы понять, сколько времени занимает рендер.

Если рендеринг продолжается дольше 5-50-300 мс, или если пользователь пытается что-то нажать/ввести в приложении, React приостанавливает рендеринг и отдаёт контроль браузеру. Вот как выглядит функция, которая решает это


​​2) В React 18 вызов ReactDOM.hydrate() по умолчанию всё ещё очень дорогой.

Но: если обернуть часть приложения в , React возьмёт все компоненты внутри — и вместо того, чтобы рендерить их в один подход, начнёт рендерить их пошагово, 5-10 мс за раз:


​​ в React 18

Мне очень нравится, как React проапгрейдил и hydration в 18-й версии. Смотрите:

1) В React 16-17 каждый вызов ReactDOM.hydrate() оказывается жутко дорогим.

Когда вы вызываете ReactDOM.hydrate(), React рендерит каждый компонент, который есть на странице. В сложных приложениях таких компонентов много, и вызов ReactDOM.hydrate() вполне может занять и секунду-две.

На всё время вызова страница зависает.


Как мониторить перформанс в React

Собрал гайд по тому, как настроить свой мониторинг React-перформанса — как с живыми пользователями, так и синтетический. Со всеми подводными камнями, про которые знаю: https://3perf.com/blog/react-monitoring/

Зачем это всё
Мой любимый ответ на «как сделать, что приложение оставалось быстрым» — это настроить мониторинг перформанса. Это, конечно, не решает все проблемы (дашборд с мониторингом ещё нужно смотреть, а увиденные проблемы — исправлять), но помогает.

Челленж в том, что готовых инструментов для React-перформанса нет. Для мониторинга скорости загрузки есть миллион сервисов (SpeedCurve, Treo, Lighthouse CI и иже с ними). А вот что, если важна не скорость загрузки, а скорость реакции кнопочек? Придётся настраивать что-то своё — про это и гайд.

(первая статья на 3perf.com за пару лет, да ✨)

6k 2 208 16 62

​​Воркшоп по React-перформансу 16-19 мая (на английском) 🏃

Я занимаюсь перформансом четыре года. Первый год я работал в основном наугад: тыкался в девтулзах, вспоминал случайно прочитанные лайфхаки, применял их, пока не сработает. Ко второму году у меня начала формироваться система. Третий и четвёртый год я тестировал и укреплял эту систему, применяя её на проектах и проводя закрытые воркшопы. Теперь я готов передать эту систему вам.

Что: 16, 17 и 19 мая (пн, вт и чт) я проведу трёхдневный англоязычный воркшоп про React-перформанс. Это воркшоп не про скорость загрузки, а про скорость работы приложения: про то, что делать, когда нажимаешь кнопку, а страница вместо мгновенной реакции зависает. Будет много Chrome DevTools и React Profiler.

Как выглядит: берём медленное приложение → разбираемся, почему оно медленное → чиним проблемы одну за другой. Повторяем, пока не посмотрим на каждый популярный перформанс-антипаттерн и не разберёмся, как его чинить.

Что внутри: ненужные и дорогие рендеры · цепочки ререндеров · антипаттерны редакса и контекста · что происходит в каждом кадре · layout thrashing · инициализация бандла и hydration · новые перф-фичи из React 18.

Чего нет внутри: нет оптимизации анимаций или памяти · нет работы с layers.

Для кого: для тех, кто хорошо знаком с базовыми оптимизациями вроде React.memo() и useMemo — но хочет лучше познакомиться с Chrome DevTools, React Profiler и дебаггингом перформанс-проблем. Если вы хорошо знакомы со штуками типа why-did-you-render и layout thrashing, вам, вероятно, будет скучно.

На английском · билеты от €299, позже — дороже · до 30 человек

Больше деталей и купить билет → https://fwdays.com/en/event/react-performance-workshop

5.8k 2 66 30 64

Содержимое скрыто


Правильный ответ — скачает React заново.
— С 2020-го во всех браузерах кеш каждого сайта хранится отдельно; это сделано для приватности
— А теперь (новости ⚡️) Chromium будет делить для каждого сайта не только HTTP-кеш, но и DNS-кеш, соединения, и прочее: https://twitter.com/cramforce/status/1490859573250387977

Что делать
— Если вы загружаете какие-то библиотеки со стороннего CDN-а, потому что «вдруг они уже будут закешированы у пользователя», то не нужно — это не работает. Устанавливайте их из npm и перемещайте в бандл
— Если вы используете Google Fonts, подключите Fontsource
— А если у вас iframe-ы со сторонними ресурсами, со свежими изменениями Chromium вам жопа: «experiment [...] slows cross-site iframe time to first contentful paint by about 5%» (пост)

8.8k 3 94 53 43

Что сделает site-b.com?
Опрос
  •   возьмёт React из кеша
  •   скачает React заново
  •   сломается, это же JS
1386 голосов

6.3k 1 32 20 23

Есть site-a.com и site-b.com. На обоих есть тег



Вы заходите сначала на site-a.com, а потом сразу же на site-b.com.

Показано 20 последних публикаций.