artalog
4.24K subscribers
542 photos
40 videos
40 files
913 links
Развернутые ответы на вопросы в чатах, мысли от рабочих процессов.
Вопросы - @artalar.
Download Telegram
Затравка перед завтрашним постом 🙂 на скрине неудачная попытка микрооптимизации бандлсайза.
🤔2🔥1
reduce nanoid bundlesize

Это уже становится хобби 🙂 Захожу раз в несколько месяцев в нано библиотеки Андрея Ситника и пытаюсь придумать как бы уменьшить их бандлсайз.

Это особенно увлекательно из-за того что Андрей сам большой спец в этом вопросе и найти какие-то оптимизации каждый раз очень сложно.

Вчера посчастливилось придумать оптимизацию, которая срезает 12% размера nanoid - доволен как слон 🤗

Кому интересны детали, обратите внимание на то что коммита два.
🔥12
Вот вам небольшая задачка на асинхронщину. Какой будет лог для каждой функции и какое из трех поведений использует реакт?

С
П
О
Й
Л
Е
Р

codesandbox

Наверное, реакт не батчит useEffect потому что в замыкании все равно предполагается старое иммутабельное значение, а не последнее по рефу.
Но в реальной жизни для описания какой-то логики и процессов нам нужны как минимум две очереди с разными приоритетами. Доказательством служит появление микротасков в платформе.
В некст реатоме, кстати, будет апишка для двух разных очередей.
🤔2
CSS-lock / CSS-шлюзы

Всегда хочется что бы веб приложением можно было пользоваться адекватно на всех устройствах, что бы контролы и текст не съезжали и при этом не было вертикального скрола. Те нужно что бы размер всей области просмотра динамически скейлился в зависимости от размера экрана.

В голову сразу же приходит viewport, но это довольно топорный инструмент, который просто скейлит весь экран. Было бы здорово иметь возможность динамически изменять размер контролов, не менять или менять по другому размер контента и применять ко всему этому медиа-выражения.

Решение - цсс-шлюзы. Демку с описанием можно найти тут, а в заголовке поста есть ссылки на английскую и русскую статьи с детальным объяснением идеи.

Базовый принцип такой: берем среднюю (медианную) ширину экрана целевой аудитории, под которую будем верстать, переводим 16px (базовый размер шрифта) в vw: для 1600px - это 1vw, для 1336px (стандартное для windows ноутбуков) - это 1.2vw и выставляем как font-size на html.
Теперь, чем меньше или больше будет размер экрана отличаться от базовой ширины, тем сильнее будет меняться и размер шрифта, что будет отражаться на всей нашей верстки, если мы будем описывать все размеры в em.

Но это не все, три важных уточнения! em наследуется по дереву, все может непропорционально меняться в случае необходимости изменения шрифта в каком-то узле, поэтому везде используем rem. Что бы не ломать пользовательский скейлинг (зум и системные настройки размера шрифта), стоит добавить в наш код абсолютные еденицы. И стоит поставить ограничения для слишком узких и огромных экранов. В итоге, получаем такой код:

html {
font-size: clamp(0.7em, calc(0.5vw + 0.7em), 1.4em);
}


Подогнал для красоты и запоминания все под семерки, но лучше значения настраивать самому и не пугаться больших дробей.
👍5
Очередная жертва дефолтных экспортов. Комичность еще и в том что импорт в модуле добавления рекламного тега - AddTag (неймспейс adTags), из-за чего становится совсем не ясно, нарочно ли был импорт так назван.
👍5🤔4💩2
artalog
🛑 в этом посте есть ошибки 🛑 Идемпотентность. TLDR: не мутируйте в useEffect! 1. Реакт позволяет с помощью useEffect описать какой-то эффект в ответ на изменение данных. 2. В рамках конкурентного рендеринга эффекты могут перевызываться лишний раз, под StrictMod…
Я был сильно не прав, useEffect не вызывается лишний раз.

Очень стыдно, простите 🙃

Избыточно перевызываться могут только хуки мемоизации.

За поправку спасибо @BuggyTheClown.

Но я еще подкину интересного по теме: Design decision: why do we need the stale closure problem in the first place? Старый и до сих пор не закрытый ишьес, в котором можно найти много занятный примеров. Может, повычитываю его потом повнимательней и скину сюда самое интересное.

UPD: useEffect без зависимостей все же может вызываться дважды в девелопе со стрикт модом.
👍4🤔2🔥1
Live stream started
Live stream finished (32 minutes)
Resumability: a no-overhead alternative to hydration

Статья подчеркивает то о чем я говорю уже года два и размышляю над возможной реализацией для реатома. Сама идея проста и состоит из двух частей: давайте грузить на клиент джаваскрипт только для интерактивности (без темплейтов) и делать это лениво.

Напомню проблему: всякие реакты и даже свелт после загрузки HTML от SSG / SSR предполагают загрузку его копии внутри JS в виде шаблонов, для построение биндингов к дому. Выглядит очень избыточно и статья о том и говорит. А еще это способствует не гранулярной работе с ДОМом и последующим томозам в рантайме.

Проблема делать иначе в том что для построения биндингов ЖСа к событиям и атрибутам ДОМа без наличия всего тела темплейта нужен достаточно хитрый компайлер, который все равно будет вас сильно ограничивать.

Но это в случае если хочется оставить возможность писать обработку данных прямо в темплейте. А если выносить ее в отдельное место и в JSX описывать только ссылки на реактивные сущности, то компилятор можно значительно упростить, а разработчика заставить описывать всю обработку состояния в соответствующем месте, за что я всегда выступал.

Уточню, что упрощение компилятора нужно не что бы ментейнеров библиотеки разгрузить, а что бы сделать инструмент с меньшей сложностью, большей предсказуемостью и простотой дебага.

Будет чудо, если в этом году я найду время на то что бы этим заняться 👀
👍12
rome.tools

Идея унифицированного инструмента для всех AOT (билд-тайм) преобразований очень здравая, зачем парсить текст и выделять семантику несколько раз. За Ромом стоят опытные разработчики (автор Babel), они уже подняли инвестиции и все бы ничего… Но продукта небыло очень долго и лично меня это сильно смущает. Говорят много, пощупать можно было мало. Два года потребовалось что бы выпустить форматтер, о котором я сегодня и хотел рассказать.

Начал понемногу пробовать его через расширение для vscode на реатоме, скорее по фану, пока что. Но оно preview, не отрабатывает и не пишет ошибки в output, если таковые есть - просто ничего не происходит. В плейграунде можно увидеть ошибки, но я вот вставил туда 600 строк кода и интерфейс фризится на секунды на моем m1.

Разницу с prettier можно увидеть тут. Правда, туда залетели дефолтные табы, использование которых странно для тех кто близок к OSS и гитхабу и знает как ужасно они там отображаются.

В общем, как вы могли заметить, у меня впечатления от всей этой истории негативные. Но, честно говоря, это потому что я многого ожидаю от этой тулзовины и хочется получить сразу все здесь и сейчас. Надеюсь, у них все получится.
👍5🤔2
Вот несколько примеров отличия от prettier, которые не касаются конфигурационных параметров.
🔥3🤔1
Так, пояснение. Я не верю в единственный правильный форматтер и только ради условно красившего форматирования уходить с преттиера, который стандарт индустрии, не стал бы.

У рома главная фича в экосистеме, которой сейчас нет 🙃.

Но! У него есть возможность парсить даже синтаксически ошибочный код - это может быть полезным во время разработки.
👍5
Live stream started
Live stream finished (20 minutes)
Асинхронная очередь.

В одном чатике задали простую, но интересную задачку: нужна очередь с колбеками, которые могут быть синхронными или асинхронными и должны исполняться строго один после завершения другого. Проблема в том что в очередь новые колбеки могут прилетать асинхронно в любое время.

Ну я накидал какой-то вариант, а потом еще несколько раз доправлял какие-то баги, которые всплыли в моей голове. И не уверен что все моменты учел. Нужно обрабатывать состояние пустой очереди, поступление колбека в момент когда очередь уже пуста, но последний колбек еще выполняется (промис) и тп.

Мне показалась моя же реализация сложной и не очевидной / не надежной и я решил еще подумать. После пары экспериментов в голову стукнуло максимально простое и понятное решение:


let chain = Promise.resolve()
export const add = cb => chain = chain.then(cb)


Тут здорово что then не хранит ссылку на предыдущий промис и нам не нужно заботиться об очистке памяти, под капотом список выглядит как односвязный linked list, голову которого подчищает GC, а мы храним только хвост.
👍16🔥4
Вот еще одна простая, но очень полезная утилита для очередей.

При рассылке ботом телеграма сообщений нельзя отправлять больше 30 в секунду, иначе можно словить временную блокировку.

Заводить под это дело очередь и кидать в нее колбеки не удобно, код перестает выглядить синхронно и могут появляться конфликты имен переменных в скоупах колбека и кода после него.

Сделал утилиту с состоянием последнего времени запроса, для использования нужно авейтнуть ее вызов перед отправкой сообщения, просто и удобно.



Посмотрел на предыдущий пост, можно было бы сделать еще проще:

freeMsgLimit = () => add(sleep(TLG_MESSAGE_LIMIT))

😀
👍6