Вольный TLRD пересказ доклада с ReactConf2025 о том как реакту улучшали перф.
Сначала был сделан бенчмарк для измерения:
- В реакт контексте лежит Map c координатами
- Инпуты добавляют туда значения
- Компоненты в цикле пробегают мапу и селектят по пропу оттуда координаты которые используют в своих стилях.
Реакт рендерил это дело 4 секунды
Потом они прогнали это через реакт компайлер
Рендер стал занимать ~1.2 секунды (благодаря мемоизации)
Потом они переписали реакт на сигналы (на графике - React Forest)
И оказалось что компайлер лучше справляется. Они даже взяли сигналы кем-то уже написаные (преактовские?) - non React signals на графике - чтобы убедиться наверняка.
Потом два года они делали React Fir - novel hybrid eager / lazy incremental rendering, суть которого в том что бы икрементально вычислять изменения в доме (т.е. отказаться от vdom) от изменений в стейте.
Получилось быстро, хотя они так и не реализовали все фичи реакта.
И тут они решили положить в контекст стор вместо мапы
Сначала был сделан бенчмарк для измерения:
- В реакт контексте лежит Map c координатами
- Инпуты добавляют туда значения
- Компоненты в цикле пробегают мапу и селектят по пропу оттуда координаты которые используют в своих стилях.
Реакт рендерил это дело 4 секунды
Потом они прогнали это через реакт компайлер
Рендер стал занимать ~1.2 секунды (благодаря мемоизации)
Потом они переписали реакт на сигналы (на графике - React Forest)
И оказалось что компайлер лучше справляется. Они даже взяли сигналы кем-то уже написаные (преактовские?) - non React signals на графике - чтобы убедиться наверняка.
Потом два года они делали React Fir - novel hybrid eager / lazy incremental rendering, суть которого в том что бы икрементально вычислять изменения в доме (т.е. отказаться от vdom) от изменений в стейте.
Получилось быстро, хотя они так и не реализовали все фичи реакта.
И тут они решили положить в контекст стор вместо мапы
👍10😁10
Work & Beer Balance
Вольный TLRD пересказ доклада с ReactConf2025 о том как реакту улучшали перф. Сначала был сделан бенчмарк для измерения: - В реакт контексте лежит Map c координатами - Инпуты добавляют туда значения - Компоненты в цикле пробегают мапу и селектят по пропу…
Т.е. вот такой вот объект благодаря которому вместо того чтобы селектить значения из контекста - позволяет подписаться на них в конечном компоненте (т.е. получаем ререндер только того что эти значения использует). И оказалось что это быстрее чем React Fir (React + Compiler + Store) на графике
И хотя React Fir еще и со стором очень быстрый, оказалось что если взять бенчмарк более приближенный к реальности - время именно рендера (т.е. то что оптимизирует Fir) там мало на что влияет, так что эксперимент был закончен и были сделаны выводы что
а) Реакт и так достаточно быстрый
б) Тупит не реакт а ваша модель данных (то как вы их обновляете и то как сообщаете реакту об этом)
В итоге реакт тима сосредоточилась на том чтобы дать больше крутых и классных апи для интеграции сторонних сторов с реактом
И хотя React Fir еще и со стором очень быстрый, оказалось что если взять бенчмарк более приближенный к реальности - время именно рендера (т.е. то что оптимизирует Fir) там мало на что влияет, так что эксперимент был закончен и были сделаны выводы что
а) Реакт и так достаточно быстрый
б) Тупит не реакт а ваша модель данных (то как вы их обновляете и то как сообщаете реакту об этом)
В итоге реакт тима сосредоточилась на том чтобы дать больше крутых и классных апи для интеграции сторонних сторов с реактом
❤22
Мастзев набор утилит поверх преактовских сигналов
https://www.npmjs.com/package/@preact-signals/utils
https://www.npmjs.com/package/@preact-signals/utils
🔥1
Вот пишешь такой на typescript проект, а потом он становиться все больше и больше и в конце концов перф падает до того что вывод типа надо ждать 2 минуты.
А еще позже и вовсе случается это
И где-то вот тут начинаешь думать что может ворчуны в твиттере были правы и в перспективе больших проектов typescript и правда игрушечный язык, и может стоило все таки взять reasonml
А еще позже и вовсе случается это
error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.
И где-то вот тут начинаешь думать что может ворчуны в твиттере были правы и в перспективе больших проектов typescript и правда игрушечный язык, и может стоило все таки взять reasonml
👍9😁5
Если люди не хотят ставить MAX а упорно сидят в телеграмме надо просто сделать так чтоб телеграмм работал через теже сервера что и MAX
Telegram
bruhcollective.
the following content will be interesting for Russian-speaking only:
тут начали закупать в ТГ рекламу некого мессенджера "Telega", общающего золотые горы стабильную работу ТГ на территории РФ
но в чем подвох? а в том, что эта "Telega" (которая https://telega.me)…
тут начали закупать в ТГ рекламу некого мессенджера "Telega", общающего золотые горы стабильную работу ТГ на территории РФ
но в чем подвох? а в том, что эта "Telega" (которая https://telega.me)…
😁11
Смотрю тут доклад по vitest от мейнтейнера (Владимир Шеремет)
От самого крутого:
- в vitest с 4 версии будут встроенные браузерные тесты. Причем ничего особо настраивать не нужно. С скриншот тестированием (toMatchScreenshot).
- Но особо отметить хочется то что они могут запускаться прямо в дебагере vscode, хотя выполняются в headless браузере. Ну короче - react компоненты с эффектами можно тестировать как обычный код без кучи сомнительных моков и танцев с бубном.
- на 25% быстрее стартует каждый тест
- Устали ловить флаки тест который воспроизводиться только в CI? Vitest научился генерить playwright трейсы (их потом можно воспроизводить в Trace viewer)
Скачивается как артефакт тестового пайплайна.
- Готов поспорить вы не знали что к тестам можно прикреплять файлы и ссылки (см. КДПВ) через спец апи аннотаций.
- И то что каждый тест принимает signal в виде параметра, так что по ctrl + c или по нажатию кнопочки ⏹️ в ui можно мгновенно прерывать долгоиграющие тесты.
- Теперь можно мокать классы целиком
От самого крутого:
- в vitest с 4 версии будут встроенные браузерные тесты. Причем ничего особо настраивать не нужно. С скриншот тестированием (toMatchScreenshot).
- Но особо отметить хочется то что они могут запускаться прямо в дебагере vscode, хотя выполняются в headless браузере. Ну короче - react компоненты с эффектами можно тестировать как обычный код без кучи сомнительных моков и танцев с бубном.
- на 25% быстрее стартует каждый тест
- Устали ловить флаки тест который воспроизводиться только в CI? Vitest научился генерить playwright трейсы (их потом можно воспроизводить в Trace viewer)
Скачивается как артефакт тестового пайплайна.
- Готов поспорить вы не знали что к тестам можно прикреплять файлы и ссылки (см. КДПВ) через спец апи аннотаций.
- И то что каждый тест принимает signal в виде параметра, так что по ctrl + c или по нажатию кнопочки ⏹️ в ui можно мгновенно прерывать долгоиграющие тесты.
- Теперь можно мокать классы целиком
🔥20👍7
React Compiler релизнулся. С нетерпением жду докладов кому и насколько он увеличил производительность. Ведь это ещё и статистика того насколько люди понимают как и где оптимизировать реакт на практике. Если это будут 10-15% можно сделать вывод что концепция рендерим все по умолчанию, а что надо мемоизируем в целом рабочая.
react.dev
React Compiler v1.0 – React
The library for web and native user interfaces
👍5
This media is not supported in your browser
VIEW IN TELEGRAM
Механическая клавиатура но каждая клавиша - с сенсорной поверхностью = тачпад-клавиатура
🔥7🤔2
Сегодня попробовал заюзать tsgo в рабочем проекте.
Сразу оговорюсь - это здоровый монореп где нету разбивки на ts project-ы.
Самое крупное приложение в со всеми зависимостями (не учитывая нод модули) - 4236 ts файла.
С первого раза tsgo (аka ts native) скушал всю оперативку и своп (72 GB) и вылетел по ООМ.
У нас немало циклических зависимостей в конфигурациях, но tsc с ними живет и не зацикливается (благодаря агрессивному кэшированию?) а вот tsgo похоже зациклился.
Пришлось немного навести порядок, выпилить "baseUrl" (tsgo его не поддерживает и судя по всему не будет - вместо него рутом считается директория с tsconfig) и после исправления всех конфигов он таки запустился, вот результаты:
итого:
tsc - 67 секунд - в полтора потока
tsgo - 12,4 секунд - в 5 потоков
Впечатляет.
Сразу оговорюсь - это здоровый монореп где нету разбивки на ts project-ы.
Самое крупное приложение в со всеми зависимостями (не учитывая нод модули) - 4236 ts файла.
С первого раза tsgo (аka ts native) скушал всю оперативку и своп (72 GB) и вылетел по ООМ.
У нас немало циклических зависимостей в конфигурациях, но tsc с ними живет и не зацикливается (благодаря агрессивному кэшированию?) а вот tsgo похоже зациклился.
Пришлось немного навести порядок, выпилить "baseUrl" (tsgo его не поддерживает и судя по всему не будет - вместо него рутом считается директория с tsconfig) и после исправления всех конфигов он таки запустился, вот результаты:
$ time pnpx @typescript/native-preview
53,56s user
4,81s system
469% cpu
12,444 total
$ time pnpm --package=typescript dlx tsc
95,85s user
3,29s system
147% cpu
1:07,08 total
итого:
tsc - 67 секунд - в полтора потока
tsgo - 12,4 секунд - в 5 потоков
Впечатляет.
👍23
Не могу поверить что в инпутах c
Не могут же авторы браузерной апи быть настолько аметистами
type="date" значение для min параметра указывается в формате который из Date объекта можно получить только вот таким способом:new Date().toISOString().split('T')[0];Не могут же авторы браузерной апи быть настолько аметистами
😁17
Web Bluetooth API - это набор апи для того чтобы можно было подключиться к блютуз устройству через браузер.
Мне вот очень не хочется писать для этого мобильное приложение под разные платформы, и я решил его использовать.
И угадайте что - в лисе оно не поддерживается. Хотя тикет был создан 14 лет назад.
3 года назад он был закрыт с пометкой WONTFIX и комментарием (перевод):
И если честно это звучит... не убедительно. Мы же прекрасно понимаем что у маззилы просто нет желания или ресурсов на реализацию, только лишь на сочинение оправданий. Хром вот не считает, зашипил эту апи на 98% пользователей интернета, и теперь ее используют как минимум 50 000 пользователей espruino.com и ничего, брат живой. Может в очередном транше гугла на $ 555 000 000 найдется немножечко денег на то что бы эту апи зашипить. А то лиса скоро растеряет даже тех полтора гика которые у нее остались
Мне вот очень не хочется писать для этого мобильное приложение под разные платформы, и я решил его использовать.
И угадайте что - в лисе оно не поддерживается. Хотя тикет был создан 14 лет назад.
3 года назад он был закрыт с пометкой WONTFIX и комментарием (перевод):
Возможно, что позиция Mozilla по поводу этого API изменится в будущем <...> но на данный момент <...> наша официальная позиция заключается в том, что мы считаем ее реализацию вредоносной для Интернета.
И если честно это звучит... не убедительно. Мы же прекрасно понимаем что у маззилы просто нет желания или ресурсов на реализацию, только лишь на сочинение оправданий. Хром вот не считает, зашипил эту апи на 98% пользователей интернета, и теперь ее используют как минимум 50 000 пользователей espruino.com и ничего, брат живой. Может в очередном транше гугла на $ 555 000 000 найдется немножечко денег на то что бы эту апи зашипить. А то лиса скоро растеряет даже тех полтора гика которые у нее остались
bugzilla.mozilla.org
674737 - (webbluetooth) Introduce WebBluetooth support
RESOLVED (nobody) in Core - DOM: Device Interfaces. Last updated 2025-10-04.
👍15
Я все еще иногда использую renderProps!
Когда это позволяет избегать избыточной вложенности.
Для примера возьму такой кейс - у нас есть форма и для ее отображения нам надо получить некие значения.
Это могут быть значение редактируемой сущности, или просто дефолты, не важно.
Как это обычно пишут (упрощенно):
Теперь если мы будем навигироваться по коду мы будем проходить вот такой вот длинный путь.
(Этот эффект я называю - матрешкой)
Рендер пропы позволяют "вынести за скобки" подготовку данных минуя "технические" прокладки (по сути существующие просто потому, что хуки нельзя вложить в условия), что делает навигацию по коду удобнее*:
Теперь мы можем переходить в сразу интересующую нас часть и видеть более цельную струкру
Вроде мелочь, а приятно.
Только не забывайте что render пропы в таком виде будут создавать лишний рендер (children функция новая на каждый рендер), поэтому Page здесь лучше сразу обернуть в React.memo
* да, того же самого можно добиться используя контекст, и если результат вам нужен в нескольких местах, а не сразу же следующем компоненте лучше именно так и делать
Когда это позволяет избегать избыточной вложенности.
Для примера возьму такой кейс - у нас есть форма и для ее отображения нам надо получить некие значения.
Это могут быть значение редактируемой сущности, или просто дефолты, не важно.
Как это обычно пишут (упрощенно):
// Page.tsx
function Page() {
return (
<Layout>
<Header />
<Form />
<Footer />
</Layout>
)
}
// Form.tsx
function Form() {
const { pending, error, initialData } = useInitialDataRequest();
if (error) return <ErrorSplashScreen error={error} />;
if (pending) return <Spinner />;
return <FormFields initialData={initialData} />
}
// FormFields.tsx
function FormFields({ initialData }) {
return <form>
{/* ... */}
</form>
}
Теперь если мы будем навигироваться по коду мы будем проходить вот такой вот длинный путь.
A
└─► фетчинг данных для B
└──► B
└──► фетчинг данных для C
└──► C
(Этот эффект я называю - матрешкой)
Рендер пропы позволяют "вынести за скобки" подготовку данных минуя "технические" прокладки (по сути существующие просто потому, что хуки нельзя вложить в условия), что делает навигацию по коду удобнее*:
// Page.tsx
function Page() {
return (
<Layout>
<Header />
<InitialDataLoader>
{initialData => <FormFields initialData={initialData} />}
<InitialDataLoader/>
<Form />
<Footer />
</Layout>
)
}
// InitialDataLoader.tsx
function InitialDataLoader({ children }) {
const { pending, error, initialData } = useInitialDataRequest();
if (error) return <ErrorSplashScreen error={error} />;
if (pending) return <Spinner />;
return children(initialData);
}
// FormFields.tsx (ничего не изменилось)
function FormFields({ initialData }) {
return <form>
{/* ... */}
</form>
}
Теперь мы можем переходить в сразу интересующую нас часть и видеть более цельную струкру
A
└─► фетчинг данных для B
└──► B
└──► фетчинг данных для C
└──► C
Вроде мелочь, а приятно.
Только не забывайте что render пропы в таком виде будут создавать лишний рендер (children функция новая на каждый рендер), поэтому Page здесь лучше сразу обернуть в React.memo
* да, того же самого можно добиться используя контекст, и если результат вам нужен в нескольких местах, а не сразу же следующем компоненте лучше именно так и делать
👍8👎2
Есть много мифов о том когда устанавливать зависимость как
Не удивительно - все что нам говорит об этом документация npm - всего две строчки:
А как же быть с тем что у нас есть еще билдтайм и рантайм, не говоря уже о дев стейдже который билдится в CI с NODE_ENV="production". А зависимости тестов куда?
Я думаю каждый сможет ответить для себя на эти вопросы если будет понимать к каким практическим последствиям приводит установка пакета в
Я знаю о всего двух npm командах на которые это повлияет -
Чтобы это продемонстрировать я поднял локальный npm репозиторий и создал 4 пакета -
devDependencies а когда как dependenciesНе удивительно - все что нам говорит об этом документация npm - всего две строчки:
dependencies - Packages required by your application in production.
devDependencies - Packages that are only needed for local development and testing.
А как же быть с тем что у нас есть еще билдтайм и рантайм, не говоря уже о дев стейдже который билдится в CI с NODE_ENV="production". А зависимости тестов куда?
Я думаю каждый сможет ответить для себя на эти вопросы если будет понимать к каким практическим последствиям приводит установка пакета в
devDependencies.Я знаю о всего двух npm командах на которые это повлияет -
npm install и npm ci.Чтобы это продемонстрировать я поднял локальный npm репозиторий и создал 4 пакета -
package-a, package-b, package-c и package-d, а так же app. Как они между собой связаны - на КДПВ, все команды выполняем в app. Результаты в комментариях в силу ограничения длинны поста👍10🔥2
Чел запустил chatgpt на компе собранном в майнкрафте из редстоуна
👍2🤯2
Work & Beer Balance
Есть такой проект verdaccio - ваш собственый npm репозиторий. Причем он zero-config и как вариант - поставляется завернутым в докер - т.е. установил - и работает. Конечно же он умеет работать как прокси к другим репам (включая npmjs.org). Зачем оно надо?…
лайт версия verdaccio (без web ui, только бэкеэнд) - sinopia
GitHub
GitHub - rlidwka/sinopia: Private npm repository server
Private npm repository server. Contribute to rlidwka/sinopia development by creating an account on GitHub.
👍3❤1🔥1
Подборка Open Source Hardware из моего вишлиста
- Умный паяльник PINECIL 2 - 26$ (Офф вики с ссылками на репозитории + проекты комьюнити на Github)
- PowerBank с BMS - 30$ - Github
- Принтер Open Printer (еще не вышел но ждем)
- ploopy Наушники на малинке (96$) и трэкпад (75$) (а так же там есть мышь (75$) и куча разных трэкболов)
#openhard
- Умный паяльник PINECIL 2 - 26$ (Офф вики с ссылками на репозитории + проекты комьюнити на Github)
- PowerBank с BMS - 30$ - Github
- Принтер Open Printer (еще не вышел но ждем)
- ploopy Наушники на малинке (96$) и трэкпад (75$) (а так же там есть мышь (75$) и куча разных трэкболов)
#openhard
PINE STORE
PINECIL – Smart Mini Portable Soldering Iron (Version 2) - PINE STORE
A smart and affordable soldering iron running on a RISC-V SoC and featuring an open-source firmware. Portable and powerful, $25.99
🔥3
Очередной раз получил огнестрельное ранение в конечность пользуясь try catch.
Если вы не добавили
Еще один поинт в пользу того чтобы избегать try catch, заменяя его на более безопасные варианты
Если вы не добавили
await или не вернули промис из функции - тайпскрипт вам не подскажет что что-то пошло не так (и ваша ошибка пролетит мимо try catch в который эта функция обернута).Еще один поинт в пользу того чтобы избегать try catch, заменяя его на более безопасные варианты
👎6😁5👍1