Валя читает ишью
СтатистикаДелюсь интересными ишьюсами и пул-реквестами в мире фронтенда и около github.com/7rulnik twitter.com/7rulnik
- Последний пост
- 12 июн.
- Последнее чтение
- 20:45
- Постов за неделю
- 0
- Всего постов
- 20
- Тип
- открытый
- Язык
- русский
- Категория
- Технологии (по похожим)
- В каталоге с
- 13 авг.
- 1/24сутки в ленте
- —
- 1/48двое суток
- —
- 1/72трое суток
- —
Оценка по просмотрам недавних постов: пост набирает почти всё за первые сутки.
Посты
Diff: You should be able to just render any diff А пока гитхаб не вывозит как с точки зрения аптайма так и интферйса, разработка продолжает меняться. Кода становится больше, его надо (хотя опыт bun показывает, что может быть и не надо…) ревьювить . И вот появляется diffshub.com, который демонстрирует что если тебе не наплевать, то в браузере можно рендерить любые пул-реквесты (ну, например, дифф на 37 миллионов строк). И при этом не делать ограничения на 40 комментариев по 20 реплаев в каждом. Ну какой же всё таки позор… Я даже представить не могу каким образом в гитхабе пришли к таким лимитам. Да, конечно, с нуля делать всегда проще, но напомню, новый дифф гитхаба находится в эксперименте 1.5 года! Прочитайте статью о том, как всё устроено ON RENDERING DIFFS. Ну и главное — примитивы для диффов полностью опенсорсные github.com/pierrecomputer/pierre UPD: Можете ещё глянуть подскат с авторами https://www.youtube.com/watch?v=5He3_Lin5gE
Diff: The uphill climb of making diff lines performant Пару лет назад я уже пинал GitHub за то, что основная, казалось бы, фича продукта работает ужасно медленно. И вот, в очередной раз я сделал пул-реквест на 1400 файлов (+2000/-172 строк). Ну и хотелось бы дифф посмотреть. А знаете (к сожалению, скорей всего знаете) сколько секунд браузер думает когда я просто файлики сворачиваю в сайдбаре на странице пул-реквеста? 3 секунды! Сам браузер при этом просто намертво зависает. Про плейсхолдеры с «load diff» я даже говорить ничего не буду… Ну да ладно, в гитхабе осознают проблему и вот уже полтора (!) года существует НОВЫЙ ЭКСПЕРИМЕНТАЛЬНЫЙ дифф! Можно включить у себя в профиле в экспериментах, что я примерно год назад и сделал. И в сравнении со старым изменения, конечно, есть. А в апреле в официальном блоге гитхаба вышла даже гордая статья The uphill climb of making diff lines performant. Ну всё, проблема решена! Ведь решена же, да? Во-первых, фичу выкатывали постепенно, через эксперимент. И первоначальный лимит был в 300 файлов на пул-реквест. Казалось бы, 300 файлов — много! Но только вот стандартный лимит 1000! Т.е. вы там сидели, улучшали и такие «ну давай раскатим на юзеров, но только сделаем ХУЖЕ». Спустя 4 месяца лимит подняли (ну или вернули) до 1000. И ещё через 2 месяца подняли до 3000! Вот уж «new experience is being built to scale», спасибо. А во-вторых, ну, получилось всё равно плохо… Как минимум в том же VS Code всё работает всё равно быстрее. Ну и кто бы мог подумать, что если уменьшить количество дом-нод и добавить виртуальный список, то станет полегче? Мне теперь даже показывают контент файла — нужно всего лишь подождать секунду пока прогрузится. Вот уж действительно performant™. В комментарии придёт кто-то умный и скажет 1400 файлов! Вон из профессии, позорник! Декомпозируй! Но простите, что мне декомпоизировать то? 2000 строк? Если интересно, можете дискуссию на гитхабе поглазеть. Хотя даже не знаю что там может быть интересного. Каких либо апдейтов нет уже полгода.
Vite выходит из Vitest В Vitest появилась крайне интересная дискуссия — а что если разделить разделить билдер и тест-раннер? Тем самым позволив людям использовать не Vite, а их любимый бандлер (или не использовать совсем), указывая его через —framework. В целом подход очень похож на то, что делает Storybook: там можно комбинировать рендерер/фреймоврк и различные бандлеры. Меня эта дискуссия очень заинтересовала, т.к. у нас БОЛЬШИЕ проблемы с Vitest. Прямо сейчас у нас 8600 тестов в 1400 тест-файлах бегают (ну как бегают, скорее хромают) в 4 шардах за 8 минут. При этом весь пайплайн проходит за 12 минут. И, кажется, основная проблема — Vite.
Port of React Compiler to Rust Пока что WIP в виде альтернативного плагина для Babel и crates для OXC и SWC. Проходят почти все тесты (кроме одного) — 1717/1718 Ну и куда уж без Claude… https://github.com/facebook/react/pull/36173 P.S. Если вы уже используете у себя React Comipler — поделитесь фидбеком в комментариях пожалуйста!
Evolving the Node.js Release Schedule Node.js давно загнала себя в странное состояние — чётные релизы становились LTS с поддержкой в 3 года, а нечётные имели очень короткий срок жизни — 9 месяцев. Нечётные релизы помогали команде быстрее итерироваться, мёрджить экспериментальные фичи. Но в конечном счёте все эти фичи всегда попадали и в чётные релизы. Возможно из-за этого нечётные релизы прославились «нестабильными». Мне кажется они никогда такими не являлись и если явно указывать версию nodejs через .nvmrc (а я считаю что нужно это делать в любом проекте, даже если вы работаете над ним один), то это помогало избежать проблем. Но из-за ощущения «нестабильности» и короткой жизни релиза нечётные релизы не пользовались популярностью — все использовали чётные версии. Здесь возникает логичный вопрос. У вас есть «экспериментальные» релизы, фичи из которых хочется протестировать на реальных людях, собрать фидбек, поправить баги и уже после этого спокойно слить в LTS версию. Как всё это делать, если пользователей толком нет? C октября 2026 года всё поменяется: 1. Один мажорный релиз каждый апрель 2. Релиз становится LTS в октябре 3. Появятся альфа-версии для изменений, ломающих обратную совместимость 4. Версия ноды совпадает с годом релиза (26 в 2026, 27 в 2027 — привет Apple) Очень правильный шаг, который позволит в том числе и снизить нагрузку на релизеров ноды. Подробнее тут https://nodejs.org/en/blog/announcements/evolving-the-nodejs-release-schedule Ну и если вам интересно как принималось решение: https://github.com/nodejs/Release/issues/1113 https://github.com/nodejs/nodejs.org/pull/8631
Oxfmt достиг паритета c prettier Пару лет назад автор prettier запускал челлендж — $10 000 тому, кто напишет альтернативу на rust. Денег тогда удалось собрать сильно больше, а $20 000 присудили Biome. С тех пор Biome так и не достиг полного паритета в целом исходя из идеи, что в prettier не всё работает правильно. И вот пару-тройку часов назад oxc как раз таки достиг (для JS и TS). При этом все инконсистености отрепортили в сам prettier — это примерно 30 кейсов. Что касается производительности, на нашем проекте получилось вот так: prettier — 25s prettier --experimental-cli — 6s prettier --experimental-cli + prettier/plugin-oxc — 4s oxfmt --trhead=1 — 5s oxfmt — 3s biome — 2s Спустя годы становится очевидно, что челлендж был не зря. Prettier, написаный на JS, получил экспериментальный CLI, который практически не уступает альтернативам на расте (а с кешем так и в целом может быть быстрее). Интересно как проекты будут сосуществовать. Кто законодатель моды? Преттиер или же всё же более быстрые альтернативы? К слову, у prettier 69 миллионов установок в неделю, у biome 5 миллионов, а у oxfmt 900 тысяч. P.S. Цитата Кристофера (автор преттиера): «I strongly believe that having the two projects align on a single formatting is going to be the best possible outcome for the JavaScript space!». Two… Not three…
yarn 6: теперь на rust Полчаса назад вышел анонс новой версии yarn. Переписывают с нуля на раст и планируют закончить через 6-8 месяцев. Не можешь победить pnpm — перепиши на rust Анонс https://yarn6.netlify.app/blog/2026-01-28-yarn-6-preview/ Репозиторий https://github.com/yarnpkg/zpm
Валя больше не читает ишью Well, полгода (рекорд однако!) без постов. Пожалуй, хочется объяснить, что же произошло. Если смотреть поверхностно, то всё просто: я утратил интерес не столько к формату, сколько к лайфстайлу «программирование — это хобби» и перестал в первую очередь маниакально мониторить ишью и пул-реквесты на гитхабе и в твиттере. Сгорел я где-то между очередным обсуждением о выпиливании corepack из ноды и фокусов ljharb с поддержкой той самой ноды, которая вышла 13 лет назад. Даже не столько сгорел, сколько разочаровался в текущем состоянии индустрии. Это правда самые важные вопросы, которые комьюнити должно решать и к чему должны быть прикованы наши взгляды? Ну а перестав читать такой контент, оказалось и не о чем писать. Вполне закономерный итог. Но всё же, пожалуй, вопрос чуть более экзистенциальный. Звучит примерно так: «а кому и для чего нужен этот канал?». Изначально мне просто нравилось структурировать свои мысли о происходящем, рассказывать вам о нюансах, расширять границы и кругозор. И это, пожалуй, получилось. И даже получилось достичь какого-то признания — 3700 подписчиков в пике (за последние полгода сотня куда-то разбежалась, бывает). Более того, 5 лет назад такой контент был по-своему уникальным — не было такого количества авторских каналов о фронтенде и JS в целом, как сейчас. Возможно, здесь я присваиваю себе какие-то несуществующие достижения, но чувствую, что было приятно находить и осозновать себя в начале этой волны. Было интересно конкурировать и развивать комьюнити. Вместе с конкуренцией было интересно и предоставлять трибуну для менее популярных авторов. Но в определенный момент стало сложно этой самой конкуренцией заниматься. Ради многих постов приходилось ложиться спать позже или откладывать важные дела. Хотелось написать первым, выиграть этот спорт и забрать свою порцию внимания и просмотров. И это тоже у меня прекрасно получалось. Более того, главное метрикой для меня всегда были просмотры, а не подписчики. И почти под каждым постом первого больше, чем второго. Так далеко не у всех. Я не особо часто рефлексировал зачем мне нужен этот канал в принципе. Логично, что за 5 лет цели могли поменяться. Я предпринимал несколько четных (и, видимо, наивных) попыток хоть как-то монетизировать всю эту историю. Основной же платой всегда была медийность — рост количество подписчиков и моей узнаваемости. Но что с этой популярностью делать? Быть может, в какой-нибудь яндекс возьмут без собеседования (хаха)? Вывод простой — моя медийность не сильно поможет моей карьере, а если и поможет, то карьере только в пределах России. Но даже это сомнительная (лично для меня) награда, потому что кратно, ну хотя бы в 1.5 раза больше (а именно это как-то существенно может повлиять на мой образ жизни), денег российские компании просто не дадут. А если и дадут, то скорей всего с бонусами вида «удалёнка только внутри РФ». По крайней мере так я вижу рынок сейчас. А как делая то, что я делаю, выйти на англоязычную аудиторию, за эти 5 лет я так и не придумал. Вот так и получается, что продолжая канал в том виде, в котором он есть, я преследую странные и неактуальные для себя цели, жертвуя временем и энергией. В текущий момент в моей жизни есть более интересные и важные вещи . Но, конечно же, я не буду писать что-то в духе «канал закрывается, всем спасибо». Мне всё ещё хочется делиться своим собственным уникальным опытом. Это и интереснее лично для меня, и менее энергозатратно, т.к. не нужно переваривать чужой контент, и, кажется, более ценным для комьюнити. Новый сезон, получается. Посмотрим что из этого выйдет.
Уже завтра состоится наш Дринкап! 🍺 — Когда: завтра, 23.07, начало в 20:00 (но можно подходить в 19:00) — Где: Бар Union, Литейный пр., 55 — Вход: бесплатный А пока делимся с вами расписанием: 20:00 — Приветствие 20:10 — Алексей Хлебаев: Побеждаем выгорание за 10 минут 20:25 — перерыв 20:35 — Антон Ленев: We need to go deeper - куда нас привела дорога WYSIWYG 20:50 — перерыв 21:20 — Андрей Соколов: Как мы делали стартап 21:35 — перерыв 21:45 — Тимур Гафиулин: Мечта любого айтишника или как я год не работал Ждем вас! 🍻
Если вы вдруг в Питере, то приходите во вторник (23 июля) в Юнион на дринкап SPB Frontend! Это дорогой моему сердцу митап (ну, в этот раз дринкап), с которого я начал карьеру публичных выступлений в самом любимом баре на свете. В общем, буду завтра там сам, приходите и вы! :*
ljharb Ситуация с ljharb продолжает быть веселее и веселее. Это тот чувак, который решил в доку свелта добавить поддержку ноды 0.4. Вчера я пытался в очередной раз апнуть наш проект до eslint 9 и увидел, что eslint-plugin-import принадлежит как раз этому челобеку. Следовательно, по классике, этот плагин поддерживает eslint 2, node 4 и прочую некрофилию. А так же чувак попросту не добавляет поддержку flat config и eslint 9. И вот история в том, что игнор идёт уже больше года. В итоге появляется eslint-plugin-import-x: https://www.npmjs.com/package/eslint-plugin-import-x, который поддерживает только eslint 8/9, не имеет кучи говнозависимостей и пока поддерживается новым ментейнером. Другая история происходит прямо сейчас про библиотеку traverse. Как легко догадаться, туда тоже пришёл ljharb. В итоге ша маемо, то маемо. Но благо, благодаря этому появилась библиотека neotraverse: https://www.npmjs.com/package/neotraverse, которая является форком оригинальной, но без всей этой дичи от нашего поциента. В итоге, если хотите получить популярный проект, то алгоритм чуток прост: 1. Смотришь, в какой очередной утилитарный проект пришел ljharb и навернул секурности 2. Делаешь форк от прошлой версии без зависимостей, обзываешь neo/nano/x-оригинальное имя и публикуешь 3. Профит, благодарные юзеры благодарны на ровном месте, репутация локального спасителя экосистемы Так шо велком, заработать лычку на популярной библиотеке сейчас как никогда просто.
Как я положил продакшен базу на выходных Вчера произошла эпическая история. После планового деплоя в субботу вечером (так было нужно), мне прилетело сообщение “кирилл, у нас почему-то не показываются заявки”. Наверное фильтры слетели, подумал я и пошел проверять. Фильтры не слетели. Я слегка напрягся и пошел в яндекс клауд посмотреть что там в базе. Как я и боялся, таблицы были пустыми. Причем не все, но многие. Самое интересное, что они были не просто пустыми, но у них сбросились счетчики. Увидел я это не сразу после деплоя, поэтому было не до конца понятно, это деплой привел к удалению данных или что-то другое. Я быстро восстановил снепшот на новом кластере, благо это делается одним кликом и выполнил туда деплой заново. Какого было мое удивление, когда после деплоя база очистилась. Какого хрена подумал я, прикидывая, что могло быть причиной. В этот момент ко мне присоединился второй разработчик проекта, с которым мы весело провели 3 часа за дебагом. Сам деплой был необычным, потому что мы выкатывали большое изменение для обработки заявок основного договора (до этого работало только раннее бронирование). Туда входило и много кода и около 40 миграций и обновления зависимостей и новая конфигурация. Но мы точно не добавляли код, который бы грохал половину базы (как нам тогда казалось, хаха). Дальше мы полезли изучать код на предмет подозрительных вещей: 1. Логи 2. Изменения в конфигурации 3. Ишьюсы в Laravel (основной фреймворк) 4. Миграции Ничего подозрительного не нашли, за исключением пары транкейтов в паре миграций. Но эти трункейты были на новые таблицы, в которых точно не было данных, их скорее делали даже для локального сброса, чтобы не фиксить данные в девелоперских базах после изменения структуры таблицы. В любом случае мы решили проверить миграции, поэтому сделали следующее. Настроили систему так, чтобы за один деплой выполнялась ровно одна миграция. Дальше мы начали выполнять последовательно деплои, попутно проверяя состояние базы в конце каждого деплоя. И, вдруг, где-то на двадцатой миграции база очистилась. Открываем миграцию, а там тот самый пресловутый транкейт, который хоть и выглядел подозрительно, но не касался других таблиц. Смотрю в логи и вижу что транкейт выполняется так: TRUNCATE marketing_discounts CASCADE. И тут я как понял. Не знаю как так получилось, но я даже не был в курсе, что у трункейта есть такая опция. CASCADE приводит к тому, что дропаются все связанные таблицы (рекурсивно) независимо от того, есть ли там данные или нет. Сказать что я был в шоке, ничего не сказать. Тут же нашелся issues в ларавеле, где выяснилось несколько интересных деталей. Мы не единственные кто грохнул базу таким образом. Собственно сам issue появился с целью того, чтобы защитить всех остальных, на что разработчики сказали сорян, обратная совместимость. Самое смешное, что подобное поведение реализовано только для драйвера постгреса, у остальных такого нет. When you truncate tables using the laravel illuminate db builder it truncates the table as expected. However, postgresql is different because it changes the DEFAULT behavior of truncate from RESTRICT to CASCADE. This means that you can loose all your data in other "related" tables (something that doesn't happen with the other sql drivers) И ниже смешные комментарии в духе: 3 years passed, Laravel users still truncates their entire databases... We were also a victim of this behavior this morning, fortunately we were on a test database. Very dangerous! Ишью кстати закрыли с поинтами что мы не будем ломать обратную совместимость и транкейт должен сбрасывать данные, а не падать с ошибкой. В итоге мы все поправили и восстановили данные, но открыли в себе новый страх. Давно в моей жизни не было таких приключений) ишью: https://github.com/laravel/framework/issues/35157
axobject-query: maximize back compat 3 дня назад Jordan Harband потряс всё JS комьюнити своим пул-реквестом в проект axobject-query с названием «maximize back compat». 210 дизлайков, ни одного лайка, бесконечное количество критики… Давайте сперва про Джордана — это очень известный человек в комьюнити, работал в твиттере, коинбейзе, эирбнб. Участник TC39, контрибьютил в еслинт, бабель, ноду, опубликовал 513 пакетов в npm. Теперь про сам axobject-query — я, честно говоря, не знаком с AXObject (и если ещё более честно, то и знакомиться особо не хочу), какая-то низкоуровневая штука для работы с доступностью в общем. Интересно кто этим пакетом пользуется — eslint-plugin-jsx-a11y (пакет Джордана), svelte, astro. Короче, короче, большие и уважаемые проекты. А теперь давайте про пул-реквест — под названием «maximize back compat» скрывается поддержка ноды v0.4. Знаете когда он вышла? 12 февраля 2011 (!!!) года! Я даже не успел её застать, кажется моя первая версия была 0.8 или 0.9 Поддержка достигается за счёт смены jest на tape, который написал Джордан. А так же замены dequal на deep-equal-json т.к. первый требует ноду старше v6. А кто является автором deep-equal-json сами догадаетесь. deep-equal-json как минимум ругают за то, что он тянет 17 зависимостей, в то время как dequal ни одной. Это критично для svelte, т.к. у них есть REPL и юзеры будут загружать эти пакеты в том числе и в браузере. В ответ на критику Джордан занимает очень оборонителньую позицию. Например, его спрашивают «а как ты стал мэйнтейнером этого пакета? Как мы видим, это твой пул-реквест в этот проект. Понятно, что ты уважаемый человек с большой историей контрибьюшенов, но ответь пожалуйста на этот простой вопрос» или «замотивирован ли ты внедрять свои пакеты т.к. можешь получать отчисления от tidelift». В ответ Джордан либо не отвечает либо делает это очень уклончиво. Интересно, что в описании пул-реквеста указано «It also expands the test matrix so that all supported engines are tested, now and moving forward.», но на деле в CI указано >= 0.8, а в engines 0.4… Кажется уж,если решил быть таким педантичным, то надо идти до конца… В общем, рекомендую почитать комментарии в пул-реквесте. Там правда очень уважаемые люди. А на самого Джордана свалилось много как конструктивной критики, так и булинга. Хоть я и осуждаю такое, но природа этого понятна. Уж очень экстравагантное решение получилось. P.S. once JS drama — always JS drama…
Кыргызы против Intl.NumberFormat Когда лучшее враг хорошего. Недавно к нам в команду web platform в aviasales пришли из техподдержки со странным багом у пользователя: в Arc браузере сломано отображение символа валюты кыргызских сомов, вместо него выводится непонятный символ. Проще всего конечно было ответить, что браузер не поддерживается, но стоп, разве арк не на хромиуме, чем он такой особенный? Начал разбираться Действительно, в обычном хроме сомы показываются как KGS, а в арке как символ, и символ явно ошибочный. Для отображения валют мы используем стандартный Intl.NumberFormat и в арке он действительно выдаёт другой символ. Начало проясняться. Возможно, арк использует новую версию хромиума и поэтому показал проблемы раньше? И действительно, Chrome Canary получил точно такой же баг. Получается, совсем скоро, валюта сломается у всех, вообще у всех сайтов и пользователей страны, и отсчёт времени уже пошёл 🫠 Куда отправлять баг? У хромиума есть свой баг трекер, но работа с ним оставляет желать лучшего, выглядит он мягко говоря антично. Никогда не заполнял баги для браузера, но видимо этот час настал. В процессе подготовки репорта вспомнил, что вообще говоря, локализациями занимается не хромиум а отдельная библиотека ICU, то есть проблема ещё глубже, чем просто баг браузерного движка. А, казалось бы, невинная проблема Описываю свои приключения коллегам, один замечает, что это первый раз, когда мы нашли баг не в самом лучшем браузере safari а в хроме, теперь счёт багов 4:1 в пользу первого. А действительно, а как себя ведёт в таких условиях сафари? Открываю. Встречаю тот же баг 🫡 Очевидно, проблема на уровне операционной системы. Решил присмотреться к символу внимательнее, это просто мусорный вывод или он имеет какую-то семантику? Символ который выдаётся на macos выглядит так: ⃀, если вы читаете с macos то почти наверняка ничего не увидите (в первом комментарии скриншот как это рендерилось в реальности). В базах данных по юникоду описание: Unicode Character 'SOM SIGN'. Бинго. Это не баг, это настоящий символ валюты, но в стандартных шрифтах macos его нет, на windows всё отображается нормально В итоге получается ситуация: раньше вместо символа валюты выдавалась аббревиатура, библиотека ICU исправила эту проблему чем ухудшила вывод на девайсах apple Это многое говорит о нашем обществе Issue в багтрекере хрома или ICU открывать не стал. Очевидно они всё сделали правильно; парадоксальная ситуация в которой никто толком не виноват. Ну, точнее, можно конечно попинать apple чтобы добавляли символ, но это всё равно что орать на баобаб Оценив диспозицию, решил что надёжнее всего будет просто сделать .replace для проблемного символа на старый вариант. Мимоходом заметил, что в некоторых других условиях у нас на сайте кыргызская валюта отображается нормально. Оказалось, что вместо официального символа используется юникод-комбинация c + нижнее подчеркивание под символом: c̲. Как говорится c̲мекалочка ок. Но чтобы я не сильно радовался, оказалось, что в том самом стандартном шрифте apple этот символ тоже отображается криво, проще заменить обратно на KGS, как это было раньше и всех устраивало Когда я заходил на эту пятничную задачу последнее чего я ожидал это изучения багтрекера браузеров. А вот проблемы с apple наоборот вполне были в рамках! Разумеется это ценно, что у движка chromium есть конкурент который не живёт на пособиях гугла, но нельзя не признать, что девайсы apple и веб разработка это головная боль. Всегда. Пока писался этот пост, «улучшающий» апдейт хрома был раскатан на всех пользователей. Кыргызский интернет оказался уже сломан, сломан для всех
Мой тиммейт Дима (а заодно и автор effector) на днях тоже с веселой детективной историей столкнулся
Стажировка в Авиасейлс У нас открывается набор на летнюю стажировку! 2 месяца по 500 баксов, 4-6 часов в день, ремоут, все дела Фронтенд, go, iOS, юристы, редакторы, дизайнеры, маркетинг — в общем есть всё! Аплайтесь через сайт, можете указать что вакансию в канале увидели https://aviasales.ru/about/vacancies
React Compiler доступен для пользователей https://react.dev/learn/react-compiler Если вперые слышите об этом, то взгляните на пост про React Forget (предыдущее название) Исходный код вот тут
Не смотря на то, что профилирование JavaScript является мощным инструментом, мне всегда не хватало возможностей инструментов. Так что последние годы я почти перестал пользоваться этим методом. Для меня это просто не работало: для небольших скриптов – слишком мало деталей, для долго работающих (например, сборка webpack или выполнение unit-тестов) – сплошная каша. Оказывалось, что инструментирование с помощью console.log() работает куда эффективнее, чем ковыряние в CPU профилях. В тоже время, мне казалось это неправильным. 2,5 года назад, очередной раз разбираясь в тормозящей webpack сборке, и делая аналитику что и как работает, представил как это могло бы выглядеть в инструментах. Пришла идея кластеризации функций по модулям, пакетам, категориям. Это казалось очевидным решением, странно, что никто еще не сделал. "Если никто не сделал, наверное это не будет работать" – думал я тогда. Но "не попробуешь не узнаешь", и решил попробовать реализовать – вдруг заработает. Сначала я начал разбираться с тем как устроен формат ".cpuprofile". Было ничего непонятно, и казалось очень сложным. Но на деле вышло, что ничего сложного в этом нет, сложно только разобраться. Сложность в том, что материалов про то как устроен формат и про логику его работы, и вообще профилирование с точки зрения аналитики, обнаружить не удалось. Обычно ограничиваются базовыми туториалами по профилированию. Информацию приходилось собирать по крупицам: по ишуям, по комментариям, по коду v8 и т.д. И еще много экспериментировать. Как бы то ни было, получилось собрать прототип кластеризации. И это на удивление хорошо заработало. Правда с кластеризацией появились новые проблемы: как считать разные агрегации, делать это быстро и под разными углами, и на больших масштабах. Информации по этому поводу было бы странно найти, так как никто кластеризацию толком и не делал. Но тем не менее основа была заложена, так появился проект под названием CPUpro – мое переосмысление того, какими должны быть инструменты анализа CPU профилей. Время от времени я понемногу допиливал CPUpro, продолжал экспериментировать. А некоторое время назад пришло озарение, на фоне размышлении о том, как сделать сравнение профилей "до" и "после" без сопоставления двух флеймчартов глазками. Сравнение профилей пока не реализовано, но многое для этого уже сделано (высокая производительность, низкое потребление памяти), и вообще стало получаться что-то приличное. Теперь я ковыряюсь в CPU профилях каждый день, и все больше коллег делают тоже самое. В общем, инструмент приобрел состояние, когда его не стыдно показать 🙂 Еще много что предстоит сделать, но он полезен уже сейчас, нам уже не раз помог в работе. Особенно если нужно проанализировать профайл на десятки или сотни мегабайт. Release notes (там больше деталей, бенчмарки и скриншоты) Твит анонса (спасибо за лайк, ретвит) CPUpro (GitHub)
cpupro — лучший cpu профайлер Не так давно я искал узкие места в витесте и вебпаке и внезапно наткнулся на cpupro. Когда я увидел, кто автор, то понял что инструмент плохим быть не может в принципе: Рома Дворнов — знак качества! Традиционно, это самый быстрый аналайзер из существующих, способный переваривать огромные (2гб) профайлы. Ну и по функциональности он впереди всех существуюших профайлеров — куча разных вьюшек, сортировки по пакетам/функциям и так далее. В общем, очень рекомендую! https://github.com/lahmatiy/cpupro/releases/tag/v0.5.0
Vitest: invalid JSON syntax found at position -1. Алло, это канал о витесте? Ну а если серьёзно, то пожалуй столкнулся с одним из самых интересных багов в своей жизни. Я уже рассказывал, что витест для нас компромиссный опыт и породил экстравагантные практикие в духе «гоняем 100 пайплайнов и проверяем, что не флакает». В общем, задумал я обновить его немного, открыл пул-реквест, погонял те самые 100 пайплайнов — всё зеленое! Мёрджим! Проходит 2 недели и 60% пайплайнов начинают падать… Разработчики ругаются, тимлид предлагает откатывать, я в замешательстве — работало же! Снова начинаю гонять пайплайны, находим 3 проблемных теста, которые никто не трогал уже полгода. Выключаем — всё снова стабильно и зелено. Начинаю разбираться… Ошибка выглядит так — Error: Failed to parse JSON file, invalid JSON syntax found at position -1. Спасибо, очень информативно! Собираю такой же докер образ как на CI, тыкаю проблемные тест — ничего. Т.к. проблема воспроизводится только на CI, то решаю запатчить vite через yarn patch, добавив название файла в лог. Сработало — проблемный файл мы генерируем на CI и путь до него известен. Проверяю содержимое файла до тестов — всё на месте. Проверяю после тестов — и снова всё на месте. Но в тестах почему-то всё так же ломается. И тут я замечаю, что у падающих шардов есть кое-что общее — падает именно первый тест. Смотрю как это работает внутри vite — обычный fs.readFile и JSON.parse. В голову закрадывается страшная идея — а что если это какя-то проблема с файловой системой и одновременным чтением одного файла из нескольких процессов. Ищу ишью в ноде, но ничего прям конкретного не вижу. Уже начинаю писать скрипт для стресс-теста одновременного чтения, чтобы проверить гипотезу и тут в голову приходит идея — а что если кто-то этот файл всё таки перезаписывает? Проверяю файл через fs.stat сразу после записи и после тестов — даты создания и редактирования отличаются! Смотрю немного в пайплайн и понимаю, что внутри одной из команд мы запускаем генерацию этого файла. Мда! А ларчик просто открывался, как говорится. Убираю лишнюю генерацию и всё сразу же зеленеет. Для меня было откровением, что при записи файл может принимать какое-то промежуточное состояние. Т.е. не before → after, а before → empty → after. Рефлексируя о дебаге и что могло упростить поиск, пришёл к такому алгоритму: 1. Если ошибка указывает на неочевидное место, то её сразу же надо патчить, чтобы сузить радиус дебага (в очередной раз могу поругать бандлинг зависимостей в vite, кажется в новой версии зависимости ошибка уже содержит путь до файла). 2. В ошибках нужно искать общие признаки (в моём случае что падает только первый тест в каждом из шардов). 3. Проверять самые простые гипотезы в userland коде, а не искать какие-то баги в больших популярных библиотеках (vite и node в нашем случае) Остаётся вопрос: а почему ошибка не сразу всплыла, а через 2 недели? Ответ прост: у нас 4 шарда и не все тесты импортируют проблемный файл. С добавлением/удалением тестов порядок в шардах немного меняется и тесты, которые читают файл, становятся первыми в очереди и попадают в те самые первые 5 секунд, когда мы перезаписываем файл. Такой вот детектив. А как вы провели вечер пятницы?