Влад Шилов

Влад Шилов

Темы
Неделя
Oct 19, 2020 → Oct 25, 2020

Архив недели @omgovich

Понедельник


Всем привет! На этой неделе с вами Влад Шилов (@omgovich) из Ростова-на-Дону. Во фронтенде уже около 12 лет. Работаю в компании resume.io. Увлекаюсь разработкой микро-библиотек и коллекционированием резиновых уточек.

Большую часть карьеры был тимлидом и CTO в агентствах. Участвовал в запуске ~800 различных сайтов: от лендингов, промо и корпоративных, до e-commerce, личных кабинетов, и веб-приложений.

Делал много интерфейсных анимаций (о чем стараюсь не вспоминать), застал темные времена IE6 (верстал на таблицах, без PNG, теней и прочего), разрабататывал SPA на jQuery и Backbone (тоже лучше не вспоминать).

В последние годы работаю разработчиком на удаленке в продуктовой компании (чему бесконечно рад). В основном занимаюсь разработкой на React, отвечаю за большую часть serverless-микросервисов компании и рендеринг документов.

🔥Тред (Влад Шилов)
Темы этой недели: — Зависимости: почему их стоит избегать и как их выбирать. — JS-экосистема, популярность !== качество. — Микро-библиотеки: как и зачем их создавать. — Генерация и превью PDF-документов.

Слоган первого дня: «Do not choose dependencies blindly». Начну с истории, которые слушатели подкаста Веб-стандарты, от меня недавно слышали (youtu.be/ZWjfMGFITHE)...

В июне нам, в resume.io, понадобился компонент колор-пикера, чтобы пользователи могли менять цвет фонов и ссылок в их резюме. Я не хотел изобретать велосипед, а планировал найти готовое решение и кастомизировать его под разработанный нами минималистичный дизайн.
notion image

Я пошел в Google и NPM c поисковым запросом "react color picker", и не смог найти ничего кроме пакета react-color. Потыкав демку и увидев 8k звездочек на GitHub и почти 2 млн скачиваний на NPM в неделю, я подумал, что это явно хорошая штука, и сделал "npm install react-color".

После установки я только и делал, что удивлялся: Импорт любого компонента из react-color делал наш бандл тяжелее аж на 140 KB. Кастомизировать внешний вид практически невозможно, плохая производительность убивала юзабилити, а на a11y даже не было и намека.

У меня в голове случился конфликт: «Не может же такой популярный пакет быть таким плохим. Я же вижу, что комьюнити его использует». И решил посмотреть на пакет повнимательней, чем это сделал в первый раз:

Сначала я увидел, что там не настроен три-шейкинг, поэтому несмотря на то, что я импортировал только один компонент, к нам в бандл попал код всех 10+ компонентов, а также все их зависимости.

К слову, прямых зависимостей у пакета оказалось аж 6 штук, а всего в графе зависимостей их 11. Пожалуй, многовато для одного компонента.

Сами зависимости, тоже были "хороши". Например, библиотека tinycolor для конвертации цветов (у которой между прочим 3 млн скачиваний в неделю) весит 15 KB, не умеет три-шейкинг и, при этом, в коде есть "Big List of Colors" на 150 строчек:
notion image

Я начал искать другие пикеры и изучать их. Они оказались примерно такими же (куча зависимостей, большой вес, нет a11y). Посмотрев на популярные пакеты для других задач (не только колор-пикеры и не только для React), я увидел проблему:

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

🔥Тред (Влад Шилов)
Почему я вообще считаю, что надо заморачиваться на тему числа и веса зависимостей? Кто-то скажет: «10 КБ или 100 КБ — какая разница? Все равно это мало! Не мегабайт же!»

Проблема в том, что в проектах редко бывает только одна зависимость, а если у вас 10 зависимостей по 100 КБ, то это уже мегабайт, а если 10 зависимостей по 10 КБ — это в сумме всего 100 КБ.

Представим, что вам надо по-быстрому сделать форму на нескольких языках с колор-пикером, автосаджестом и еще парой каких-нибудь кастомных полей...

Если вы возьмете, например, react-dom (120KB), styled-components (14 KB), react-color (140 KB), react-intl (54 KB) и еще пару таких же популярных ребят, то получите вес больше 0,5 MB одного только JS-кода, который low-level телефон будет парсить несколько секунд.

Или вы возьмете preact (4 KB), goober (2 KB), react-colorful (6 KB), eo-locale (5 KB) и т.д., получите тот же самый функционал, но весить он будет примерно в 10 раз меньше, и даже слабый смартфон обработает код меньше, чем за секунду.

🔥Тред (Влад Шилов)
Итак, пакеты которые разработаны без заботы о размере и доступности зачастую становятся очень популярны и делают веб хуже. Что же мы, как комьюнити, можем сделать? Разумеется, раз это open-source, то можем делать Pull Request-ы, чтобы улучшить эти популярные либы.

Звучит разумно и благородно, но получается не всегда. Например, однажды я решил помочь одной библиотеке: сделал PR, где настроил инструменты для отслеживания размера и сказал автору, что помогу ему сделать либу легче. Однако мейнтейнер сказал, что ему это не интересно.

К тому же, зачастую, если пакет изначально разрабатывался без мыслей о размере, то его либо сложно, либо невозможно сделать легче хотя бы на 10% Тот же tinycolor2 спроектирован как moment: сделать его ощутимо легче без потери функционала и без кучи breaking changes уже не выйдет

Если же решите помочь какому-либо проекту стать легче, сперва вам понадобится настроить в репозитории инструменты, чтобы отслеживать как ваши изменения меняют вес импортов. Вашим первым PR-ом может быть, например, установка и настройка size-limit.

Рекомендую именно size-limit, так как в нем легко отслеживать вес отдельных импортов с учетом tree-shaking, да и вообще установка и использование очень простые. Для работы над оптимизацией более чем достаточно.

Так же, можно добавить в репозиторий action, для авто-отчетов в Pull Request-ах, чтобы упростить мейнтенерам процесс проверки. Примеры: github.com/preactjs/compr… github.com/andresz1/size-… С базовыми инструментами разобрались. Дальнейшие шаги в следующем треде.

🔥Тред (Влад Шилов)
Как можно сделать существующую библиотеку легче? Вариантов много, но начал бы со следующих пунктов: Удалить зависимости или заменить их на более легкие. Пример: заменить moment на date-fns (или на стандартный Date) или styled-components на какой-нибудь goober.

Настроить tree-shaking, чтобы неиспользуемый код зависимости не попадал в бандлы сайтов. Особенно актуально если библиотека предоставляет множество различных экспортов (как lodash). По сути, нужно просто настроить поле sideEffects в package.json. webpack.js.org/guides/tree-sh…

Если пакет публикуется в виде транспилированного кода, то "упростив" исходный код можно избавиться от лишних полифиллов. Отбрасывание современных "фишек" (классы, async/await, генераторы, spread-операторы и тд) значительно уменьшает вес того, что "выдает" Babel.

Например, ощутимо помогает замена классов на функции, так как Babel трансформирует классы в "колбасу" из кода. К тому же, названия методов у классов не минифицируются В случае с Реактом, переписав все на хуки и функциональные компоненты, можно сделать бандл легче почти в 2 раза
notion image

Также, из того что еще сразу приходит в голову, можно сделать легче сам пакет, чтобы ускорить его установку и время на CI. Для этого можно настроить .npmignore, а еще лучше поле files в package.json. docs.npmjs.com/files/package.…

Многие авторы не настраивают это и, в итоге, мы скачиваем в свои node_modules все подряд, включая тесты, демки и т.д (пример на картинке) Если запустить в папке проекта npm publish --dry-run, то можно проверить, какие файлы будут публиковаться, сколько их всего, какой общий вес
notion image

🔥Тред (Влад Шилов)
Если вы видите, что популярный пакет сложно сделать легче или автор не хочет принимать PR-ы на эту тему, вы можете просто попробовать найти альтернативу. Моя мысль в том, что если мы все изменим подход к подбору зависимостей, то лучшие библиотеки станут популярнее.

Учитывая, например, алгоритм сортировки поиска NPM: чем больше пакет скачивают, тем выше он в выдаче. Поэтому самое простое, и при этом не такое бесполезное, что вы можете сделать — не устанавливать плохие пакеты. Но как заранее понять что пакет плохой/хороший, спросите вы?

Давайте сперва посмотрим на типичный флоу по поиску и установке пакетов: Google/NPM → GitHub → npm install looks-good Проблема в том, что на этих шагах мы почти не встречаем метрик, которые характеризовали бы качество пакета.

Weekly downloads в NPM обманчивая метрика, так как есть много вариантов по которым у пакета может быть много скачиваний.
notion image

Например, у moment до сих пор в несколько раз больше скачиваний чем у date-fns, хотя авторы первого уже даже заявили, чтобы их не использовали. А у react-color очень много скачиваний, потому что он попал в зависимости к таким популярным проектам, как, например, Storybook.
notion image

Unpacked size в NPM тоже почти бестолковая цифра, т.к. характеризует вес именно самого пакета. При этом, например, пакет у которого забыли убрать из публикации тесты и ненужные конфиги, может весить столько же, сколько пакет, который публикует для вас sourcemap-ы и TS-декларации.

К примеру, содержимое пакета qs, у которого 40 млн скачиваний в неделю, имеет и тесты, и настройки редатора, и даже конфиг ESLint. Суммарный вес — 160 КБ. Если заменить ненужное на TS-декларации, то unpacked size, наверное, не сильно изменится, хотя качество либы вырастет.
notion image

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

Число звездочек на GH это просто vanity-метрика и не характеризует доверие комьюнити к проекту. Разработчик также может поставить звездочку просто чтобы добавить репозиторий в закладки и посмотреть на него потом.
notion image

А вот на Issues надо смотреть обязательно. Если у какого-нибудь, простого по функционалу пакета, уже несколько десятков Issue, это значит, что скорее всего пользователям много чего не хватает, есть баги и проект не поддерживается в должной мере.

Отмечу, что обязательно стоит посмотреть сами Issue: о чем они, как много среди них багов, как долго они уже открыты, отвечают ли мейнтейнеры и т.д. Это, пожалуй, одно из самых полезных действий, которое вы можете сделать пытаясь оценить пакет на основе его репозитория.
notion image

Разумеется, если автор их добавил, в README проекта могут быть различные бейджи про наличие тестов, процент code coverage, актуальность зависимостей и т.д. Но фактически, от самих GH и NPM кроме числа Issue и даты обновления толком не получить хороших числовых метрик для оценки

🔥Тред (Влад Шилов)
Окей, на GH и NPM метрик маловато, как же тогда оценить пакет не ковыряясь полдня в репозитории и не устанавливая его в свой проект? На помощь приходят такие классные сервисы и инструменты как: — bundlephobia.comnpm.anvaka.com — npm-consider

Проект bundlephobia.com я очень люблю и пользуюсь им почти каждый день. Здесь можно получить такую информацию как: вес импорта JS-кода (min и gzip), число прямых зависимостей и поддержка tree-shaking.
notion image

Также очень полезно посмотреть распределение веса. Зачастую авторы библиотек выбирают зависимости так неудачно, что для маленьких опциональных фич используются зависимости, которые весят в несколько раз больше кода самого пакета. Пример: bundlephobia.com/result?p=react…
notion image

Кстати, bundlephobia.com ведет что-то вроде библиотеки аналогов пакетов. Если вы знаете легкую альтернативу к какому-нибудь популярному пакету, можете сделать issue в репозитории bundlephobia.
notion image

Кто-то скажет, что так открыто предлагать альтернативы это немного токсично. Я лично считаю, что надо дать пользователю возможность выбрать. Если популярный пакет реально лучше, то он все равно выберет его, а не альтернативу. Подобная конкуренция должна хорошо влиять на качество

Если не хочется заходить на сайт бандлфобии, то есть браузерный extension, который работает с их API и добавляет отображение min и gzip размеров прямо на сайты NPM и GH. github.com/vicrazumov/js-…
notion image

Переходим к сервису npm.anvaka.com, который обожаю не меньше. Этот сервис рекурсивно строит граф зависимостей и показывает сколько всего вы притащите с свой node_modules.

Результаты могут вас, мягко говоря, удивить. Например, у пакета react-input-color шесть прямых зависимостей, но итоговое дерево его зависимостей включает больше 80 пакетов.
notion image

На меня, кстати, сильно влияет то, с какой такой анимацией тут строится граф: как будто какой-то вирус распространяется. Еще сильнее отбивает желание устанавливать пакеты с кучей зависимостей.
notion image

Если вдруг npm.anvaka.com не работает (у них иногда бывает), можете воспользоваться сайтом npm.broofa.com — почти тоже самое, но менее удобно (IMHO), зато с отображением баллов npms.io (про них чуть позже).

Для любителей CLI-инструментов, могу предложить npm-consider. Не особо популярный инструмент, но с кучей полезных функций. Запуская npm-consider install вместо npm install, вы можете перед установкой просмотреть граф зависимостей и оценить их размер. github.com/delfrrr/npm-co…

🔥Тред (Влад Шилов)
Если вы ищете пакеты на сайте NPM, то попробуйте npms.io — их поиск IMHO работает лучше. Разница в выдаче выглядит странно, учитывая тот факт, что на npmjs.com написано об использовании движка от npms.io: docs.npmjs.com/searching-for-…
notion image

В общих чертах, о том как работает анализатор пакетов от npms.io написано у них на сайте: npms.io/about Если нужно больше деталей, то можно изучить репозиторий (github.com/npms-io/npms-a…) или уговорить меня собрать в тред результаты моего исследования =)
notion image

Если хотите сравнить насколько лучше работает поиск npms.io, посмотрите, например, на выдачу все по тому же запросу "react color picker": npmjs.com/search?q=react… npms.io/search?q=react…

... половина первых страниц выдачи на npmjs.com по этому запросу — форки самого популярного пакета. Даже при желании здесь сложновато найти альтернативы. По сути, NPM провоцирует нас на использование самого популярного решения и не предлагает никакого выбора.
notion image

🔥Тред (Влад Шилов)
Резюмирую недавние треды: хотел бы попросить вас внимательней подходить к подбору зависимостей, и изменить привычный флоу, например, на такой: npms.io → NPM/GitHub → bundlephobia.comnpm.anvaka.com

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

Вторник


День второй: «Micro-libraries» Что я подразумеваю под этим понятием? Для меня лично, микро-библиотека — это средство решающее какую-либо задачу, сохраняя при этом близкий к минимальному размер бандла.

Это, например, date-fns, который решает большинство задач по работе с датами/временем, разбит на модули и весит очень мало. Или Preact, который повторяет функционал react+react-dom и весит всего 3–4 KB в gzip.

Несколько месяцев назад, я узнал, что самый популярный колор-пикер для React весит аж 140 KB, а легких альтернатив ему нет, — поэтому решил создать компонент, заботящийся о весе, производительности и доступности. Так родился react-colorful (1,8 KB gzip). github.com/omgovich/react…

Также, мы с @mlfrg, занимаемся развитием Wouter — это легкая современная альтернатива react-router, которая весит всего 1,3 KB в gzip: github.com/molefrog/wouter

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

Недавно мы с коллегами из resume.io отдыхали в дачном поселке в Тульской области, всего в 2 часах от Москвы, и были дни когда нам был доступен только слабенький 3G. После такого опыта я еще больше убедился, что нужно делать пакеты легче и каждый килобайт важен.

Есть много статей и видео о том, как размер JS-бандла влияет на время загрузки страниц при плохом соединении и как сильно парсинг JS-кода бьет по перфомансу слабых устройств. Пара ссылок для тех, кто любит цифры: v8.dev/blog/cost-of-j… developers.google.com/web/fundamenta…

Это все наводит на мысли, что важно стараться держать в уме, что не у всех в мире есть проводной домашний интернет, не всем доступен LTE, не у всех в тарифах безлимит или большой пакет гигабайт, не у всех iPhone или флагманские андроиды, не у всех макбуки или мощные ПК.

Давайте наконец перейдем к тому, как разрабатывать микро-библиотеки. Если вы нашли какую-то проблему или сферу для которой вы можете создать новое lightweight-решение, то не рекомендую сразу писать код, — начните с формирования целей и ограничений. 👇

Если решите, например, создать альтернативу какому-то тяжелому компоненту, то вам стоит заранее определить максимальный размер. Перед разработкой react-colorful я поставил себе цель сделать импорт своего компонента минимум в 10 раз легче, чем у react-color.

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

Во-вторых, для того, чтобы успешно продвигать библиотеку (об этом мы еще поговорим), вам понадобятся объективные преимущества на фоне "конкурентов". И, согласитесь, "10 times lighter than X" будет выглядеть очень хорошо.

К слову, ограничения могут касаться не только размера, но и производительности. У меня есть один проект — генератор запоминающихся паролей весом в 300 байт. Его цель быть не только легче, но и быстрее своих аналогов. github.com/omgovich/omgop…

Для этого я "загнал" все популярные генераторы паролей в один бенчмарк, посмотрел на цифры и решил, что мой должен быть в 2 раза быстрее и легче любого из существующих. Этот бенчмарк потом помогал отслеживать как обновление кода влияет на производительность.
notion image

Как только вы определили ограничения, настраивайте инструменты для их мониторинга: например, size-limit и benchmark.js. Во время разработки периодически запускайте их, чтобы понять как ваши изменения влияют на размер и скорость работы.

Кроме того, если вы планируете разрабатывать легкий аналог какой-то тяжелой библиотеки, то вам еще до начала разработки стоит подумать хотите ли вы делать похожее/совместимое API.

С одной стороны если API будет таким же, то разработчики легко смогут мигрировать на вашу библиотеку, а с другой — это может привести к тому, что вы повторите неудачную архитектуру. Правильного ответа тут нет, но зачастую, самый оптимальный вариант находится где-то посередине.

Например wouter повторяет знакомые по react-router интерфейсы, но при этом упрощает или отбрасывает advanced-кейсы, которые редко нужны. В большинстве случаев, миграция на эту библиотеку пройдет без проблем. github.com/molefrog/wouter

🔥Тред (Влад Шилов)
Как добиться того, чтобы вес библиотеки был небольшим? Многое, конечно, зависит от задачи, но первым универсальным пунктом я бы выделил "Не использовать зависимости пока это возможно". 👇

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

Зависимости могут стать уязвимыми или вообще исчезнуть (пока left-pad). Второе конечно маловероятно, но первое достаточно частый кейс, который "подкидывает" лишние работу и переживания, как разработчикам, так и пользователям библиотек. Меньше зависимостей — спокойней жизнь.

После выхода новой версии, зависимости могут начать больше весить, медленней работать или "тащить" дополнительные зависимости.
notion image

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

Из-за зависимостей в проектах может появляться несколько версий одного и того же пакета. Например, если вы разработаете какой-нибудь date-picker, который использует date-fns v2, а в проекте у пользователя используется v1, то в JS-бандл попадут обе версии.

Где-то год назад я потратил несколько дней, изучая отчеты webpack-bundle-analyzer и ковыряясь в yarn.lock нашей монорепы, пытался убрать дубли разных пакетов. "Клубок" зависимостей распутать очень сложно.

Кроме того, обычно, библиотеки загружаются в NPM уже с транспилеными кодом и вшитыми "полифилами". Это означает, что в конечном бандле может оказаться по несколько полифилов одной и той же проблемы, что прилично поднимает вес итогового JS-кода.

Например, вы используете у себя в пакете ES6 классы, для работы которых Babel меняет код и добавляет кучу функций вроде _createClass. Если какая-нибудь зависимость тоже использует классы и настроена аналогично, то в конечный бандл сайта попадет два набора полифиллов.

Окей, на GH и NPM метрик маловато, как же тогда оценить пакет не ковыряясь полдня в репозитории и не устанавливая его в свой проект? На помощь приходят такие классные сервисы и инструменты как: — bundlephobia.comnpm.anvaka.com — npm-consider
Меньше зависимостей = быстрая установка пакета, более быстрый и стабильный CI. Если все-таки решите добавить зависимость, подойдите к подбору тщательно и постарайтесь выполнить шаги, которые упоминал вчера. twitter.com/jsunderhood/st…

🔥Тред (Влад Шилов)
Также, если избегать вещей, которые плохо минифицируются, требуют полифиллов или трансформация кода, то можно заметно снизить вес вашей библиотеки после сборки. Примеры: 👇

Лучше использовать функции вместо классов. Функциям не нужна трансформация и, к тому же, в отличие от классов, они хорошо минифицируются. Избавившись от классов целиком может получится сделать итоговый минифицированный код в 2 раза легче.
notion image
notion image

Используйте обычные Promise, вместо async/await и генераторов. Хоть исходный код с async/await или yield и занимает меньше строк кода, но после трансформации эти участки кода будут весить во много раза больше, чем аналогичный код на промисах.
notion image

Такая же история со spread-оператором. Используете его один раз и бандл сразу значительно "потяжелеет".
notion image

Нужно быть аккуратнее с различными "новыми" методами встроенных классов. Пример: ваш бандлер работает с полифилами core-js, вы настроили проект на поддержу Edge 12, но использовали в коде Array.includes. Из-за этого в бандл попадет полифилл es.array.includes.
notion image
notion image

🔥Тред (Влад Шилов)
@jsunderhood По поводу includes github.com/zloirock/core-…
That's what I'm talking about... twitter.com/SanichKotikov/…

Если рассматривать различные микро-оптимизации веса бандла, то выделил бы следующие: Помимо классов, по возможности лучше не использовать и объекты, так как названия ключей в них обычно не минифицируются, а если используете, старайтесь делать ключи покороче. 👇

Вместо какого-нибудь { totalAmountOfPages: 1 } напишите { pageCount: 1 }. А еще лучше попробовать разбить объект на отдельные переменные: названия переменных отлично минифицируются.
notion image

Кстати, если ваша библиотека подразумевает настройку с помощью конфиг-объекта, то лучше сразу придумать названия ключей покороче. Потом поменять их без breaking changes будет нельзя.
notion image

Если в исходниках один код весит меньше другого, это не значит, что их минифицированные версии тоже. Простой пример: у нас в react-colorful есть функция clamp, которая работает на тернарниках.
notion image

Мне дважды предлагали заменить этот код на аналог с Math, так как он короче. Однако не учитывали, что минификация в корне меняет дело.
notion image

Всегда ищите более "короткий" способ. Даже если есть популярное bulletproof решение, подумайте над альтернативой. Например, для проверки, что клик был не мышкой, а пальцем, часто рекомендуют длинную проверку на TouchEvent, но я нашел для своих задач более короткий вариант.
notion image

Из области нано-оптимизаций: Скорее всего, ваш код будет отдаваться через gzip. Поэтому иногда разработчики пытаются подстроить итоговый код под алгоритм gzip.

Самое дикое, что я видел на эту тему — это сортировка строки с алфавитом в nanoid, чтобы gzip лучше сжал итоговый файл. Как видно на скриншоте, символы в строке пересортированы так, что в строке встречаются части названий методов. github.com/ai/nanoid/blob…
notion image

🔥Тред (Влад Шилов)
Коротко о продвижения микро-библиотек. Сразу скажу, что я не особо известный разработчик. Летом у меня было всего 200 подписчиков, но за пару месяцев получилось пропиарить библиотеку так, что меня позвали и в подкаст Веб-стандарты, и в jsunderhood. 👇

Если считаете, что нужно быть "звездой", чтобы ваш проект начали использовать, то это не так. Разумеется это поможет, но у меня вроде неплохо получилось без 5k подписчиков и всемирной известности. Многое зависит от того, сколько сил вы готовы вложить именно в продвижение.

Советую посмотреть доклад @andrey_sitnik о продвижении опен-сорс проектов, так как многие вещи я оттуда использовал лично и они реально пригодились. youtube.com/watch?v=DU0LiH…

Бесполезный проект продвинуть невозможно. У хорошей микро-библиотеки есть главное, что необходимо для роста популярности — польза для пользователя.
notion image

Если подойти к разработке проекта используя принципы, которые я описывал в начале дня, то она будет в разы легче/быстрее аналогов. Таким образом, у вас изначально есть как минимум 1–2 преимущества на фоне "конкурентов". Смело пишите о них в первых блоках вашего README.
notion image
notion image

Не поленитесь потратить некоторое время и сделать бенчмарки. Тогда люди смогут объективно оценить выгоду от использования вашей библиотеки. В react-colorful я вообще собрал бенчмарк на основе бейджей, использующих API bundlephobia.com.
notion image

Мне, кстати, не хватало бейджей про три-шейкинг и число зависимостей, так что я сделал их сам: github.com/badgen/badgen.… badgen.net/bundlephobia Вставляйте и в свои README тоже.

Как только вы сделали первые стабильные версии, сформировали хорошее README, нужно запускать волну продвижения: делаете регулярные посты о вашем проекте.

Нет смысла делать что-то целый год, чтобы потом написать один твит. Публикуйте информацию по мере выхода фич и развития проекта. Пиара много не бывает. Выпустили первую версию — пост. Добавили поддержку мобильных — пост. Добавили a11y — пост. Сделали еще легче — снова пост.
notion image

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

Несколько постов в Твиттере на английском, несколько публикаций на Reddit/DEVto, пара постов в Telegram/Twitter-каналах и у вас начнет формироваться свое комьюнити. Дальше в том же духе и расширяя спектр каналов.

Кто-то скажет: "У меня вообще нет подписчиков, как люди увидят мои твиты?". Справедливо. И я вас понимаю, ведь у меня такая же история. Для этого, во-первых, и надо пробовать Reddit и публичные сайты/каналы, где ваша личная популярность не так сильно влияет на результат.

Reddit на удивление сильно помог нам на начальном этапе продвижения. После первых постов у нас даже появились активные контрибьюторы. reddit.com/r/reactjs/comm…

Так же, рекомендую вам не стесняться mention-ить в Твиттере известных разработчиков, которые могут оценить вашу заботу о размере, доступности или других ценностях. Например, Дэн Абрамов, Андрей Ситник или ребята из Preact легко могут сделать ретвит и охват поста будет огромный.

🔥Тред (Влад Шилов)
Чтобы разработчики начали использовать ваш пакет в продакшене, информация о вашей либе должна внушать им уверенность. Обычно, люди видят, что у пакета много скачиваний и им этого достаточно, но у новой библиотеки им взяться неоткуда. Проблема курицы и яйца. 👇
notion image

Без популярности неоткуда взяться установкам, а без них нет доверия, которое нужно для популярности. Нужно, чтобы появились проекты, которые используют вашу библиотеку. GitHub покажет их в "Used by", а NPM — в Dependents. И они же дадут первые цифры по установкам.
notion image

Если ваша библиотека только вышла, то вряд ли кто-то сам найдет и установит ее. Но никто не мешает вам найти через GitHub и NPM проекты, которые используют более тяжелые аналоги и сделать PR, заменяющий их на ваш пакет.
notion image

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

Разумеется, шанс, что PR-ы примут — не очень высок, а делать их при этом очень сложно (нужно развернуть и запустить незнакомый проект, разобраться в его коде и т.д). Особенно тяжело, когда API вашей библиотеки отличается от API пакета, который вы хотите заменить.

Если у вас хорошее README, демка и вы хорошо описали пользу для проекта от вашего PR, то шансы конечно выше. Сразу делать PR-ы в крупные проекты наверное не стоит. Начните, например, с простых инструментов/сайтов, которые разработчики делают для других разработчиков.
notion image

Точно не будет лишним отметить проекты, которые используют вашу библиотеку, в README и, по возможности, "приправить" все это цитатой какого-нибудь известного разработчика.
notion image

Мне немного повезло, так как я изначально сделал колор-пикер как рабочую задачу для resume.io, а уже потом мы его заопенсорсили. Так что в моем README сразу красовался проект с аудиторией в 8 млн пользователей.
notion image

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

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

🔥Тред (Влад Шилов)

Среда


Ключевой частью resume.io является конструктор, в котором пользователи создают резюме, чтобы потом скачать его в виде PDF и отправить потенциальному работодателю. Рендеринг и live-превью PDF — это, наверное, один из самых больших челленджей, которые мы решали. 👇
notion image

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

В 2016 году, когда велась работа над MVP нашего продукта, ребятам был нужен быстрый и легкий способ внедрить генерацию PDF, при этом не вводя другие технологии, языки и т.д. 👇

Бекенд resume.io работал и работает на Rails, поэтому ребята нашли гем Wicked PDF, который генерирует PDF на основе HTML+CSS, что идеально нам подходило.
notion image

Wicked PDF — это ruby-обертка над CLI-инструментом wkhtmltopdf, который под капотом работает с Qt Webkit. Последний стал для нас причиной проблем, но об этом позже. wkhtmltopdf.org
notion image

Быстро были сверстаны несколько HTML-шаблонов для резюме, которые рендерились рельсами как обычные view, и в 2016 вышло MVP, которое работало так: юзер регистрировался, поэтапно заполнял резюме, а потом нажимал "Download" и только тогда видел какое резюме у него получилось.
notion image

С точки зрения UX не очень хорошо, зато уже работало и приносило деньги. Однако, с ростом пользовательской базы начало приходить все больше сообщений о том, что в рендере PDF-файлов есть ошибки и резюме выглядят некорректно:

Оказалось, что многие CSS-свойства в Wicked PDF работали неправильно. Например, letter-spacing не работал вообще, а flex поддерживался не полностью. Часто были проблемы с отрисовкой кастомных шрифтов.
notion image

🔥Тред (Влад Шилов)
В 2017 мы выпустили следующую версию редактора, в которой, поскольку этого явно не хватало, была добавлена возможность предпросмотра резюме до его скачивания. 👇
notion image

Превью, работало на том же HTML- и CSS-коде, который мы использовали для рендера PDF. Поскольку это были обычные веб-страницы, то для превью мы использовали iframe. Это было самое очевидное и простое решение, которое очень быстро внедрили.

Добавление превью открыло Ящик Пандоры и число наших проблем начало расти в геометрической прогрессии. Дело в том, что браузер пользователя и Wicked PDF рендерили одинаковые HTML+CSS по разному. Люди начали жаловаться, что они видят в браузере одно, а скачивают совсем другое.

Большая часть проблем, которые в 2017 году были у нас в рендеринге PDF из HTML+CSS, были вызваны тем, что Wicked PDF использовал Qt Webkit, который работал с устаревшей на несколько лет версией движка Webkit. 👇

Это, к слову, стало одной из причин закрытия PhantomJS, который тоже работал на Qt Webkit. Вот интересное интервью с мэйнтейнером PhantomJS на эту тему: medium.com/devschacht/pha…

Пока мы думали, что же делать, команда Хрома выпустила Puppeteer и все недовольные пользовали Wicked PDF, включая нас, начали мигрировать на него. Генерация PDF через Puppeteer, по сути, аналогична тому, что вы откроете Print в Chrome и вместо принтера выберете "Сохранить в PDF"

Мы переделали архитектуру рендеринга и сделали новый изолированный сервис, который запускал Puppeteer. Сам код для получение PDF с помощью Puppeteer был простым и выглядел примерно так:
notion image

Что не маловажно, мы не удалили наш Wicked PDF рендерер. И он, и наш новый сервис работали с HTML+CSS, а значит были совместимы. Поэтому настроили архитектуру таким образом, чтобы в случае падения нового движка, рендеринг резюме временно переходил на старый.

После миграции на Puppeteer жизнь стала в разы легче, PDF-ки стали рисоваться без багов, а клиенты стали на порядок довольней. Однако, в 2018 году стало понятно, что эпопея с рендерингом и превью PDF не закончилась...

🔥Тред (Влад Шилов)
В 2018 году, собрав фидбек от пользователей, мы поняли, что отображения превью на отдельном шаге недостаточно. Пользователи хотели видеть: — как меняется резюме прямо в процессе редактирования; — как их контент помещается на А4-страницы в PDF. 👇

Поэтому мы разработали новую версию редактора, правую часть экрана в котором занимает лайв-превью с (внимание!) постраничной навигацией.
notion image

Принцип отрисовки самого превью мы не поменяли — это все еще были обычные HTML и CSS, которые показывали через iframe. Но теперь ко всему этому добавилась необходимость эмулировать разделение контента на страницы А4. И вот тут проблемы снова «полезли, как червячки»...

Суть в том, что веб-страница это просто длинное "полотно" и разделения на страницы у нее нет. В попытках решить эту проблему, мы написали JS-скрипт под названием Paguin 🐧, который подключали на страницу превью (отображается внутри iframe).

Скрипт пробегался по всем HTML-элементам и проверял, попадают ли они в зону указанного размера и, таким образом собирал массивы элементов для каждой А4-страницы.

Общение между Paguin-ом в iframe и нашим редактором резюме осуществлялось через postMessage. Paguin посылал "наверх" число страниц, на которое он разбил элементы страницы. А наше React-приложение посылало ему "вниз" команды на переключение страниц.

Смена страниц производилась без перезагрузки iframe — мы просто устанавливали display: none всем элементам, которые не попадали в массив для нужной страницы.
notion image

Вроде бы это все должно было решить проблему с превью, но увы... Главной темой жалоб в поддержку стало то, что пользователи, глядя на превью, заполняли резюме, так чтобы оно помещалось на 1-2 страницы, а после скачивания получали другое число страниц и вообще другие переносы.

Дело в том, что полностью повторить, то как Chrome разбивает контент на А4-страницы при печати у нас не вышло. Из-за этого структура документа в превью часто отличалась от той, что была в скачанном PDF-файле.

Например, в сделанной Puppeteer-ом PDF-ке параграф текста мог начаться на одной странице, а закончится на другой. Мы не могли такое повторить, так как для нашего скрипта параграф — это один неразрывный HTML-элемент.

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

Кроме того, так как сами PDF-файлы мы генерировали с помощью Headless Chrome, у пользователей, например, Edge и Firefox, HTML-превью не было похоже на PDF еще сильнее. Другой рендеринг шрифтов, другие переносы в тексте и т.д. Короче, беда.
notion image

В течение года мы предпринимали разные попытки потюнить скрипт пагинации, но быстро стало понятно, что эту битву нам не выйграть. Не получится сделать HTML+CSS превью, которое будет в достаточной мере похоже на PDF-файл, который делается из этих же HTML+CSS.

🔥Тред (Влад Шилов)
Резюмирую сегодняшнюю информацию: Вы можете генерировать PDF-файлы на основе HTML+CSS если ваше приложение не показывает live-превью будущей PDF-ки и не важно, как контент разделится на страницы. То есть для задач, вроде отправки чеков или билетов по почте, это подходит отлично.

Тот же Puppeteer достаточно легко внедрить, а для верстки PDF нужно будет знать только HTML и CSS. Это хорошее решение, чтобы быстро внедрить генерацию PDF-файлов. Главное не показывайте пользователю эти HTML+CSS в браузере, если вам важно, чтобы внешний вид превью и PDF совпадал

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

Раз уж мы сегодня погружаемся в прошлое, как на счет немного удариться в ностальгию? Давайте поделимся друг с другом скриншотами/ссылками на наши старые проекты или историями про них. Я нашел сайты, которые делал еще в 2007—2009 годах. Вот это дизайн раньше был! =)
notion image
notion image
notion image
notion image

Раз уж мы сегодня погружаемся в прошлое, как на счет немного удариться в ностальгию? Давайте поделимся друг с другом скриншотами/ссылками на наши старые проекты или историями про них. Я нашел сайты, которые делал еще в 2007—2009 годах. Вот это дизайн раньше был! =) pic.twitter.com/LZWr1qR9eb
2020 как не очень, поэтому мы открыли портал в прошлое десятилетие) twitter.com/jsunderhood/st…

@toivonens @jsunderhood О да! Я такое для сайта строй материалов делал. Там ещё кусты на земле тянулись
Всегда смешило как со стороны звучат разговоры про верстку старых сайтов =) «У тебя логотип на облако наехал» «Почему дерево не резиновое» «У телефона в подвале должна быть тень» ... twitter.com/gladkih_m/stat…

Четверг


Продолжаю историю про PDF: Наступил 2018, у нас стало 1,8 млн юзеров и наш support был завален письмами от пользователей о том, что они заполнили резюме, глядя на превью, а потом скачали PDF, в котором контент по-другому "влезал" на страницы А4 и вообще число страниц другое. 👇
notion image

Как я писал вчера, хоть Puppeteer и делал PDF на основе тех же HTML+CSS, что мы показывали юзеру в браузере. Для своего iframe-превью мы смогли написать такой JS, который смог бы повторить логику Puppeteer-а по разделению HTML-элементов на А4-страницы.

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

Можно было бы, например, оставить и Puppeteer, и наши HTML/CSS-шаблоны: Генерировать новый PDF-файлы при каждом изменении резюме, а потом показывать этот файл в браузере через pdf.js. Так вчера предлагали сделать некоторые подписчики.

Однако, этот вариант быстро "отпал", так как для каждого пользователя превью нужно обновлять хотя бы раз в несколько секунд. Для этого Puppeteer был слишком ресурсоемким и недостаточно быстрым.

Мы проверили существующие JS-библиотеки, которые позволяли бы создавать PDF и на сервере, и в браузере. Были, например: jsPDF и PDFkit, которые оказались неудобны для верстки таких сложных документов как резюме. parall.ax/products/jspdf pdfkit.org

Autolayout-а в jsPDF и PDFkit нет — нужно самостоятельно расставлять элементы по координатам (как в Canvas API), "руками" создавать страницы и т.д. Учитывая, что у нас 36 динамических шаблонов по сложности верстки сопоставимых с сайтами, эти решения нам не никак подходили.
notion image

Есть еще pdfmake, в котором хоть и есть autolayout, стили и т.д., но после попытки сверстать на нем документ хотя бы средней сложности, к этому инструменту вы больше не вернетесь. Для простых документов подходит. Для резюме — нет. pdfmake.org/playground.html twitter.com/SlimBaron/stat…

Упс, опечаточка: "мы НЕ смогли написать".

🔥Тред (Влад Шилов)
PDFkit, PDFmake и jsPDF не подошли, так что мы решили потестировать проект React-PDF, за которым уже некоторое время наблюдали. По аналогии как, например, React-Native является рендерером для мобильных приложений, так React-PDF — react-рендерер для PDF. react-pdf.org
notion image

React-PDF нам хорошо подходил, так как отлично укладывался в наши требования: Знакомые технологии. Чтобы создать документ с помощью React-PDF нужны знания только CSS, JS и React. Autolayout, легкость верстки за счет повторения возможностей HTML+CSS.

SSR и CSR. React-PDF может делать PDF не только на сервере, но и в браузере, а это значит, что можно сэкономить много денег на вычислительных ресурсах. Perfomance. Мы провели кучу замеров и скорость работы нас более чем устроила (~200 ms на рендер базового резюме).
notion image

Мы сделали у себя в проекте браузерный playground для экспериметов с React-PDF. И, чтобы снова не наступить на старые грабли, полностью сверстали один из шаблонов резюме и проверили на нем все, что нас волновало.
notion image

Например, у нас был чеклист для проверки "качества" рендеринга. Не хватало только поддержки SVG (вроде бы уже есть), но это не было для нас большой проблемой. В итоге все оказалось хорошо: мы поняли, что React-PDF нам подходит и начали поэтапно внедрять его в наш продукт
notion image

В первой половине 2019 года мы переверстали все шаблоны резюме на React-PDF, решили все возникшие по пути проблемы (о них чуть позже), провели несколько A/B тестов и сейчас используем React-PDF в нашем продукте, как основной и единственный движок рендеринга и превью PDF.

🔥Тред (Влад Шилов)
React-PDF хорош тем, что упрощает верстку сложных PDF-файлов, делая его максимально похожим на верстку HTML-страниц c использованием React. Только вместо HTML-тэгов вы используете компоненты, которые предоставляет сам React-PDF. Например, View вместо div и Text вместо span.
notion image

Есть ряд компонентов, которые специфичны именно для PDF: — Document – корневой компонент, для описания различных мета-данных файла (заголовок, автор и т.д). — Page – по сути это body, но с дополнительными функциями по описанию формата (A4 и т.д) и ориентации страниц.
notion image

Отмечу, что хотя компонент и называется Page, не нужно вручную оборачивать каждую страницу в отдельный компонент. В Document добавляется только один Page, а React-PDF сам будет разбивать его содержимое на страницы.

Чтобы вручную перенести контент на новую страницу, можно воспользоваться специальным property "break".
notion image

🔥Тред (Влад Шилов)
Хотя рендеринг в React-PDF, по сути, не имеет отношения к вебу и браузерам, стилизация там делается с помощью CSS, а значит учить отдельно ничего не надо. Причем поддерживается много свойств и, в целом, все работает почти так же, как в браузере. react-pdf.org/styling
notion image

Серьезно, тут есть и полноценный flexbox, и отступы, и border-ы, все что нужно для настройки шрифтов. Даже position: relative/absolute и transform работают. Если вы когда-нибудь "верстали" PDF с помощью других инструментов, то понимаете какое это счастье иметь возможности CSS.

Как я понял, React-PDF, как и React-Native, для работы с расположением элементов использует yoga-layout. yogalayout.com

Стандартным способом работы с CSS является использование StyleSheet и передача стилей в properties компонентов:
notion image

Есть также дополнительный пакет, который дает возможность работать со styled-components, если так удобнее или привычнее:
notion image

В React-PDF есть поддержка кастомных шрифтов и, в целом, API для работы с ними очень удобное. Все, опять же, максимально похоже на то, что мы делаем в CSS.
notion image

Список поддерживаемых в стилях единиц измерения. Не так давно добавились vw и vh.
notion image

🔥Тред (Влад Шилов)
В рендеринге сложных PDF-ок безусловно помогает то, что React-PDF работает именно на React, так как это дает возможность использовать различные функции облегчающие процесс разработки. Например, мы используем контексты и хуки для более легкой работы с переводами и данными.
notion image

Ну и, разумеется, вы можете разделять ваш код на компоненты, оборачивать их в условия и циклы. В общем все так же, как при работе с react-dom. Это делает работу по верстке больших/динамических шаблонов на порядок легче по сравнению, например, с pdfmake.
notion image

Без ложки дёгтя конечно никуда. Давайте расскажу про минусы React-PDF и про проблемы, с которыми столкнулись в процессе работы... 👇

Блокировка потока. Ранее я говорил, что React-PDF генерит PDF-файл для простого резюме где-то за 200 ms. Это достаточно быстро, однако умолчал, что все это время браузер "висит", так как React-PDF блокирует поток.

Это дико печально, но мы разобрались с этой проблемой просто "засунув" весь браузерный код генерации PDF в вебворкер. В упрощенном варианте код воркера выглядит примерно так:
notion image

Не HTML. У нас в редакторе резюме есть поля, которые заполняются с помощью WYSIWYG и их контент хранится в базе как строка с HTML-кодом. Раньше мы просто вставляли HTML в HTML и не было никаких проблем.
notion image

Но React-PDF не знает что такое HTML. Поэтому нам пришлось дополнительно установить в приложение HTML-парсер и потратить пару недель, чтобы написать конвертер HTML-разметки в дерево компонентов React-PDF, а также сделать дополнительные компоненты для правильного рендера.
notion image

Не CSS. Хоть и похоже, но все таки это не браузерный CSS. Бывают небольшие различия в работе и в первое время они сбивают с толку. Кроме того, очень не хватает таких привычных по CSS вещей как, например, :last-child.

Размер. К сожалению, React-PDF весит очень много. Минифицированный вес рендерера больше 1 МБ (420 KB gzip). Поэтому, если вам не нужно часто обновлять превью, то советую запускать его только на сервере.

В защиту React-PDF скажу, что все JS-генераторы PDF-файлов весят много. PDFmake, например, весит еще больше. Так что выбора особо и нет. Если будете делать рендеринг в браузере, то постарайтесь вынести библиотеку в отдельный чанк и скачивать его только когда это требуется.
notion image

Поскольку это не веб-страница, а PDF-файл, то дебажить верстку сложновато. В браузерном превью вы не можете кликнуть на элемент, проинспектировать и настроить его стили. Поэтому верстка все-таки проходит немного сложнее, чем обычно.

В React-PDF есть специальный проперти debug, который подсвечивает box элемента и показывает его размер, но это, разумееется, не заменит DevTools.
notion image

Достаточно долгое время автор библиотеки работает над релизом v2 (уже вышло 14 бета версий), поэтому если вы захотите использовать React-PDF сейчас, то я затрудняюсь сказать, какую версию вам стоит использовать: v1 видимо скоро станет deprecated, а v2 еще не stable.
notion image

🔥Тред (Влад Шилов)
React-PDF у нас работает не только в браузере, но и в микросервисе. Мы собираем webpack-oм тот же самый код, импортируем его в serverless-функции и деплоим все это на Vercel. С марта 2019 микросервис делает по 300GB PDF-файлов в месяц и ни разу не "падал".
notion image

Серверный React-PDF мы используем: — как fallback для юзеров, браузер которых не поддерживает React-PDF в браузере; — для создания PDF-файлов по запросу сервера (например для отправки на почту); — для генерации картинок (например, для превью в списке всех резюме пользователя).
notion image

Вообще говоря, помимо генерации PDF, у нас еще куча всего "крутится" в микросервисах: рендер DOCX-файлов, "склейка" документов, рендер OG-картинок и рандомных аватаров, сервис для поиска опечаток в тексте и тд.

Недавно наш CTO @mlfrg делал доклад о возможностях serverless-функций и современном edge computing. Там много примеров того, как мы используем Vercel, AWS и CloudFlare Workers, чтобы решать самые различные задачи. Очень рекомендую к просмотру: youtu.be/kKfW9LLL7Rc?t=…

🔥Тред (Влад Шилов)
Кстати, тем кто предпочитает видео тексту или пропустил мои вчерашние треды: ~1,5 года назад (когда мы еще работали над внедрением React-PDF в прод) про нашу историю с рендерингом и превью PDF рассказывал @Avdyakov на конференции в Краснодаре: youtube.com/watch?v=_CFK9N…

Пятница


Окей, на GH и NPM метрик маловато, как же тогда оценить пакет не ковыряясь полдня в репозитории и не устанавливая его в свой проект? На помощь приходят такие классные сервисы и инструменты как: — bundlephobia.comnpm.anvaka.com — npm-consider
Вчера, кстати, вышел еще они инструмент для оценки качества пакетов: skypack.dev/blog/2020/10/s… twitter.com/jsunderhood/st…

Наступила пятница, а значит время немного отдохнуть от разработки! Первая тема — коллекционирование. Я, например, практикующий адепт rubber duck debugging и коллекционирую резиновых уточек. На данный момент их около 50. А вы собираете что-нибудь?
notion image
notion image
notion image
notion image

Благодаря отцу, с детства читаю много науч. фантастики и кажется, это прокачало мое воображение. Когда работаю над версткой/анимациями, могу легко представить результат и писать код по "видео" в голове. А какую художественную литературу вы читаете и повлияла ли она на работу?

Ладно, настало время задать самый важный вопрос, ради которого я пришел в jsunderhood... Чего больше вы пьете?
🤔 55.6% Чай
🤔 44.4% Кофе

Суббота


Тред-дискуссия: Работа и счастье. Последние 2 года работаю "рядовым" разработчиком в продукте и текущая работа делает меня счастливым. Однако, до этого посвятил годы тому, чтобы стать техдиром. А когда стал им, понял, что то, чего я так долго добивался не приносит радости.

Уверен, что я, как и многие, даже не задумывался зачем мне вообще карьерный рост. Это какой-то советский стереотип, который передался нам от родителей: «Ты не должен стоять у станка на заводе, а должен стать начальником цеха. Карьера и деньги — это и есть цель работы».

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

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

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

Если у кого-то, как у меня раньше, в голове сидит стереотип, что нужно обязательно стать "начальником цеха", остановитесь на секунду и подумайте, что в работе реально приносит или может приносить вам удовольствие. Стремитесь к этому, а не просто к высокой должности.

А какие цели вы глобально ставите своей работе и к чему сейчас стремитесь?

🔥Тред (Влад Шилов)

Воскресенье


Недавно мы затронули тему поиска зависимостей и я упомянул, что GitHub и NPM плохо помогают в этом. Скажите, а что вы думаете про ситуацию с нашей экосистемой в целом? Мы храним код в GitHub, который принадлежит Microsoft, и публикуем пакеты в NPM, который принадлежит GitHub.

Не пугает ли вас возможная перспектива того, что Microsoft может, если захочет, изменить вектор развития всего нашего комьюнити? Что, как вы думаете, мы можем сделать?

Слоган первого дня: «Do not choose dependencies blindly». Начну с истории, которые слушатели подкаста Веб-стандарты, от меня недавно слышали (youtu.be/ZWjfMGFITHE)...
Треды понедельника. Тема «Do not choose dependencies blindly». Вступление. История про популярный колор-пикер: twitter.com/jsunderhood/st…

Почему я вообще считаю, что надо заморачиваться на тему числа и веса зависимостей? Кто-то скажет: «10 КБ или 100 КБ — какая разница? Все равно это мало! Не мегабайт же!»
Почему нужно смотреть на размер зависимостей, примеры: twitter.com/jsunderhood/st…

Итак, пакеты которые разработаны без заботы о размере и доступности зачастую становятся очень популярны и делают веб хуже. Что же мы, как комьюнити, можем сделать? Разумеется, раз это open-source, то можем делать Pull Request-ы, чтобы улучшить эти популярные либы.
Первые шаги по улучшению существующих пакетов, настройка инструментов: twitter.com/jsunderhood/st…

Как можно сделать существующую библиотеку легче? Вариантов много, но начал бы со следующих пунктов: Удалить зависимости или заменить их на более легкие. Пример: заменить moment на date-fns (или на стандартный Date) или styled-components на какой-нибудь goober.
Как сделать существующую библиотеку легче: twitter.com/jsunderhood/st…

Если вы видите, что популярный пакет сложно сделать легче или автор не хочет принимать PR-ы на эту тему, вы можете просто попробовать найти альтернативу. Моя мысль в том, что если мы все изменим подход к подбору зависимостей, то лучшие библиотеки станут популярнее.
Меняем подход к подбору зависимостей для своих проектов: twitter.com/jsunderhood/st…

Окей, на GH и NPM метрик маловато, как же тогда оценить пакет не ковыряясь полдня в репозитории и не устанавливая его в свой проект? На помощь приходят такие классные сервисы и инструменты как: — bundlephobia.comnpm.anvaka.com — npm-consider
Полезные инструменты и сервисы для оценки качества пакетов: twitter.com/jsunderhood/st…

Если вы ищете пакеты на сайте NPM, то попробуйте npms.io — их поиск IMHO работает лучше. Разница в выдаче выглядит странно, учитывая тот факт, что на npmjs.com написано об использовании движка от npms.io: docs.npmjs.com/searching-for-… pic.twitter.com/g6FbjgMW1P
Поиск NPM сломан? Альтернатива: twitter.com/jsunderhood/st…

Резюмирую недавние треды: хотел бы попросить вас внимательней подходить к подбору зависимостей, и изменить привычный флоу, например, на такой: npms.io → NPM/GitHub → bundlephobia.comnpm.anvaka.com
Заключение: twitter.com/jsunderhood/st…

🔥Тред (Влад Шилов)
👋 Для тех кто пропутил контент, который был в начале недели, или хочет сохранить эту информацию в более структурированном виде, я сегодня опубликую 5 тредов, в которых будут сгруппированы все публикации добавленные мной в будние дни.

День второй: «Micro-libraries» Что я подразумеваю под этим понятием? Для меня лично, микро-библиотека — это средство решающее какую-либо задачу, сохраняя при этом близкий к минимальному размер бандла.
Треды вторника. Тема: «Микро-библиотеки». Вступление: twitter.com/jsunderhood/st…

Недавно мы с коллегами из resume.io отдыхали в дачном поселке в Тульской области, всего в 2 часах от Москвы, и были дни когда нам был доступен только слабенький 3G. После такого опыта я еще больше убедился, что нужно делать пакеты легче и каждый килобайт важен.
Почему важно следить за размером бандла: twitter.com/jsunderhood/st…

Давайте наконец перейдем к тому, как разрабатывать микро-библиотеки. Если вы нашли какую-то проблему или сферу для которой вы можете создать новое lightweight-решение, то не рекомендую сразу писать код, — начните с формирования целей и ограничений. 👇
Перед началом разработки микро-библиотеки нужно сформировать цели и ограничения: twitter.com/jsunderhood/st…

Как добиться того, чтобы вес библиотеки был небольшим? Многое, конечно, зависит от задачи, но первым универсальным пунктом я бы выделил "Не использовать зависимости пока это возможно". 👇
Делаем легкую библиотеку 1/3. Про зависимости: twitter.com/jsunderhood/st…

Также, если избегать вещей, которые плохо минифицируются, требуют полифиллов или трансформация кода, то можно заметно снизить вес вашей библиотеки после сборки. Примеры: 👇
Делаем легкую библиотеку 2/3. Про полифиллы и трансформации кода: twitter.com/jsunderhood/st…

Если рассматривать различные микро-оптимизации веса бандла, то выделил бы следующие: Помимо классов, по возможности лучше не использовать и объекты, так как названия ключей в них обычно не минифицируются, а если используете, старайтесь делать ключи покороче. 👇
Делаем легкую библиотеку 3/3. Микро-оптимизации: twitter.com/jsunderhood/st…

Коротко о продвижения микро-библиотек. Сразу скажу, что я не особо известный разработчик. Летом у меня было всего 200 подписчиков, но за пару месяцев получилось пропиарить библиотеку так, что меня позвали и в подкаст Веб-стандарты, и в jsunderhood. 👇
Продвижение микро-библиотек 1/2. Основы: twitter.com/jsunderhood/st…

Чтобы разработчики начали использовать ваш пакет в продакшене, информация о вашей либе должна внушать им уверенность. Обычно, люди видят, что у пакета много скачиваний и им этого достаточно, но у новой библиотеки им взяться неоткуда. Проблема курицы и яйца. 👇 pic.twitter.com/yRGi2M1XFa
Продвижение микро-библиотек 2/2. Формируем доверие: twitter.com/jsunderhood/st…

🔥Тред (Влад Шилов)
Ключевой частью resume.io является конструктор, в котором пользователи создают резюме, чтобы потом скачать его в виде PDF и отправить потенциальному работодателю. Рендеринг и live-превью PDF — это, наверное, один из самых больших челленджей, которые мы решали. 👇 pic.twitter.com/WRZ8YE90kp
Треды среды. Тема: «Как мы делали рендер и live-превью PDF на основе HTML+CSS, но проиграли». Вступление: twitter.com/jsunderhood/st…

В 2016 году, когда велась работа над MVP нашего продукта, ребятам был нужен быстрый и легкий способ внедрить генерацию PDF, при этом не вводя другие технологии, языки и т.д. 👇
2016 год. Рендер PDF на Qt Webkit: twitter.com/jsunderhood/st…

В 2017 мы выпустили следующую версию редактора, в которой, поскольку этого явно не хватало, была добавлена возможность предпросмотра резюме до его скачивания. 👇 pic.twitter.com/FbU97TREYi
2017 год. Превью в iframe или открытие Ящика Пандоры: twitter.com/jsunderhood/st…

Большая часть проблем, которые в 2017 году были у нас в рендеринге PDF из HTML+CSS, были вызваны тем, что Wicked PDF использовал Qt Webkit, который работал с устаревшей на несколько лет версией движка Webkit. 👇
2017 год. Переход на Puppeteer: twitter.com/jsunderhood/st…

В 2018 году, собрав фидбек от пользователей, мы поняли, что отображения превью на отдельном шаге недостаточно. Пользователи хотели видеть: — как меняется резюме прямо в процессе редактирования; — как их контент помещается на А4-страницы в PDF. 👇
2018 год. Добавление live-превью и появление новых проблем: twitter.com/jsunderhood/st…

Резюмирую сегодняшнюю информацию: Вы можете генерировать PDF-файлы на основе HTML+CSS если ваше приложение не показывает live-превью будущей PDF-ки и не важно, как контент разделится на страницы. То есть для задач, вроде отправки чеков или билетов по почте, это подходит отлично.

Раз уж мы сегодня погружаемся в прошлое, как на счет немного удариться в ностальгию? Давайте поделимся друг с другом скриншотами/ссылками на наши старые проекты или историями про них. Я нашел сайты, которые делал еще в 2007—2009 годах. Вот это дизайн раньше был! =) pic.twitter.com/LZWr1qR9eb
Бонус. Вечер ностальгии: twitter.com/jsunderhood/st…

🔥Тред (Влад Шилов)
Продолжаю историю про PDF: Наступил 2018, у нас стало 1,8 млн юзеров и наш support был завален письмами от пользователей о том, что они заполнили резюме, глядя на превью, а потом скачали PDF, в котором контент по-другому "влезал" на страницы А4 и вообще число страниц другое. 👇 pic.twitter.com/hK2s1Ybrxh
Треды четверга. Тема: «Используем JS для рендеринга и live-превью PDF». Про проблемы с Puppeteer и большинством JS-библиотек для генерации PDF: twitter.com/jsunderhood/st…

PDFkit, PDFmake и jsPDF не подошли, так что мы решили потестировать проект React-PDF, за которым уже некоторое время наблюдали. По аналогии как, например, React-Native является рендерером для мобильных приложений, так React-PDF — react-рендерер для PDF. react-pdf.org pic.twitter.com/6B7a6qviAC
React-PDF. Краткий обзор: twitter.com/jsunderhood/st…

React-PDF хорош тем, что упрощает верстку сложных PDF-файлов, делая его максимально похожим на верстку HTML-страниц c использованием React. Только вместо HTML-тэгов вы используете компоненты, которые предоставляет сам React-PDF. Например, View вместо div и Text вместо span. pic.twitter.com/noE3Yj0Bbs
React-PDF. Что тут вместо HTML-тэгов. Как работает разделение на стрнаницы: twitter.com/jsunderhood/st…

В рендеринге сложных PDF-ок безусловно помогает то, что React-PDF работает именно на React, так как это дает возможность использовать различные функции облегчающие процесс разработки. Например, мы используем контексты и хуки для более легкой работы с переводами и данными. pic.twitter.com/W9xJly9bMV
React-PDF. Нужен ли тут вообще React: twitter.com/jsunderhood/st…

Хотя рендеринг в React-PDF, по сути, не имеет отношения к вебу и браузерам, стилизация там делается с помощью CSS, а значит учить отдельно ничего не надо. Причем поддерживается много свойств и, в целом, все работает почти так же, как в браузере. react-pdf.org/styling pic.twitter.com/uriwsub70E
React-PDF. Стилизация компонентов с помощью CSS: twitter.com/jsunderhood/st…

Без ложки дёгтя конечно никуда. Давайте расскажу про минусы React-PDF и про проблемы, с которыми столкнулись в процессе работы... 👇
React-PDF. Минусы: twitter.com/jsunderhood/st…

React-PDF у нас работает не только в браузере, но и в микросервисе. Мы собираем webpack-oм тот же самый код, импортируем его в serverless-функции и деплоим все это на Vercel. С марта 2019 микросервис делает по 300GB PDF-файлов в месяц и ни разу не "падал". pic.twitter.com/84cdgL9vKl
Серверный рендеринг: twitter.com/jsunderhood/st…

🔥Тред (Влад Шилов)
Наступила пятница, а значит время немного отдохнуть от разработки! Первая тема — коллекционирование. Я, например, практикующий адепт rubber duck debugging и коллекционирую резиновых уточек. На данный момент их около 50. А вы собираете что-нибудь? pic.twitter.com/V6ijap66CF
Треды пятницы. Тема: «undefined» Коллекционирование: twitter.com/jsunderhood/st…

Благодаря отцу, с детства читаю много науч. фантастики и кажется, это прокачало мое воображение. Когда работаю над версткой/анимациями, могу легко представить результат и писать код по "видео" в голове. А какую художественную литературу вы читаете и повлияла ли она на работу?
Художественная литература и работа: twitter.com/jsunderhood/st…

Ладно, настало время задать самый важный вопрос, ради которого я пришел в jsunderhood... Чего больше вы пьете?
Ответ на главный вопрос жизни, вселенной и всего такого: twitter.com/jsunderhood/st…

Вот и подошла к концу моя неделя в jsunderhood. Спасибо, что читали и комментировали! Надеюсь, было интересно и вы узнали что-то полезное. Если нужен будет совет как сделать open-source библиотеку легче или "приготовить" PDF для вашего проекта, я (@Omgovich) буду рад помочь ❤️

Подписывайтесь, чтобы оставаться на связи 👋 GitHub: github.com/omgovich Twitter и Telegram: @Omgovich

Ссылки