Што оптымізуе компіляр React і шта застаёцца на вашай адпаведнасці
З’ясавайце, які аспекты працэйнасупрацоўкі автаматызуе React Compiler, чаму спадзялыя API і важкія пакеты застаюцца вашай адпаведнасцю, і як безпечна ўжываць яго ў уже існуючай базе коду React.
Кампайляр React абсалютна большая частка ручнай мемаізацыі, што стварае прагненне спрытваць яго як рашэння проблемы медленных дапрацоўкаў. Аднак гэта не так: ён оптымізуе толькі процес атрыбутавання, які контролюеўць React, і нічога больш. Чырвоным паказана, дзе знаходзіцца гэтыя межы, якія спамеджэнняя ўсё ж трэбуе рашэнняі інжынера, а таксама як увядзіць кампайляр у існуючы код без настання проблем.
Ад спісу пунктав для мемаізацыі да автаматычнай мемаізацыі
Дзялёгі час саветы па падвышэнню карыстоўнасці React складаліся з короткага спісу інструментоў:
useMemo()
useCallback()
React.memo()
Компонент ператрыбутаваўся занадта часта, таму яго загарнулі. Вычысленне вярцалася даскладным, таму яго збераглі ў кэшы. Калебак выканаўся ў дзецячы компонент, таму яго стабілізавалі. Кожна з гэтых мераў была ручной мемаізацыяй, для якой трэбавалася арыйка залежнасцей.
Кампайляр React зменяе гэты стандарт. Версія 1.0 адзначаецца як стабільная, і рэкамендацыяя команды React для новага коду — дазволіць кампайляру здзейсніць мемаізацыю, у замест на ручныя викорыстанні useMemo і useCallback. Пераканаўцеся ў актуальных документах React, каб атрымаць найновейшыя прадактыкі ўжывання.
Суть можна выразыць ў адной фразе: кампайляр можа зробіць роботу самога React эфектывней, але ён не мае вплыву на роботу, якая адбываецца за межамі React.
Што на самай працэ кампайляр
У час будовы кампайляр аналізуе компаненты і хукі і дагаўляе мемаізацыю там, дзе, за яго аналізам, гэта є карысным. Возьмем компанент, які фільтруець спіс продуктав пры ўражанні:
function ProductList({ products }) {
const visible = products.filter(
product => product.inStock
);
Фільтраванный масэвы потым праганяецца безпосередна да дзецінага компанента:
return <List items={visible} />;
}
Даўжыню компіляцыі, развічальнік, які акцэнтавае увагу на выдатнасці, часта явным чынам кэшуе фільтр, так што List отрымае той самы аб’ект-адрэсу массива пакуль products не змяніцца:
const visible = useMemo(
() => products.filter(
product => product.inStock
),
[products]
);
Калі компіляцыя ўвімкнута, такі код зазвычай праігноруецца. Компілятор сам вырахоўвае залежнасці, можа кэшаваць мяркавей, чым це робляць ручна напісаныя хукі, і не выкарыстоўвае правільна перыяктаваныя вам залежнасці. React называе гэта автаматычным кэшаваннем для компонентаў і хуків.
Адзначыце, протэму, межы ў гэтым апісанні: кожны элемент у лісте ёсць структурой React.
Ментальная модель: оптымізатор адрасавання
Дапамагае уявіць сабе компілятор як аб’ект, який працуе над двума типамі задач у React і адсекае ўсё зайвое:
React Compiler
│
┌───────────┴───────────┐
▼ ▼
Component work Hook calculations
│ │
▼ ▼
memoization memoization
│ │
└───────────┬───────────┘
▼
fewer unnecessary
React updates
Меншая колькасць непатрэбных перыядражэнняў можа стаць справжнім прыбуткам. Аднак важлівай частю дыяграмы є тое, што яна не паказвае.
Медленныя бэкенды не ў межах яе можлівасцей
Разглядзім асінхронны компонент, які чакае на даны з API пры перыядражэнні панелі керування:
async function Dashboard() {
const data = await fetch(
"https://api.example.com/dashboard"
);
Калі даны прыбываюць, яны перадаюцца інтерфейсу:
return <DashboardUI data={data} />;
}
Якщо той канцэнтр патрабуе 800 мс, компілятор не зможа зменшыць гэты час да 50 мс. Ён можа спростыць пры ператварэнні дадзеных у інтерфейс у React, але не змусіць бэкенд адпавядаць быстрей. У вигляді часовай лініі:
Browser
│
▼
React
│
▼
API request ──────────► 800ms
│
▼
Response
│
▼
React render
Мемаізацыя выконвачваецца практычна абсалютна ў последнім кроцы. Якщо большая частка часу прабывае на чаканні сеті, вы оптымізаваеце не той слой; рашэнняя — глыбшыя запыткі, кэшаванне, меньшыя адпаведзіць или паралельнае запрашэнне дадзеных. Чыба адсепрація часу сеті ад часу кліента, пагляньце Diagnosing React Performance Issues Beyond the API Response Time.
JavaScript, які не трэба было дапраўляць
Той самы ліміт паўсходзіць і для размаху бандлу. Уявіце стартовую сторунку, якая завантажае важкую бібліятэку для стварэння графікаў, редактар тексту з расширэнымі можлівасцямі і SDK для аналітыкі ўжо перад тым, як хтось ачыне экраны, якія іх викорыстоўваюць:
Initial page
│
├── React
├── UI
├── Chart library
├── Editor
└── Analytics SDK
Кампіляр не адключае жадных залежнасцей; кожны байт все равно завантажваецца, параскладываецца і выконвачаецца. Дапамагае раздзелэнне коду, напрыклад, завантажэнне экрана аналітыкі за патрэбай:
const Analytics = lazy(
() => import("./Analytics")
);
Цей код запрашоўваецца толькі тады, калі функцыя насправды атрыбуецца, а суседнія межы Suspense паказваюць альтернатыўны варіант паказвання пакуль він завантажаецца. Цэя рашынка є часткай архітектуры пакетаў, і жадная мемазаванняе не можа яе заменіць.
Дзе выклікаюцца непарадныя наследкі
Частая ситуацыя: прыстрой запрацоўвае повольна, хтось увялічвае швальнасць компілятора, і каманда спадзяваецца на такі результат:
Slow app
│
▼
React Compiler
│
▼
Fast app
Гэта занадто проста. Повольнае запрацоўкі маюць калькі прычын, а компілятор падтрымлівае толькі адну з іх:
SLOW APP
│
┌───────────────┼───────────────┐
▼ ▼ ▼
React work Network Browser
│ │ │
▼ ▼ ▼
Compiler API/cache JS/rendering
│ │ │
▼ ▼ ▼
Optimized Engineer Engineer
Компілятор — це толькі адна з інструментаў для падвышэння працэснасці, а не сама інструментальная сумка. Для рашэння проблем з задзеймленасцю сеті та витрамі браузера, такімі як адрабатка скрыптав і форматаванне, все рава патрэбны людзі.
Чы хаця быць выдалены існуючыя вызывы useMemo?
Не автаматычна. У нэвыканутага коду офіцыйны стандарт — дазволіць кампайляру выконваць мемаўванне. Для жыдучага коду React радзіць застаўляць чынны спосаб мемаўвання або адменаваць яго толькі пасля рэтельных тэставанняў. Прычына ціх рэкамендацый — паведанчасныя аспекты, а не толькі канцэрнавасць: значэнне, якое было мемаўвана і выкарыстоўваецца як залежнасць Effect, вялічы, калі гэты Effect зноў будзе выкананы, таму змена спосабу мемаўвання можа пацягнуць за сабой змены ў часе выканання паўнарадковых эфектаў.
Таму трэба стрымацца ад прагнення адразу выконаць такую чыстку ў всім кодбэсе:
useMemo → DELETE
useCallback → DELETE
React.memo → DELETE
Безпечнейшы падход — поступовы, з пераканальнем на кожным кроцы:
Existing app
│
▼
Enable compiler
│
▼
Run tests
│
▼
Profile
│
▼
Remove unnecessary
manual memoization
carefully
Кампайляр створаны, каб у майбутнем зменшыць патрэбу ў ручным мемаўванні, а не каб за одну ноч заявіць, што ўсе існуючыя оптымізацыі неправильныя.
Кампайляр як пераканальнік якосці коду
Адзіныя перавага, якой падае меньшая увага: кампайляр включае этапы пераканальвання, створаныя на адпаведнасці з правіламі React, а його інтеграцыя з инструментамі лінтингу можа адказваць пра такія патэрны:
set-state-in-render
set-state-in-effect
unsafe ref access
React зазначае, што такія дыягнастыкі можу адкрыць багі, якія вже ўсё-такі існуюць у прыемлі. Паколькі кампайляр прахоўвае код, який наражае ў падазрэння його прыпускі, адзвешчанні таксама паказваюць, якія компоненты не оптымізаваны, таму гэта стае часткай ўседзённага цыклу адзвечання, а не проста плагінам для павышэння карыстоўнасці.
Спачатку аналізуйте, потым выберайце спосаб выправлення
Калі інтэрфейс здаецца медленным, перад тым, як вжываць будзь-які інструмент, здзейсніце вимеры, і нехай саме яны пакажуць прычыну:
SLOW UI
│
▼
PROFILE
│
┌────────┼────────┐
▼ ▼ ▼
React Network Browser
work │ │
│ │ │
▼ ▼ ▼
Compiler API/cache JS/render
│
▼
Targeted fix
Потым падберіце спосаб выправлення, які будзе адпаведны таму, што паказвае інструмент аналізу:
- Непатрэбныя перызначэння компонентаў у React: тут можа памагчы кампайляр React.
- Медленны API: паспрабуйце паўнэчыць канец-пункт або стратэгію запрашання дадзеных.
Ключовыя выводы
У старой модэлі было неабходна паведамляць React, што трэба запам’ятаваць; у новай вы можете пісаць правільны код на React і даваць кампайляру адпаведальнасць за большую частку роботы з рендэрам. Це падвышае значэнне адной навыку: ведаць, куды на самай працоўвае час.
- Кампайляр оптымізуе тую роботу, якую разумее, тое ў значэнні рендэр React і вычыслення хуків.
- Ён не можа зменшыць размер апасвячання API, прышвыдзіць запит да базы дадзеных, адключыць скрыпт трэцьяго сторонньага аплікацыі чы стиснуць адпрацоўванне 5 MB з’явы.
- Ён не можа вываліць архітэктуру, якая стварае непатрэбную роботу ў всіх месцах.
- У існуючам коде ўвядзіце яго, працаваць з ім, апрацаваць профіль i толькі пасля чаго адключыце ручную мемаізацыю.
- Спрыяйце яго діагностицы як безкоштовным адказам пра наявнасць праваў React.
Не запытваюце, чыякі кампайляр працуе, а лепш дзе практыка выдзейла свой час; самэ гэта і є метай кампайляра.