artalog
Архитектура веба В комментариях к этому посту Никиты Прокопова опять начался дискурс об ошибочном применении веба (точнее браузерных технологий) для написания приложений. Мол, только нативные технологии, только хардкор, только так можно контролировать перф…
Состояние на клиенте
Множествостарыхопытных разработчиков постоянно выступают за максимально тонкие клиенты и одностраничные вебсайты (MPA), вместо SPA. SPA тяжелее, разделяют ответственность в кодовой базе и вносят лишнюю сложность.
Но я увеерн, что чем больше фич реализовано на клиенте и больше стейта там хранится, тем лучше UX пользователя и его общее впечатление от продукта. Идея перезагрузки всего отображения и накопленного состояния на каждый чих обрекает пользователей на страдание по десяткам причин и лишь показывает ленивость разработчиков. Ну или бизнес денег не дал 🙂
У меня есть очень простой пример, которым я хотел бы поделиться, того что может происходить с простым текстом на самой обычной странице любого блога. Конечно речь даже не идет о редактировании, только об отображении.
Итак, какие фичи на странице с текстом простого блога могут улучшать UX пользователя, храня состояние локально.
1) Поиск. Браузеры до сих пор не умеют в нормальный поиск по странице, нет банальных настроек case sensetive и частичного / полного совпадения, нет регекспов, нет поиска по части документа и нет краткого превью результатов поиска с разбивкой по главам. Нет поиска по нескольким страницам в рамках всей или части карты сайта. Все это нужно.
2) Выделение. Хочется подсвечивать текст и складывать его в заметки. Иногда, нужно выделить и скопировать несколько кусков текста разом. Выделением практически нельзя управлять с клавиатуры. Все это нужно.
3) Ссылки. До сих пор в вебе нет нативной возможности скопировать ссылку на заголовок. Так же, пользователь должен мочь сам выбирать якоря для подсветки по ссылки.
4) Закладки. Как на больших статьях помечать где пользователь остановился читать?
5) Предварительный просмотр. Картинки нужно мочь зумить, формулы вычислять, код запускать, диаграммы передвигать и тп.
6) Специфичные типы данных. Даты должны мочь добавляться в календарь, цвета копироваться с выбором формата, элементы списков отмечаться как выполненные, а денежные суммы переводиться в другую валюту.
Можно еще пачку пунктов придумать. И да, что-то уже есть в браузере, что-то скоро будет (нормальные дейт и колор пикеры только на подходе), но все это клиентское состояние и нужно понимать его и уметь с ним работать.
Главная проблема, которую можно решить только полным контролем клиентского состояния - это фичи поверх нескольких фич, когда мы каждое из их состояний связываем, для улучшения UX. Например, в поиске сначала должны появляться результаты из закладок, созданные ссылки пусть храняться где-то в истории и было бы хорошо мочь делать их на предварительный просмотр или какие-то выделения в нем.
Это просто несколько примеров в рамках работы с простым текстм. Но современные медиа и приложения намного сложнее и я уверен, всегда могут предоставить больше возможностей по работе с контентом, нежели есть сейчас.
Множество
Но я увеерн, что чем больше фич реализовано на клиенте и больше стейта там хранится, тем лучше UX пользователя и его общее впечатление от продукта. Идея перезагрузки всего отображения и накопленного состояния на каждый чих обрекает пользователей на страдание по десяткам причин и лишь показывает ленивость разработчиков. Ну или бизнес денег не дал 🙂
У меня есть очень простой пример, которым я хотел бы поделиться, того что может происходить с простым текстом на самой обычной странице любого блога. Конечно речь даже не идет о редактировании, только об отображении.
Итак, какие фичи на странице с текстом простого блога могут улучшать UX пользователя, храня состояние локально.
1) Поиск. Браузеры до сих пор не умеют в нормальный поиск по странице, нет банальных настроек case sensetive и частичного / полного совпадения, нет регекспов, нет поиска по части документа и нет краткого превью результатов поиска с разбивкой по главам. Нет поиска по нескольким страницам в рамках всей или части карты сайта. Все это нужно.
2) Выделение. Хочется подсвечивать текст и складывать его в заметки. Иногда, нужно выделить и скопировать несколько кусков текста разом. Выделением практически нельзя управлять с клавиатуры. Все это нужно.
3) Ссылки. До сих пор в вебе нет нативной возможности скопировать ссылку на заголовок. Так же, пользователь должен мочь сам выбирать якоря для подсветки по ссылки.
4) Закладки. Как на больших статьях помечать где пользователь остановился читать?
5) Предварительный просмотр. Картинки нужно мочь зумить, формулы вычислять, код запускать, диаграммы передвигать и тп.
6) Специфичные типы данных. Даты должны мочь добавляться в календарь, цвета копироваться с выбором формата, элементы списков отмечаться как выполненные, а денежные суммы переводиться в другую валюту.
Можно еще пачку пунктов придумать. И да, что-то уже есть в браузере, что-то скоро будет (нормальные дейт и колор пикеры только на подходе), но все это клиентское состояние и нужно понимать его и уметь с ним работать.
Главная проблема, которую можно решить только полным контролем клиентского состояния - это фичи поверх нескольких фич, когда мы каждое из их состояний связываем, для улучшения UX. Например, в поиске сначала должны появляться результаты из закладок, созданные ссылки пусть храняться где-то в истории и было бы хорошо мочь делать их на предварительный просмотр или какие-то выделения в нем.
Это просто несколько примеров в рамках работы с простым текстм. Но современные медиа и приложения намного сложнее и я уверен, всегда могут предоставить больше возможностей по работе с контентом, нежели есть сейчас.
👍26👎4❤1
SWC
У нас на проекте несколько сотен тысяч строк кода в монорепе, разбросанных по десяткам пакетов. Крупнейший сервис (админка) собирается на M1 с бабелем секунд 80 (после установки нод модулей). Мой коллега @Astartsky решил поправить перф сборки и попробовать SWC.
Миграция с бабеля оказалась практически безболезненной, тк SWC сразу включает в себя множество фич, которые реализованы в бабеле плагинами. Меньше чем за день удалось все завести и ускорить сборку до…
Скольки вы думаете?)
10 секунд, ускорение в ~8 раз. Для нас это значительная разница и результат очень обрадовал.
Паблишь в прод тормозят только небольшие проблемы в дев сборке со styled-components. Которые не будут решены, но решаются частично, да и чем-то можно пожертвовать ради такого перфа.
У нас на проекте несколько сотен тысяч строк кода в монорепе, разбросанных по десяткам пакетов. Крупнейший сервис (админка) собирается на M1 с бабелем секунд 80 (после установки нод модулей). Мой коллега @Astartsky решил поправить перф сборки и попробовать SWC.
Миграция с бабеля оказалась практически безболезненной, тк SWC сразу включает в себя множество фич, которые реализованы в бабеле плагинами. Меньше чем за день удалось все завести и ускорить сборку до…
Скольки вы думаете?)
10 секунд, ускорение в ~8 раз. Для нас это значительная разница и результат очень обрадовал.
Паблишь в прод тормозят только небольшие проблемы в дев сборке со styled-components. Которые не будут решены, но решаются частично, да и чем-то можно пожертвовать ради такого перфа.
👍15🔥4🤔1
Через минут 5 войс про перф оптимизацию, которую я долго искал и когда нашел ужаснулся
🔥2
Хотел сегодня написать про проблемы разгона спред оператора, но история эта довольно большая и затрагивает еще несколько оптимизаций. Сегодня дам поверхностную инфу, а на следующей неделе будем разбирать все детально.
Скрины перф тестов перед вами. Первый скрин “до” - сильно оптимизированная версия нового реатома (см `reatom3`) с точки зрения архитектуры и используемых структур данных. Меня не покидало ощущение что результаты должны быть лучше и после долгих копаний и перф дебага нашел две проблемы:
- копирование объектов лучше делать через ручное перечисление всех свойств
- нативный forof быстрее транспилированной версии и forEach вместе взятых.
Результат - либа стала тупо в два раза быстрее, см. абсолютные значения (`med` справа) на втором скрине.
Скрины перф тестов перед вами. Первый скрин “до” - сильно оптимизированная версия нового реатома (см `reatom3`) с точки зрения архитектуры и используемых структур данных. Меня не покидало ощущение что результаты должны быть лучше и после долгих копаний и перф дебага нашел две проблемы:
- копирование объектов лучше делать через ручное перечисление всех свойств
- нативный forof быстрее транспилированной версии и forEach вместе взятых.
Результат - либа стала тупо в два раза быстрее, см. абсолютные значения (`med` справа) на втором скрине.
👍12🔥2
Профилирование производительности
Хотел бы я рассказать о том как просто, быстро и весело это делать и что результат оправдывает все ожидания, но история будет только про хороший результат, а вот что бы его достичь придется покрутиться.
У меня есть бенчмарки для реатома и их результаты не всегда меня удовлетворяют. В очередном заходе на оптимизацию библиотеки я решил попрофилировать перф через нормальные инструменты, а не просто случайными переписками кода.
План был такой: посмотреть в профайлер от квоки, увидеть прожорливое место в коде и исправить ошибку, которую я, видимо, не заметил раньше.
По факту все было дольше и вот почему:
1) Из стандартного отсортированного списка вызовов функций я ничего понять не смог. Пошел изучал флеймграф. Там тоже мало что понятно, пока не не схлопнешь одинаковые вызовы вместе (
2) В бенче происходило много лишней работы, кроме самого теста реатома, которая мусорила в результаты. Для удобства чтения я закомментировал не важный для анализа код.
3) Когда я нашел прожорливое место перейти в исходники мне не удалось, видимо сурсмапы не подтягивались. Понимать минифицированный код было очень сложно, а преттиер не хотел его форматировать из-за какой-то ошибки парсинга. К счастью, у меня был установлен Rome и он смог отформатировать код к более понятному состоянию.
4) Я перезапустил профайлер и переоткрыл флеймграф, но ссылка на функцию потребляющую много ресурсов все еще вела на первую строчку, как будто код все еще минифицирован. Помогло только
5) Дальше меня ждал большой сюрприз, функция которая потребляля треть перфа в большом пайплайне операций была очень тривиальной и я все никак не мог понять в чем там проблема. Тк. профилировщик дает ссылку не на конкрутную проблемную операцию, а на содержащую ее функцию, я решил разбить внутрении операции на отдельные функции, а для удобочитаемости минифицированного кода я переписал функцию на методы тестового объекта - минификатор не меняет имена свойств, только переменные.
6) Повторяем п. 4 и вуаля! Проблема найдена. В минифицированной версии спред заменялся на свою реализацию с Object.assign (или полифилом).
Осталось лишь переписать копирование объекта на ручной перебор всех свойств и флеймграф стал более равномерным, ура-ура!)
P.S. Я попробовал запустить бенч с импортом из исходников, а не билда, для нормальной работы сурсмапов, но сами результаты тестов в этом случае едут (терсер и другие минификаторы делают некоторые AOT улучшения кода), да и ссылки все равно были на транспилированную версию без типов, которую делает квока под каптом.
P.P.S. После смены таргета билда на современные браузеры спред не транспилируется и работает быстрее, но версия с ручным перебором свойств все равно заметно быстрее.
Хотел бы я рассказать о том как просто, быстро и весело это делать и что результат оправдывает все ожидания, но история будет только про хороший результат, а вот что бы его достичь придется покрутиться.
У меня есть бенчмарки для реатома и их результаты не всегда меня удовлетворяют. В очередном заходе на оптимизацию библиотеки я решил попрофилировать перф через нормальные инструменты, а не просто случайными переписками кода.
План был такой: посмотреть в профайлер от квоки, увидеть прожорливое место в коде и исправить ошибку, которую я, видимо, не заметил раньше.
По факту все было дольше и вот почему:
1) Из стандартного отсортированного списка вызовов функций я ничего понять не смог. Пошел изучал флеймграф. Там тоже мало что понятно, пока не не схлопнешь одинаковые вызовы вместе (
Toggle left-heavy view).2) В бенче происходило много лишней работы, кроме самого теста реатома, которая мусорила в результаты. Для удобства чтения я закомментировал не важный для анализа код.
3) Когда я нашел прожорливое место перейти в исходники мне не удалось, видимо сурсмапы не подтягивались. Понимать минифицированный код было очень сложно, а преттиер не хотел его форматировать из-за какой-то ошибки парсинга. К счастью, у меня был установлен Rome и он смог отформатировать код к более понятному состоянию.
4) Я перезапустил профайлер и переоткрыл флеймграф, но ссылка на функцию потребляющую много ресурсов все еще вела на первую строчку, как будто код все еще минифицирован. Помогло только
rm /Users/artalar/.quokka/test.cpuprofile5) Дальше меня ждал большой сюрприз, функция которая потребляля треть перфа в большом пайплайне операций была очень тривиальной и я все никак не мог понять в чем там проблема. Тк. профилировщик дает ссылку не на конкрутную проблемную операцию, а на содержащую ее функцию, я решил разбить внутрении операции на отдельные функции, а для удобочитаемости минифицированного кода я переписал функцию на методы тестового объекта - минификатор не меняет имена свойств, только переменные.
6) Повторяем п. 4 и вуаля! Проблема найдена. В минифицированной версии спред заменялся на свою реализацию с Object.assign (или полифилом).
Осталось лишь переписать копирование объекта на ручной перебор всех свойств и флеймграф стал более равномерным, ура-ура!)
P.S. Я попробовал запустить бенч с импортом из исходников, а не билда, для нормальной работы сурсмапов, но сами результаты тестов в этом случае едут (терсер и другие минификаторы делают некоторые AOT улучшения кода), да и ссылки все равно были на транспилированную версию без типов, которую делает квока под каптом.
P.P.S. После смены таргета билда на современные браузеры спред не транспилируется и работает быстрее, но версия с ручным перебором свойств все равно заметно быстрее.
👍4🤔2
Есть такой уже старый и почти заброшенный ponyfoo.com, которым я восторгался в свое время. Там можно найти множество глубоких и понятных статей по теме фронтенда и далеко не все из них уже устарели.
Например, туда писал Benedikt Meurer, один из разработчиков v8.
Или вот еще пара статей:
Polyfills or Ponyfills?
The JavaScript Standard
Например, туда писал Benedikt Meurer, один из разработчиков v8.
Или вот еще пара статей:
Polyfills or Ponyfills?
The JavaScript Standard
👍4
artalog
Хотел сегодня написать про проблемы разгона спред оператора, но история эта довольно большая и затрагивает еще несколько оптимизаций. Сегодня дам поверхностную инфу, а на следующей неделе будем разбирать все детально. Скрины перф тестов перед вами. Первый…
А по поводу проблем с производительностью спред оператора есть такие баги:
https://bugs.chromium.org/p/v8/issues/detail?id=10763
https://bugs.chromium.org/p/chromium/issues/detail?id=1204540
Выдержка от @cevek:
видимо проблема в том что спред создает новый объект не соответветсвующей мапе к оригинальному
The problem is that the CloneObjectIC creates local copies of object literal maps instead of reusing the shared trees from the cache. The following should be true but isn't:
от этого случается мегаморфизм и прощай перформанс
https://bugs.chromium.org/p/v8/issues/detail?id=10763
https://bugs.chromium.org/p/chromium/issues/detail?id=1204540
Выдержка от @cevek:
видимо проблема в том что спред создает новый объект не соответветсвующей мапе к оригинальному
The problem is that the CloneObjectIC creates local copies of object literal maps instead of reusing the shared trees from the cache. The following should be true but isn't:
~/v8$ v8 --allow-natives-syntax --nolazy-feedback-allocation
d8> o = {a:1, b:2}; %HaveSameMap({...o}, {...o})
false
от этого случается мегаморфизм и прощай перформанс
👍6