О, не думал, что долистаю тут до настоящего человека. Если посмотреть профили этих комментаторов, то все они зарегистрированы вчера. Это какое-то дикое позорище.
Я описал в статье сколько это на самом деле стоит.
Справедливости ради, созданные функции даже не успеют попасть в old space, как их грохнет GC. А объекты созданные на каждый рендер тоже легкие, т.к. у них стабилизированный shape.
У реакта куда больше проблем с перфом, чем вами описанные
1) Ужасно долгий renderToString на SSR, который не даст превысить 40-50 RPS на среднем по производительности ядре серверов.
2) VDOM дерево куда сильнее бьет по GC, т.к. там не всегда стабильная структура и очень много лишних созданий shape'ов.
3) Громадный бандл, это дорого по компиляции/парсингу.
На этом фоне создание неиспользованных функций в рендере это вообще спички, особенно учитывая современные движки, которые такие вещи круто оптимизируют.
Поэтому, когда я хочу писать быстрые приложения, но оставаться в экосистеме реакта (по крайней мере, чтобы найм не усложнить) я использую Preact+Signals. Сильно проще выполнение diff, т.к. глубина дерева сигналов меньше чем vdom, сильно меньше бандл, плюс базовая скорости выше, чем в реакте.
Так может вы не будете защищать хуки? Это ведь они к этому приводят, и им приходится чинить их еще больше ломая все?
Тут сильно вкусовщиной пахнет. Я вот не люблю классы в js, т.к. на старых движках там все плохо с ними оптимизировано, от них громоздкий бандл получается и плюс всякие tensor не умеют укорачивать имена приватных свойств у класса, любят убивать дефолтные свойства у классов, оставляя их только в конструкторе и тем самым ломая тот же shape объекта, особенно если в разных вызовах конструкторов может быть инициализирован разный набор свойств.
То есть если вы заботитесь о производительности и памяти, классы не ваш выбор, нужно исследовать в конкретном случае, лучше/также ли они по перфу и памяти по сравнению с функциями, создающими объекты.
Мне кажется, что скорость обновления UI на современных компьютерах не является проблемой
Я вот не согласен совсем. Веб приложения современные тормозят, а могли бы не тормозить, если бы их делали вспоминая про перформанс. Архитектура важна, но она не важнее скорости, т.к. скорость важнее для продукта. Я много проводил АБ тестов в крупных компаниях, и всегда скорость влияет на продукт, даже 300мс могут сильно решать в продуктовых и финансовых метриках.
Мегабайты скриптов даже современные процессоры тяжко обрабатывают, а надо понимать, что пользователи часто с смартфонов сидят, там все намного хуже.
React из коробки медленный, он весит много, он тяжёлый для рендера, он ужасно тяжёлый для SSR. Но все на нем пишут, поэтому тяжело его в продукте применять, так как сложно будет найти разработчиков. В этом смысле preact идеален - и быстрый и разработчики react на нем могут писать даже не заметив подмены.
Архитектура это круто, но кому она нужна, если приложение тормозит?
Кстати, в преакте очень круто использовать их preact signals, они его интегрировали хорошо, что если в рендере в html элемент в атрибуты или children добавить сигнал без распаковки .value, то его изменение не приведет к ререндеру компонента, будет точечно обновлен атрибут или текстовое содержимое. По перфу эта связка идеальна. И можно точечно переписывать react приложение на такую связку.
Не, там поднимается V8, среди сред интерпретируемых языков он очень шустр. Просто ему нужно выполнить все дерево компонентов, получить VDOM дерево реакта и снова по нему рекурсивной функцией пройтись и получить html. Я не понимаю почему, но renderToString написан ужасно не оптимально. Можно было сделать хитрее и сразу html составлять по вызову createElement, вместо чем потом снова рекурсивно обходить дерево.
На клиент, если это SSR классический, идёт потоковый html, который в нескольких event loop вставляется на страницу, это гораздо быстрее и эффективнее, чем составлять DOM дерево на клиенте или делать innerHTML. Идея очень крутая, но реализация хромает.
Часто в SSR спасает кэширование. Можно кешировать SSR результат допустим для неавторизированных пользователей. Для них вариативность ответа часто мала. Плюс можно ключ кеша сформировать для разных групп пользователей.
Но вообще, renderToString даже базовый, ужасно медленный, там легко рендер будет выполняться 20-40мс. Плюс ещё много чего лишнего выполняется на сервере, что нужно только на клиенте, типа чтения пропсов событий, создание массива зависимостей для хуков. Ещё, например, makeObservable от mobx совершенно не нужен на клиенте, но создаёт лишние вычисления. Поэтому нужно брать профайлер в зубы и смотреть, может там какая-то функция формирования урлов ссылок или картинок кучу вычислений делает.
Ещё в идеале нужен инструмент, который бы позволял настраивать кеш верстки для отдельных компонентов. Условная шапка или футер не особо вариативны, поэтому можно высчитать строку один раз (такую библиотеку видел, но она не особо развивается).
Но в целом, конкатенация строк в js не особо быстрая, даже через шаблонизатор не сильно шустрее будет работать. Все хочу попробовать сделать нативный модуль renderToString на С или Rust, но пока руки не доходили.
Плюс я так и не понял, у автора NodeJS отдает статику js/css? Это должен делать nginx или аналоги. Плюс судя по проблемам с сетью, у него не настроен gzip, но это мои предположения.
Карма пользователя без публикаций не может быть больше +4
Кстати, не совсем точно. У меня нет публикаций, но карма 5, кажется кто-то из модерации/администрации может 5й балл закинуть. Но при этом мне недоступны плюшки >=5 кармы, т.е. я не могу голосовать отрицательно на посты и комментарии. Поэтому правильнее условие будет выглядеть: >=5 кармы && наличие публикаций
Preact+Signals, к сожалению, совсем не поддерживает реактивные классы
Классовые компоненты да, там с костылями только. Я и команда не пишем новый код на классовых компонентах, а в старом коде можно хелпер создать, который будет подписываться на сигнал и делать forceUpdate. Но это велосипед, поэтому ваша правда.
и завязывается на написание логики внутри компонента - этот подход не адаптировать под ViewModel и MobX.
Я делал ViewModel (правда там нет автоматической реактивности, нужно помечать поля). Реактивность работает за пределами preact, сигналы можно как угодно формировать, не обязательно в компонентах. А если такой сигнал уже подцепится в рендере компонента, то компонент автоматически становится observer компонентом.
т.е. в компонентах создаются сигналы через useSignal, а за пределами (в сторах) уже через signal.
Да, нет магии с makeAutoObservable, но на мой взгляд это только плюс, makeAutoObservable это код с кучей оверхеда.
Другой вопрос, что сигналы это примитивы, поэтому observable.deep там невозможен из коробки (но есть открытые решения).
сильная привязка к Preact
С React тоже отлично работает. А в SolidJS свои сигналы, которые очень похожи на преактовские.
В любом случае, в новых проектах проще SolidJS использовать. Preact+Signals хорош там, где уже есть react/preact приложение, или это проект на большую команду разработчиков, куда проще искать react разработчиков чем solidjs (да, при найме это оказывается важно, хотя обе технологии простые, но люди хотят строчку в резюме "работал с реактом").
Спасибо за статью и за то, что про перф что-то пишите, очень важная тема!
Меня смущает, что Painting так отличается. Если у вас одинаковое число элементов и одинаковые стили, то он должен +- быть равным, и Rendering тоже.
Я погонял локально ваш проект, и у меня всегда при перемещении по Page1 - Page 2 метрика Paiting на всех сборках близка к 5мс, а Rendering 15мс. Различий между фреймворками не заметил.
Плюс хочу добавить, что для меня супер сборка это Preact+Signals. Там перф ререндеров получается такой же, как с SolidJS. Если на них писать без использования useState/Callback/Memo, то можно вообще все приложение без ререндеров сделать (т.к. Preact если в div получает сигнал, то он не вызывает ререндер, а просто меняет атрибут элемента по изменению сигнала, по сути как в solid). Плюс совместимость с библиотеками React есть.
Хм, либо он есть, либо у него слишком частые ресканы. Когда я на компьютере сохраняю заметку, на телефоне она отображается где-то через 5 секунд. Довольно шустро.
Как я понял, имеется ввиду, что после покупки этой консоли, во время работы будешь ее играть (или хотеть играть), что скажется на объеме выполненных задач и бэклог распухнет.
Мне кажется, IvanTheCrazy писал не про вопросы из вашего поста, а про пример от пользователя kirillbelash93 про typeof на строку. Это действительно ужасный вопрос для собеседований.
Вопросы же из вашего поста часто встречаются в практике, лично меня ничего не смутило в них, на все можно +- ответить хоть как-то.
О, не думал, что долистаю тут до настоящего человека. Если посмотреть профили этих комментаторов, то все они зарегистрированы вчера. Это какое-то дикое позорище.
Справедливости ради, созданные функции даже не успеют попасть в old space, как их грохнет GC. А объекты созданные на каждый рендер тоже легкие, т.к. у них стабилизированный shape.
У реакта куда больше проблем с перфом, чем вами описанные
1) Ужасно долгий renderToString на SSR, который не даст превысить 40-50 RPS на среднем по производительности ядре серверов.
2) VDOM дерево куда сильнее бьет по GC, т.к. там не всегда стабильная структура и очень много лишних созданий shape'ов.
3) Громадный бандл, это дорого по компиляции/парсингу.
На этом фоне создание неиспользованных функций в рендере это вообще спички, особенно учитывая современные движки, которые такие вещи круто оптимизируют.
Поэтому, когда я хочу писать быстрые приложения, но оставаться в экосистеме реакта (по крайней мере, чтобы найм не усложнить) я использую Preact+Signals. Сильно проще выполнение diff, т.к. глубина дерева сигналов меньше чем vdom, сильно меньше бандл, плюс базовая скорости выше, чем в реакте.
Тут сильно вкусовщиной пахнет. Я вот не люблю классы в js, т.к. на старых движках там все плохо с ними оптимизировано, от них громоздкий бандл получается и плюс всякие tensor не умеют укорачивать имена приватных свойств у класса, любят убивать дефолтные свойства у классов, оставляя их только в конструкторе и тем самым ломая тот же shape объекта, особенно если в разных вызовах конструкторов может быть инициализирован разный набор свойств.
То есть если вы заботитесь о производительности и памяти, классы не ваш выбор, нужно исследовать в конкретном случае, лучше/также ли они по перфу и памяти по сравнению с функциями, создающими объекты.
Я вот не согласен совсем. Веб приложения современные тормозят, а могли бы не тормозить, если бы их делали вспоминая про перформанс. Архитектура важна, но она не важнее скорости, т.к. скорость важнее для продукта. Я много проводил АБ тестов в крупных компаниях, и всегда скорость влияет на продукт, даже 300мс могут сильно решать в продуктовых и финансовых метриках.
Мегабайты скриптов даже современные процессоры тяжко обрабатывают, а надо понимать, что пользователи часто с смартфонов сидят, там все намного хуже.
React из коробки медленный, он весит много, он тяжёлый для рендера, он ужасно тяжёлый для SSR. Но все на нем пишут, поэтому тяжело его в продукте применять, так как сложно будет найти разработчиков. В этом смысле preact идеален - и быстрый и разработчики react на нем могут писать даже не заметив подмены.
Архитектура это круто, но кому она нужна, если приложение тормозит?
Кстати, в преакте очень круто использовать их preact signals, они его интегрировали хорошо, что если в рендере в html элемент в атрибуты или children добавить сигнал без распаковки .value, то его изменение не приведет к ререндеру компонента, будет точечно обновлен атрибут или текстовое содержимое. По перфу эта связка идеальна. И можно точечно переписывать react приложение на такую связку.
Не, там поднимается V8, среди сред интерпретируемых языков он очень шустр. Просто ему нужно выполнить все дерево компонентов, получить VDOM дерево реакта и снова по нему рекурсивной функцией пройтись и получить html. Я не понимаю почему, но renderToString написан ужасно не оптимально. Можно было сделать хитрее и сразу html составлять по вызову createElement, вместо чем потом снова рекурсивно обходить дерево.
На клиент, если это SSR классический, идёт потоковый html, который в нескольких event loop вставляется на страницу, это гораздо быстрее и эффективнее, чем составлять DOM дерево на клиенте или делать innerHTML. Идея очень крутая, но реализация хромает.
Часто в SSR спасает кэширование. Можно кешировать SSR результат допустим для неавторизированных пользователей. Для них вариативность ответа часто мала. Плюс можно ключ кеша сформировать для разных групп пользователей.
Но вообще, renderToString даже базовый, ужасно медленный, там легко рендер будет выполняться 20-40мс. Плюс ещё много чего лишнего выполняется на сервере, что нужно только на клиенте, типа чтения пропсов событий, создание массива зависимостей для хуков. Ещё, например, makeObservable от mobx совершенно не нужен на клиенте, но создаёт лишние вычисления. Поэтому нужно брать профайлер в зубы и смотреть, может там какая-то функция формирования урлов ссылок или картинок кучу вычислений делает.
Ещё в идеале нужен инструмент, который бы позволял настраивать кеш верстки для отдельных компонентов. Условная шапка или футер не особо вариативны, поэтому можно высчитать строку один раз (такую библиотеку видел, но она не особо развивается).
Но в целом, конкатенация строк в js не особо быстрая, даже через шаблонизатор не сильно шустрее будет работать. Все хочу попробовать сделать нативный модуль renderToString на С или Rust, но пока руки не доходили.
Плюс я так и не понял, у автора NodeJS отдает статику js/css? Это должен делать nginx или аналоги. Плюс судя по проблемам с сетью, у него не настроен gzip, но это мои предположения.
А не, мне 5й уже поставили позже, даже кто-то писал до этого "не могу карму плюсануть, пишет максимум 4". Там какая-та магия точно.
Ну, считается, что вклад в общество это больше про посты а не комментарии. Но я из тех, кто глупо считает "все уже написано до нас" и не пишет статьи.
Кстати, не совсем точно. У меня нет публикаций, но карма 5, кажется кто-то из модерации/администрации может 5й балл закинуть. Но при этом мне недоступны плюшки >=5 кармы, т.е. я не могу голосовать отрицательно на посты и комментарии. Поэтому правильнее условие будет выглядеть: >=5 кармы && наличие публикаций
Есть вот такой черновик, он уже на stage 1 https://github.com/tc39/proposal-signals/blob/main/README.md
Но его принцип основан на примитивах, как в preact signals, хотя никто не мешает каждое поле объекта сделать сигналом.
Не, это плагины от стороннего автора на гитхабе.
https://github.com/ruslanlap/PowerToysRun-VideoDownloader
Классный обогреватель из моего компа получился :D
Классовые компоненты да, там с костылями только. Я и команда не пишем новый код на классовых компонентах, а в старом коде можно хелпер создать, который будет подписываться на сигнал и делать forceUpdate. Но это велосипед, поэтому ваша правда.
Я делал ViewModel (правда там нет автоматической реактивности, нужно помечать поля). Реактивность работает за пределами preact, сигналы можно как угодно формировать, не обязательно в компонентах. А если такой сигнал уже подцепится в рендере компонента, то компонент автоматически становится observer компонентом.
т.е. в компонентах создаются сигналы через useSignal, а за пределами (в сторах) уже через signal.
Да, нет магии с makeAutoObservable, но на мой взгляд это только плюс, makeAutoObservable это код с кучей оверхеда.
Другой вопрос, что сигналы это примитивы, поэтому
observable.deepтам невозможен из коробки (но есть открытые решения).С React тоже отлично работает. А в SolidJS свои сигналы, которые очень похожи на преактовские.
В любом случае, в новых проектах проще SolidJS использовать. Preact+Signals хорош там, где уже есть react/preact приложение, или это проект на большую команду разработчиков, куда проще искать react разработчиков чем solidjs (да, при найме это оказывается важно, хотя обе технологии простые, но люди хотят строчку в резюме "работал с реактом").
Спасибо за статью и за то, что про перф что-то пишите, очень важная тема!
Меня смущает, что Painting так отличается. Если у вас одинаковое число элементов и одинаковые стили, то он должен +- быть равным, и Rendering тоже.
Я погонял локально ваш проект, и у меня всегда при перемещении по Page1 - Page 2 метрика Paiting на всех сборках близка к 5мс, а Rendering 15мс. Различий между фреймворками не заметил.
Плюс хочу добавить, что для меня супер сборка это Preact+Signals. Там перф ререндеров получается такой же, как с SolidJS. Если на них писать без использования useState/Callback/Memo, то можно вообще все приложение без ререндеров сделать (т.к. Preact если в div получает сигнал, то он не вызывает ререндер, а просто меняет атрибут элемента по изменению сигнала, по сути как в solid). Плюс совместимость с библиотеками React есть.
А это перевод зарубежной статьи https://zenfamily.dental/csLearnDental.php Надо писать туда, иначе никогда не узнаем
Хм, либо он есть, либо у него слишком частые ресканы. Когда я на компьютере сохраняю заметку, на телефоне она отображается где-то через 5 секунд. Довольно шустро.
Как я понял, имеется ввиду, что после покупки этой консоли, во время работы будешь ее играть (или хотеть играть), что скажется на объеме выполненных задач и бэклог распухнет.
2003, последняя версия без Ribbon меню
Мне кажется, IvanTheCrazy писал не про вопросы из вашего поста, а про пример от пользователя kirillbelash93 про typeof на строку. Это действительно ужасный вопрос для собеседований.
Вопросы же из вашего поста часто встречаются в практике, лично меня ничего не смутило в них, на все можно +- ответить хоть как-то.
Нене, ютуб заблокировал блокировщики рекламы, а эти ребята заблокировали блокировку блокировщиков рекламы.