# Понедельник 67 твитов
Всем привет! Я @xnimorz. Работаю в @hh_ru. Прошел в hh.ru путь от фронтендера до тимлида и сейчас… twitter.com/i/web/status/1…
7:26В какой-то момент я осознал, что люблю больше чистый язык, чем фреймворки, но удобство, которое дают при разработке… twitter.com/i/web/status/1…
7:31Я для себя получил ответ в pet-projects и open-source проектах. Так, мой последний эксперимент был со Svelte:… twitter.com/i/web/status/1…
7:31На этой неделе постараемся чередовать технические темы и soft skills. Пока план такой
7:32Предлагаю начать с паранойи. И несколько вопросов: Сколько браузерных расширений у вас установлено?
7:37Вы их проверяли, что они "белые и пушистые"?
7:39Я свое знакомство с разработкой браузерных расширений начал еще в 2015 году с написания плагина, который заменял ne… twitter.com/i/web/status/1…
8:06Уже затем я создавал плагин для нашей системы для HR менеджеров: chrome.google.com/webstore/detai… и после этого занимался пе… twitter.com/i/web/status/1…
8:08Главная проблема с браузерными расширениями — их редко воспринимают как реальную угрозу.
Однако, у них есть все ин… twitter.com/i/web/status/1…
Расскажу несколько тру-стори, а потом уже перейдем к техническому разбору.
8:14История 1 про безопасность: Cоздаю себе аккаунт в некоторой условной социальной сети, ввожу телефон и email. В наст… twitter.com/i/web/status/1…
8:22Через пару дней на email \ телефон начинает приходить спам. Что происходит? Соц. сеть продает мои данные? Она взломана?
8:22На самом деле все куда как проще. У пользователя стоит плагин, который делает какую-то полезную штуку для него. Но… twitter.com/i/web/status/1…
8:22Затем передает это в BackgroundScript, который уже отправляет наши контакты в спам-базы, причем с именем, фамилией… twitter.com/i/web/status/1…
8:22Самое грустное в этой истории, что отследить, что твой сайт кто-то "парсит" таким способом — практически нереально.… twitter.com/i/web/status/1…
8:22@jsunderhood @xnimorz @hh_ru А можно подробнее об опыте на svelte ? Сколько уже натыкаюсь на стоить на хабре про не… twitter.com/i/web/status/1…
Да, конечно. Сразу предупреждаю — опыт не production, личный.
По svelte у меня есть один проект на github — маски… twitter.com/i/web/status/1…
@jsunderhood @xnimorz @hh_ru А можно подробнее об опыте на svelte ? Сколько уже натыкаюсь на стоить на хабре про не… twitter.com/i/web/status/1…
9:14
Учет финансов, синхронизация между всеми членами семьи, разделение прав и многое-многое другое.
Я периодически дел… twitter.com/i/web/status/1…
В какой-то момент, я проникся svelte и появилось желание разобраться, насколько он удобен, можно ли им пользоваться… twitter.com/i/web/status/1…
9:14А потом при том же переходе на реакт появлялись боли: тут нужно PureComponent, там отписку правильную сделать, здес… twitter.com/i/web/status/1…
9:14Немного по-другому у меня сложилась история со svelte.
Про плюсы svelte тут уже писали и мне лично svelte очень по… twitter.com/i/web/status/1…
1) Нестабильность API. Я разрабатывал на 3.12.1, а демку делал на другой версии (ниже). У меня в итоге сломался `bi… twitter.com/i/web/status/1…
9:142) Вам часто нужно будет разбираться в коде, который сгенерировал svelte. Особенно если вы делаете большое приложен… twitter.com/i/web/status/1…
9:143) Если вам нужно прокинуть класс, вам придется объявить его как :global(класс) codesandbox.io/s/svelte-input… (вот здесь в App.svelte пример).
9:144) Если вы делаете утилитарный компонент и вы хотите прокинуть все props в обычный элемент (например aria атрибуты… twitter.com/i/web/status/1…
9:145) Еще неудобство вот github.com/sveltejs/svelt…
6) Иногда вы зависите от порядка переменных: github.com/sveltejs/svelt…
9:14Это те боли, которые у меня возникли за последние примерно 2 месяца.
9:14История 2 про "случайно сломать статику сайта": блокировщики рекламы очень эффективно блокируют запросы к ресурсам.… twitter.com/i/web/status/1…
9:21А все дело в том, что плагин просто решил, что STATic — это сбор статистики пользователя, поэтому радостно заблочил… twitter.com/i/web/status/1…
9:23@DonnaInsolita @jsunderhood @xnimorz @hh_ru Посмотри доклад Климова, почему использовать Свелт может быть больно.
Если я правильно понял, то речь об этом выступлении? youtube.com/watch?v=0cFoEP…
@DonnaInsolita @jsunderhood @xnimorz @hh_ru Посмотри доклад Климова, почему использовать Свелт может быть больно.
9:25
@jsunderhood @sbaha88 И это - постоянная головная боль для авторов расширений.9:34А ещё куча дельцов, которые встраи… twitter.com/i/web/status/1…
@jsunderhood @foodenko Всё так. Стараюсь минимизировать вектор атаки, снижая количество установленных разрешений.9:53
Последняя история: расширения прокси могут также зарабатывать на пользователях. Это это не только то, что они получ… twitter.com/i/web/status/1…
10:52После публикации они правда сменили способ монетизации :)
10:52Итак, набор проблем ясен, скрипт может выполняться в фоне, может внедряться на страницу. Остается открытым вопрос,… twitter.com/i/web/status/1…
12:10Всегда лучше знать, кого берешь себе. Можно проводить кучу действий над площадками, чтобы выдрать код, а можно (во… twitter.com/i/web/status/1…
12:10Этот плагин будет крайне полезен при установке дополнений. Открыли стор, запустили плагин, посмотрели — насколько… twitter.com/i/web/status/1…
12:11В первых же строках его кода должно закрасться сомнение, что его стоит устанавливать себе на машину.
Он откуда-то… twitter.com/i/web/status/1…
Если попытаться выработать алгоритм для паранойи, то что мне делать как пользователю?
1) Проверять каждое расширен… twitter.com/i/web/status/1…
12:152) Отключить обновление расширений, в которых не уверены или вообще всех: stackoverflow.com/questions/2765…
12:15Что делать с проблемой мне как разработчику сайта? Я постараюсь дать ответ с разбором на HolyJs… twitter.com/i/web/status/1…
12:16@jsunderhood А есть расширение, которое бы проверяло другие расширения на подозрительный код автоматически?
Хорошая идея, но мне встречать такое расширение не доводилось. Может быть кто-то встречал подобное?
@jsunderhood А есть расширение, которое бы проверяло другие расширения на подозрительный код автоматически?
12:32
@jsunderhood Все дело в том, что автор фильтров перестарался.
Тут больше играет роль то, что мы на основном сайте используем урл `/stat` для баннерки и мониторинга клиентской п… twitter.com/i/web/status/1…
@jsunderhood Все дело в том, что автор фильтров перестарался.
13:31
Ключевая проблема здесь — правило пишут для домена, и все поддомены автоматом наследуют эти правила
13:32@jsunderhood В рабочем (Хром) — 1, в личном (Сафари) — 0
Круто! Я провел эксперимент и понял, что не смогу отказаться от трех плагинов :(
@jsunderhood В рабочем (Хром) — 1, в личном (Сафари) — 0
13:34
@jsunderhood Браузеры это проверяют автоматом перед паблишем, но не на 100%
В Firefox такая проверка присутствует и такой фокус обычно не пройдет. Аналогично в сафари.
В Chrome store же можн… twitter.com/i/web/status/1…
@jsunderhood Браузеры это проверяют автоматом перед паблишем, но не на 100%
13:42
@BasherTheJedi @jsunderhood Это делают веб-сторы. У Оперы вообще даже ручным режимом, если автоматика показала угрозу
В Firefox проводят (проводили, когда я паблишил) также в ручном режиме. Более того, там проверяют очень подробно, м… twitter.com/i/web/status/1…
@BasherTheJedi @jsunderhood Это делают веб-сторы. У Оперы вообще даже ручным режимом, если автоматика показала угрозу
13:46
@jsunderhood Им еще можно настраивать доступ, у меня один экстеншн(notion) имеет доступ ко всем сайтам, а гугл тран… twitter.com/i/web/status/1…
Да, это хорошо позволяет уменьшить аппетиты и чуть больше быть уверенным, что за вами не следят👍. Настраивается обы… twitter.com/i/web/status/1…
@jsunderhood Им еще можно настраивать доступ, у меня один экстеншн(notion) имеет доступ ко всем сайтам, а гугл тран… twitter.com/i/web/status/1…
13:58
@jsunderhood А это вообще нормально, что расширения( в хроме точно) имеют доступ кл всем твоим куки. Это разве не дыра в безопасности?
Любое расширение, которое получило пермишен к сайту (либо маска сайта, либо <all_urls>) может внедрять свой код на… twitter.com/i/web/status/1…
@jsunderhood А это вообще нормально, что расширения( в хроме точно) имеют доступ кл всем твоим куки. Это разве не дыра в безопасности?
14:36
httpOnly прямо обязательно для любых авторизационных кук. Такие куки недоступны со стороны js.
Также можно использо… twitter.com/i/web/status/1…
Справедливости ради, проблема с плагинами вырастает из-за того, что большая часть возможностей им нужна, чтобы творить добро.
14:49Скорее всего большинство из нас пользуется react или vue devtools. Им нужны пермишены для общения с вкладками, обра… twitter.com/i/web/status/1…
14:49Если вы получаете обращение в саппорт "сайт тормозит", часто саппорту приходится объяснять пользователю, как сделат… twitter.com/i/web/status/1…
14:49В тему плагинов и блокировщиков рекламы (особенно, если у вас хром) — пробовали ли вы Brave вместо Chrome + блокиро… twitter.com/i/web/status/1…
15:23@jsunderhood Уже пол года им пользуюсь
Я тоже в какой-то момент попробовал Brave и понял, что он меня всем устраивает.
@jsunderhood Уже пол года им пользуюсь
15:39
Но с brave были некоторые сложности. Например, он блокировал сайт mvideo. Получилось зайти, только отключив guard
15:39@jsunderhood А если использовать атрибут integrity для скриптов на сайте, в этом случае расширение сможет внедрить и выполнить js?
Обычно Content Security Policy — одна из первых штук, которая приходит в голову для защиты от плагинов. Сама по себ… twitter.com/i/web/status/1…
@jsunderhood А если использовать атрибут integrity для скриптов на сайте, в этом случае расширение сможет внедрить и выполнить js?
16:55
Integrity или Subresource Integrity идет вместе c Content-Security-Policy: require-sri-for script; что требует пров… twitter.com/i/web/status/1…
16:55Плюс с поддержкой у require-sri-for все пока еще не радужно: developer.mozilla.org/en-US/docs/Web…
16:55Куда эффективнее будет запретить все скрипты, включая inline, кроме своего домена, но и тут плагины будут исполняться.
16:55Маленькое дополнение к svelte: пару дней назад выложили "The Return of 'Write Less, Do More'" от Rich Harris… twitter.com/i/web/status/1…
17:12Не "Скрипты же действуют по-другому:", а "Расширения же действуют по-другому"
17:32@jsunderhood Единственная возможность защитить приложение от браузерных расширений, на сколько я понимаю, описана т… twitter.com/i/web/status/1…
Здесь рассматривается только подмножество проблем — отправка данных, подписка данных ключом и получение данных. Сам… twitter.com/i/web/status/1…
@jsunderhood Единственная возможность защитить приложение от браузерных расширений, на сколько я понимаю, описана т… twitter.com/i/web/status/1…
19:04
Как пример: приложение вставляет свои данные к нам на сайт, для добавления комментариев: chrome.google.com/webstore/detai…
Са… twitter.com/i/web/status/1…
Мое выступление на HolyJs holyjs-moscow.ru/2019/msk/talks…
Как раз будет про различные векторы атак и защиту от них.
@boriscoder @jsunderhood В кейсе описана регрешн бага насколько я понял, а они у всех бывают. Хотя в целом, чем мол… twitter.com/i/web/status/1…20:51
# Вторник 95 твитов
@jsunderhood @xnimorz @hh_ru Привет!Хотелось бы услышать про организационную структуру фронтенда и отдельно про к… twitter.com/i/web/status/1…
Сегодня как раз поговорим о работе и процессах в компании.
@jsunderhood @xnimorz @hh_ru Привет!
Хотелось бы услышать про организационную структуру фронтенда и отдельно про к… twitter.com/i/web/status/1…
6:00
Как и обещал, сегодня поговорим про тех.деп хх и процессы. Я сейчас работаю в команде архитектуры, где 100% времени… twitter.com/i/web/status/1…
7:06Что есть типичная задача в моей команде?
На самом деле они очень сильно разнятся. Начиная от внедрения SSR для реа… twitter.com/i/web/status/1…
Кстати, организовать удобную работу с иконками на большом сайте — это может быть (внезапно) не самой тривиальной за… twitter.com/i/web/status/1…
7:16Предлагаю начать с паранойи. И несколько вопросов: Сколько браузерных расширений у вас установлено?
Результаты по количеству плагинов в браузере:
Предлагаю начать с паранойи. И несколько вопросов: Сколько браузерных расширений у вас установлено?
7:44
Команда архитектуры занимается всем, что позволит повысить скорость разработки или качество кода. Из того, что перв… twitter.com/i/web/status/1…
7:58Все изменения делаются для всей фронтенд группы, а не локально. Иногда во время таких задач появляются разные open-… twitter.com/i/web/status/1…
7:58Здесь будет тред, о том, как организован технический департамент HeadHunter (большими мазками) >>>
9:31У нас нас есть страница на tech.hh.ru/about.html, где описано достаточно подробно все, какие технологии мы исполь… twitter.com/i/web/status/1…
9:311) Технический департамент на текущий момент — это более 130 человек и 25 команд. Каждая команда — отдельный unit,… twitter.com/i/web/status/1…
9:31Поэтому стандартная конфигурация команды это 1 фронтенд-разработчик, 1 бекенд, 1 тестировщик и 1 тимлид. В зависимо… twitter.com/i/web/status/1…
9:312) Владение кодом общее. Поэтому если команде, которая занимается работодательскими фичами, нужно добавить что-то в… twitter.com/i/web/status/1…
9:313) Команды разбиваются по своим ролям: работодательские фичи, соискательские сервисы, поиск, реклама, команды сайд-… twitter.com/i/web/status/1…
9:314) Бывает так, что какая-то команда больше занимается определенной частью возможностей, например, созданием ваканси… twitter.com/i/web/status/1…
9:315) У каждой команды есть product owner, с которым команда прорабатывает задачи. Команда участвует в проработке зада… twitter.com/i/web/status/1…
9:316) Большинство задач выпускаем под AБ-тестами. Обычно на проде одновременно включено десятки (а то и сотни) тестов.… twitter.com/i/web/status/1…
9:317) Полезная-интересная штука: кроме бизнес-задач у нас есть понятие "технического налога" — это термин похож на тех… twitter.com/i/web/status/1…
9:318) Более того, есть соглашение, что 30% времени работы команды могут тратить на налог.
9:31К предыдущему пункту — еще более хорошая новость, что договоренность про 30% соблюдается.
9:319) Код храним на Github, ревьювим код через pull request. Коротко про ревью — любой может участвовать, должен быть… twitter.com/i/web/status/1…
9:3110) Релизы ежедневные. Сегодня сделал \ протестировал задачу — можно сегодня собрать релиз или завтра она автоматически попадет в релиз дня.
9:3111) Самих релизов в день может быть много. Очень много. Они могут быть большими. Пару недель назад было 4 релиза фр… twitter.com/i/web/status/1…
9:31Это не считая остальных сервисов, которых у нас много (так как идем в стороу микро-сервисной архитектуры).
9:31Тредик с фактами о фронтенд части (компиляция tech.hh.ru/about.html и интересных фактов): >>
9:531) Фронтенд делится на 2 стека: старый и новый. Старый это ванильный js + jQuery, на сервере html рендерится через… twitter.com/i/web/status/1…
9:53Стили пишем в less, используем АНБ подход для разграничения стилей АНБ — верстка независимыми блоками, одно из перв… twitter.com/i/web/status/1…
9:532) На новом стеке включен SSR везде. Миграция отдельная большая тема, о ней поговорим на следующий день
9:533) Есть UIToolkit — блоко. Работает на двух стеках и состоит более чем из 120 компонентов. Начиная от кнопок и зака… twitter.com/i/web/status/1…
9:534) Кстати, на styleguidist документированы и легаси компоненты. Для написания примеров у нас используется кастомный… twitter.com/i/web/status/1…
9:535) Код транспайлится бабелем (тайпскрипта у нас пока нет). Используем в том числе такие штуки как optional chainig:… twitter.com/i/web/status/1…
9:536) Есть самописные бабель плагины. Некоторые могут быть полезны всем, некоторые специфичны: github.com/hhru?utf8=%E2%…
9:537) Код автоматически проверяем eslint github.com/hhru/eslint-co… — наш конфиг. Для стилей используем stylelint. Pretti… twitter.com/i/web/status/1…
9:538) Все фронтендеры пишут прослойку на питоне — это сервис, который выполняет роль API Gateway. Получить запрос поль… twitter.com/i/web/status/1…
9:53Код в прослойке очень простой, веб-сервер c открытым кодом: github.com/hhru/frontik
9:539) Юнит-тесты. Их пишем на новом стеке обязательно. Кроме юнит-тестов есть более 8000 сьютов автотестов. Автотесты… twitter.com/i/web/status/1…
9:5310) В каждом PR мы сделали индикацию code-coverage в зависимости от base branch. Основное правило — желательно, что… twitter.com/i/web/status/1…
9:53Если стало меньше и если увеличилось: pic.twitter.com/sboHyTQO8a
9:5311) Fun Fact: такой простой прием позволил заметно повысить code coverage
9:5312) У каждого разработчика, тестировщика в компании есть отдельная виртуалка, со всеми сервисами. Вся разработка св… twitter.com/i/web/status/1…
9:53Накатка веток, запуск тестов, обновление стенда — все автоматизированно. Например, у меня в 8 утра всегда происходи… twitter.com/i/web/status/1…
9:53Во второй половине дня поговорим про Kanban, визуализацию процессов и как удобная и хорошая визуализация помогает разработке.
9:54В хх я работаю больше 5 лет. И за это время я сменил 5 команд. В разных командах процессы могут отличаться очень за… twitter.com/i/web/status/1…
12:26Сейчас в ХХ используется Kanban методология. Обычно для новых разработчиков это: стендапы, отсутствие спринтов и пр… twitter.com/i/web/status/1…
12:28Кроме разработки (product delivery) все разработчики участвуют в проработке проекта (product discovery). Как должен… twitter.com/i/web/status/1…
12:34В книгах можно встретить понятие бутылочного горлышка (bottleneck). Идея такая: во время проработки отказатсья от и… twitter.com/i/web/status/1…
12:34Каждая команда определяет свой состав участников на такие проработки. Где-то 2 человека от команды, где-то вся кома… twitter.com/i/web/status/1…
12:34Команда вместе с продактом разбирает проблему, набрасывает идеи решения и описывает user story. Обычно применяются… twitter.com/i/web/status/1…
12:34Остальной процесс проработки задачи типовой — построили видение задачи, отдали на отрисовку, декомпозировали, задача упала в беклог.
12:34В хх мы построили систему, которая рисует графики, помечает долгие фичи и позволяет даже "гадать", что происходило… twitter.com/i/web/status/1…
12:34Мы используем базовые инструменты — кумулятивная диаграмма, box plot, гистограмму по статусам и сводные таблицы.
12:34Нашел хорошую иллюстрацию, которая описывает что позволяет визуализировать кумулятивная диаграмма: pic.twitter.com/O3mjwmD1my
12:34@MrL1n @_bravit @PodlodkaPodcast @mobileunderhood @jsunderhood ещё им не покорён. возможно фронтендеры смогут своим… twitter.com/i/web/status/1…
Надо звать! :-)
@MrL1n @_bravit @PodlodkaPodcast @mobileunderhood @jsunderhood ещё им не покорён. возможно фронтендеры смогут своим… twitter.com/i/web/status/1…
12:40
Нашёл абсолютно волшебный сайт littlebigdetails.com с клёвыми маленькими фичами, делающими жизнь лучше.
Это великолепно :)
Нашёл абсолютно волшебный сайт littlebigdetails.com с клёвыми маленькими фичами, делающими жизнь лучше.
12:41
@seminioni @MrL1n @_bravit @PodlodkaPodcast @mobileunderhood @jsunderhood На фронтенд он уже нацелился holyjs-moscow.ru/people/2eqmuhq…13:24
Часто может возникнуть вопрос: а чем отличается канбан от скрама?
Про это есть хорошая статья от Алексея Пименова:… twitter.com/i/web/status/1…
1) Отсутствие спринтов. Никто никогда не пытается "выпустить все задачи в пятницу, потому что спринт заканчивается"… twitter.com/i/web/status/1…
13:50Если у меня задача сегодня протестировалась, то завтра она уже будет на проде. Кроме того, если очень хочется, можн… twitter.com/i/web/status/1…
13:502) Более явная вытягивающая система — "запросы" на задачи поступают от команд по мере образования вакуума на этапах… twitter.com/i/web/status/1…
13:50Как только команда берет user story, в колонке "беклог" образуется вакуум. Это сигнал для продакта, что его нужно ч… twitter.com/i/web/status/1…
13:503) Визуализация — чем лучше визуализирован процесс, тем лучше команда понимает, в каком состоянии она находится, на… twitter.com/i/web/status/1…
13:50@jsunderhood А зачем на проде то?
Не нужно при каждом вопросе подключать VPN для стенда, не нужно грепать по проекту — открыл сайт, выбрал нужный эле… twitter.com/i/web/status/1…
@jsunderhood А зачем на проде то?
13:53
Насколько важна визуализация процесса? Я для себя вывел, что хорошая визуализация решает 2 задачи:
1) Быстрее ориен… twitter.com/i/web/status/1…
Этот тред можно смело будет назвать — "о чем я бы хотел знать про визуализацию перед тем, как стал тимлидом"
14:36Классический подход, который я встречал в куче мест: это когда заводят для задач разработчиков 5 колонок: туду, в р… twitter.com/i/web/status/1…
14:36Тут мы сталкиваемся с первой проблемой. Если мы перевели задачку в тестирование, она тестируется или нет? Что с ней происходит?
14:36Чтобы решить эту проблему, иногда возникает желание добавить метку или комментарий в задачку "ожидает тестирования"… twitter.com/i/web/status/1…
14:36Это плохо тем, что любому члену команды, чтобы понять "а что там с задачей" придется открывать каждую задачу, искат… twitter.com/i/web/status/1…
14:36Решением может быть разделение колонки Ревью на 2: "ревью: в процессе" и "ревью: готово". В этой системе тестировщи… twitter.com/i/web/status/1…
14:36Решение легко масштабируется и на другие подобные проблемы. Мы получаем доску, на которой мы понимаем, что происход… twitter.com/i/web/status/1…
14:36Вторая проблема: тестировщик находит критические баги в задаче. Выпускать нельзя. Здесь есть разные пути решения. М… twitter.com/i/web/status/1…
14:36Зачем в этом случае такие навороты?
14:36Задачка уже сделана, на нее уже потрачены силы\нервы\деньги\обсуждения. Приоритет такой задачи, скорее всего, выше,… twitter.com/i/web/status/1…
14:36И тут мы подходим к такой штуке как определение приоритетов на доске.
14:36Самый простой и "нативный" способ — это чтение справа налево по строкам. Т.е. мы сортируем наши swimlines по приори… twitter.com/i/web/status/1…
14:36Члены команды при выборе очередной задачи проходят по этим swimlines и выбирают первую задачу, над которой они рабо… twitter.com/i/web/status/1…
14:36В результате, если тестировщик перевесил задачку на разработчика, то разработчик, закончив текущую работу, открывае… twitter.com/i/web/status/1…
14:36Преимуществом такого подхода является отсутствие излишних коммуникаций.
14:36Этот подход можно использовать и для проведения стендапов. Идти по задачкам, справа налево. В теории, это позволяет… twitter.com/i/web/status/1…
14:36Мы в двух командах пробовали сделать так для стендапа и каждый раз мы терпели фиаско. Потому что, во-первых, этот п… twitter.com/i/web/status/1…
14:36У меня для вас подборка статей, как сделать качественный dropdown:15:28— a11y-guidelines.orange.com/web_EN/exemple…;
—… twitter.com/i/web/status/1…
@jsunderhood Чувствуют-ли себя разработчики винтиками в системе?
Процесы - как по книге у Пименова - охренительные.… twitter.com/i/web/status/1…
Хороший вопрос! Если хочется просто "закрывать входящие таски и чтобы меня не трогали" то будет ощущения винтика. Н… twitter.com/i/web/status/1…
@jsunderhood Чувствуют-ли себя разработчики винтиками в системе?
16:00
Процесы - как по книге у Пименова - охренительные.… twitter.com/i/web/status/1…
HeadHunter не идеален, как и везде есть свои недостатки. Каждая команда может сама донастраивать процессы. Вот прям… twitter.com/i/web/status/1…
16:00Поэтому главный инструмент, как и везде — общение и улучшение команды в которой работаешь, чтобы всем было комфортн… twitter.com/i/web/status/1…
16:00@jsunderhood Зачем переводить задачу на тестировщика? QA просто берет из “to verify” и либо закрывает, либо перемещает обратно в “open”.
Переводить на тестировщика не обязательно, особенно, если есть отдельная колонка «ревью:готово», из которой тестиро… twitter.com/i/web/status/1…
@jsunderhood Зачем переводить задачу на тестировщика? QA просто берет из “to verify” и либо закрывает, либо перемещает обратно в “open”.
17:37
Потому что тестировщик должен писать в чат или делать какой-то другой call, что эту задачу нужно доделать. Все из-з… twitter.com/i/web/status/1…
17:37А сакральным знанием «она уже готова, нужно ещё чуть-чуть» обладает только разработчик и тестировщик. И про эту зад… twitter.com/i/web/status/1…
17:37Куда как проще тестировщику навесить задачку прямо на доске на разработчика, не меняя этапа. И как только начнётся… twitter.com/i/web/status/1…
17:37Есть ещё одна причина тестировщика не идти / писать сразу в чат. Это асинхронность коммуникации. Разработчик может… twitter.com/i/web/status/1…
17:37Правильно настроенная доска работает как single source of truth — сама может разрулить коммуникацию.
17:37@jsunderhood Мы скорее не сталкивались с необходимостью это знать, на долго они там не задерживаются всё равно.
Хороший пример того, что не существует единого рецепта для всех.
Кому-то дополнительные колонки могут оказаться из… twitter.com/i/web/status/1…
@jsunderhood Мы скорее не сталкивались с необходимостью это знать, на долго они там не задерживаются всё равно.
18:02
@jsunderhood @boriscoder Делается очень просто: .parent-class :global('.child-class')
Подробнее: habr.com/ru/post/438834/
Клево! Вы все также создаете глобальный класс, но везде, кроме .parent-class он не будет иметь смысла, так как селе… twitter.com/i/web/status/1…
@jsunderhood @boriscoder Делается очень просто: .parent-class :global('.child-class')
18:37
Подробнее: habr.com/ru/post/438834/
Главное помнить, что это все еще css и если вы создадите просто :global(.child-class) то эти стили также применятся… twitter.com/i/web/status/1…
18:37@jsunderhood @oburejin Соглашусь pic.twitter.com/FmBudIeeHQ19:42
В моей карьере фронтендера было 2 жестких бага, на которые я убил кучу времени (примерно по 2 месяца) и понял, что… twitter.com/i/web/status/1…
Страшилки на ночь :)
В моей карьере фронтендера было 2 жестких бага, на которые я убил кучу времени (примерно по 2 месяца) и понял, что… twitter.com/i/web/status/1…
19:58
@jsunderhood @PaulMaly @boriscoder Критичные проблемы в Svelte 3 встречаются в сложных ситуациях, которые выходят з… twitter.com/i/web/status/1…20:33
# Среда 93 твита
Вчера я спрашивал про иконки — было бы интересно послушать, что там нетривиального и как с ними работать. Иконки, д… twitter.com/i/web/status/1…
7:44Тред про иконки. >>>
8:33Ограничения в задаче: есть базовые иконки, которые используются везде. Есть специфические иконки, которые выполняют… twitter.com/i/web/status/1…
8:33Сверху добавляем браузерную поддержку и желание, чтобы иконки кешировались, реиспользовались и работали на двух сте… twitter.com/i/web/status/1…
8:33Накидываем, прототипируем варианты:
8:33Код прототипа для inline варианта (вместе с кастомным webpack loader): gist.github.com/xnimorz/8dfe0c…
Лоадер направляем на .svg иконки.
Выглядит просто и легко, но каждая иконка — это куча тегов в DOM, а значит куча данных, которые используются при SS… twitter.com/i/web/status/1…
8:33В защиту решения: можно сделать поддержку многоцветных иконок, анимацию цветовых переходов.
8:332. Можем улучшить этот вариант и использовать inline svg + use директиву.
8:33Идея такая: на этапе сборки превращаем все иконки в одну большую мега-иконку, где весь контент описан, например в `… twitter.com/i/web/status/1…
8:33Код становится проще, нам уже не обязательно делать кастомный лоадер. Достаточно обычного react-компонента: gist.github.com/xnimorz/543dc8…
8:33Вместо одной большой мега-иконки можно использовать другой подход: в компоненте icon храним singleton-Map, в ней от… twitter.com/i/web/status/1…
8:33Если добавляется новая иконка, то вставляем эту иконку через `symbol`, помечаем в singleton и добавляем реальное ис… twitter.com/i/web/status/1…
8:33Главная проблема подхода: у `<symbol>` должен быть id. А значит мы получаем опасность пересечений, если иконки не с… twitter.com/i/web/status/1…
8:33Можно для иконок сделать решение аналогичное подходу css-modules и добавлять хеши например. Но мы начинаем строить… twitter.com/i/web/status/1…
8:33Сама идея inline svg + use хороша и для многих проектов может зайти. Этот подход экономит и размер данных, и имеет… twitter.com/i/web/status/1…
8:33Теряем удобные анимации по сравнению с предыдущими случаями, получаем возможность работать с многоцветными иконками… twitter.com/i/web/status/1…
8:33Здесь есть даже готовый калькулятор таких стилей codepen.io/sosuke/pen/Pjo…
8:33Главные минусы: вас будут не очень сильно любить за стили вида: filter: invert(17%) sepia(32%) saturate(5440%) hue-… twitter.com/i/web/status/1…
8:33Здесь этот способ описан подробнее: css-tricks.com/solved-with-cs…
Плюсы — удобно, все средствами css.
Какое бы вы решение выбрали?
8:33@jsunderhood Удобство это понятно, а что с оверхедом на размер бандла?Средняя длина имени - 50 букв, то есть 64 б… twitter.com/i/web/status/1…
Сам бандл разбиваем на chunks по странице. Общий код для нескольких страниц выносится отдельно. В итоге:
1) оверхед… twitter.com/i/web/status/1…
@jsunderhood Удобство это понятно, а что с оверхедом на размер бандла?
Средняя длина имени - 50 букв, то есть 64 б… twitter.com/i/web/status/1…
9:01
3) Мы проводили ряд АБ тестов направленных на улучшение и деградации производительности клиентского приложения, с ц… twitter.com/i/web/status/1…
9:01И опять же данные сжимаем brotli, в итоге оверхед на страницу — меньше
9:036 ноября в Москве мы с HolyJS проведем Node.js Code+Learn.10:09
Это отличная возможность сделать вклад в разработку Node… twitter.com/i/web/status/1…
В опросе про иконки с большим отрывом лидирует вариант использовать inline иконки (с use тегом или без).
Расскажу… twitter.com/i/web/status/1…
Если сейчас попытаться оценить решение, то
по экономии размера, самыми эффективными будут решения через filter или… twitter.com/i/web/status/1…
Правильный выбор между этими решениями сделать сложно. Субъективно меня очень тянет к решениям с inline + use, filt… twitter.com/i/web/status/1…
11:59Если вы не поддерживаете эти браузеры — рекомендую посмотреть в сторону filter или mask для иконок. Делается очень… twitter.com/i/web/status/1…
11:59Выбираем из оставшегося.
11:59Если рассматривать вариант просто inline без use. На моменте, когда вспоминается, что кроме React у тебя есть еще m… twitter.com/i/web/status/1…
11:59В любой задаче приходится искать баланс. Решение должно позволять очень просто вставить иконку, но не должно быть к… twitter.com/i/web/status/1…
11:59Пробуем вариант с inline svg + use. Само решение простое: мы инлайним + используем use при первой вставке иконки на… twitter.com/i/web/status/1…
11:59Окей, это решается именем иконки — нам же все равно компонент вызывать с уникальным именем. А чтобы названия не пер… twitter.com/i/web/status/1…
11:59Такое решение очень хорошо зайдет, особенно, если у вас single source of icons 😀.
Поэтому, если задаетесь подобны… twitter.com/i/web/status/1…
11:59Но на большом сайте можно столкнуться с тем, что самих иконок большое количество. Есть иконки UIToolkit, иконки отн… twitter.com/i/web/status/1…
11:59В итоге, получаем, что у нас есть потенциальное место для коллизий и если не сводить все иконки в одно место при эт… twitter.com/i/web/status/1…
11:59Остается вариант со спрайтами. Он дает чуть больший размер бандла по сравнению с inline + use и добавляет сложносте… twitter.com/i/web/status/1…
11:59Возможные состояния у нас генерируются на less.
Выглядит это так: миксину приходит набор состояний, например `.abst… twitter.com/i/web/status/1…
Затем через рекурсию создаются модификаторы: `icon_action, icon_primary icon_secondary` и модификаторы для hover, f… twitter.com/i/web/status/1…
11:59Специфические иконки для сайтов генерируются по аналогичному механизму. UIToolkit предоставляет миксин, который сге… twitter.com/i/web/status/1…
11:59Мораль этой истории?
У нас есть N подходов и ни одного идеального. И это просто вставить иконку на страницу.
Справедливости ради сказать, если у вас нет поддержки ie11 и прочего, то inline + use, filters или mask вам хорошо подойдут
13:02Давайте сегодня поговорим о миграциях.
В случае в хх мы мигрируем с xslt + vanilla js + jquery на react стек.
Я п… twitter.com/i/web/status/1…
Я, скорее всего, не открою ничего нового в самой миграции. Поэтому короткое резюме-спойлер:
Мы переводим код на ре… twitter.com/i/web/status/1…
Микрофронтенды мы не делаем. Вместо этого — четкая структура проекта. Выглядит вот так: pic.twitter.com/Kixsb8WSYC
13:24Каждая страницы — это отдельный chunk. На каждой странице, прямо внутри pages/PageName/component хранятся компонент… twitter.com/i/web/status/1…
13:24Если компонент используется больше, чем на 1 странице, то он переезжает в shared.
Chunk загружаем при запросе стра… twitter.com/i/web/status/1…
Так как при подобном переписывании кода получается много, он также выходит под фичей на часть пользователей. Если н… twitter.com/i/web/status/1…
13:24Зачем вообще нужна миграция?
13:251) Скорость разработки — на новом стеке проще декомпозировать компоненты, люди находятся внутри одной технологии, ч… twitter.com/i/web/status/1…
13:252) Поддержка. Также вытекает из того, что поток данных четко направлен, все изменения проходят через единое место.… twitter.com/i/web/status/1…
13:253) Порог входа. У меня есть стойкое ощущение, что сейчас людей, которые больше хотят писать на условном реакте, про… twitter.com/i/web/status/1…
13:254) Хайп. Это момент, когда на рынке разработчики начинают крутить носом — у вас нет react, я к вам не пойду. Как бы… twitter.com/i/web/status/1…
13:25Главная проблема миграции — бизнес хочет выпускать бизнес задачи, разработчики должны балансировать между техническ… twitter.com/i/web/status/1…
14:01Какой алгоритм перевода страницы?
Вначале нужен фундамент. Это вся инфраструктра — роутинг, дата-слой, разделение… twitter.com/i/web/status/1…
14:03На этом фундаменте можно строить страницу.
Обычно здесь все происходит по типовому сценарию: посмотрели какие комп… twitter.com/i/web/status/1…
Что при переходе важного?
Наиболее критическим моментом для нас является наличие SSR. Потому что это SEO, это хор… twitter.com/i/web/status/1…
14:04Тут мы подходим к важной теме SSR (server side rendering).
Здесь мои коллеги уже писали о SSR в хх… twitter.com/i/web/status/1…
1) node.js не занимается походами на бекенды. Мы сделали SSR as a service. То есть есть питонячье приложение, котор… twitter.com/i/web/status/1…
14:15Урл у нас всегда один `/render`. Информация о реальном урле и данных лежит в body запроса.
Схематично это выглядит… twitter.com/i/web/status/1…
На сервере крутится Koa (выбирали между express, koa и hapi). express не взяли — были проблемы в секьюрности, hapi… twitter.com/i/web/status/1…
14:15Кроме того, api koa отдалено похож на api нашего питон-приложения, за счет чего разработчикам проще было бы освоиться в новом окружении.
14:15Каждый инстанс ноды запускает внутри себя Clusters по количеству ядер выделенных контейнеру:… twitter.com/i/web/status/1…
14:15Код вызова рендера очень простой умещается на десяток строк вместе с обработкой ошибок: gist.github.com/xnimorz/2a6283…
То… twitter.com/i/web/status/1…
Это позволило нам сделать SSR не переделывая специальным образом клиентскую часть (а вызовы window.something и подо… twitter.com/i/web/status/1…
14:15Мониторим сервер через okmeter: okmeter.io
14:15Контейнеров node.js много и тут появляется задача: как выпускать обратно несовместимые релизы? Когда в питоне с нов… twitter.com/i/web/status/1…
14:15С одной стороны можно сохранить обратно-совместимые релизы и на такие изменения делать 2-3 релиза паровозиком (друг… twitter.com/i/web/status/1…
14:15Тут на помощь приходит "хитрый" метод: у питонячьего приложения и node.js рендер сервера единая версия. То есть пос… twitter.com/i/web/status/1…
14:15Делим группу Node.js серверов на 2 и вначале катим релиз на половину машин.
Когда релиз раскатился, катим релиз на… twitter.com/i/web/status/1…
Остается посыпать решение инфраструктурой:
питон приложение идет в node.js с указанием версии. Node.js перед рендер… twitter.com/i/web/status/1…
Если нет, отправляем 503. Питон получает 503 и пытается заретраить запрос на другой сервер. количество ретраев = ко… twitter.com/i/web/status/1…
14:15Можно пойти дальше и завести единое место с конфигом, которое будет балансировать и знать, где-какая версия раскаче… twitter.com/i/web/status/1…
14:15Если у вас есть еще вопросы про SSR или миграцию — пишите, с радостью отвечу на что смогу :)
14:19@jsunderhood А делали какое-нибудь сравнение этого подхода с подходом «1 процесс (ядро) на 1 контейнер» (то есть, без кластера)?
Да, когда только внедряли проверяли, насколько будет рост, если использовать cluster и будет ли он.
При включении… twitter.com/i/web/status/1…
@jsunderhood А делали какое-нибудь сравнение этого подхода с подходом «1 процесс (ядро) на 1 контейнер» (то есть, без кластера)?
14:36
@jsunderhood Но это же ваще оценочное мнение, так ведь? Которое вообще ничего общего может не иметь с реальной жизнью.
Отчасти да, отчасти нет. Поясню, крайне сложно для суждения привести абсолютно идеальные данные. Никто не будет дел… twitter.com/i/web/status/1…
@jsunderhood Но это же ваще оценочное мнение, так ведь? Которое вообще ничего общего может не иметь с реальной жизнью.
15:57
В то же время, мы измеряем lead time всего процесса разработки и lead time только разработки. Если выбрать задачи,… twitter.com/i/web/status/1…
15:57Это не на 100% идеальный способ, но чем больше задач делает команда на странице, тем более репрезентативна выборка.… twitter.com/i/web/status/1…
15:57И тут я сам же поломаю свой довод :) во время переписывания происходит ещё рефакторинг кода, что упрощает дальнейшу… twitter.com/i/web/status/1…
15:57Важный момент: мы измеряем lead time не для сравнений, а для рефлексии, чтобы понимать, какие вопросы и трудности у команды были.
15:57@jsunderhood И где-то здесь ещё передают привет микросервисы ;)17:57
@jsunderhood А что происходит с глобальными задачами из разряда - обновить какую-то либу на следующий мажор по всем… twitter.com/i/web/status/1…
Все зависит от размера проблемы. Если задача достаточно большая, то работает +/- так:
1) Задача описывается в jira,… twitter.com/i/web/status/1…
@jsunderhood А что происходит с глобальными задачами из разряда - обновить какую-то либу на следующий мажор по всем… twitter.com/i/web/status/1…
19:19
2) Определяется приоритет задачи. Раньше мы пытались использовать для приоритетов RAF (Risk assessments framework)… twitter.com/i/web/status/1…
19:193) Команды, если планируют взять тех. задачу видят все задачи и выбирают исходя из приоритета + времени, которое он… twitter.com/i/web/status/1…
19:194) Если команда архитектуры понимает, что вряд ли кто-то возьмет эту задачу в ближайшем будущем, а профит от задачи… twitter.com/i/web/status/1…
19:19Для синка у нас есть 2 типа встреч. Тимлидский статус-синк и синк фронтенд группы. (это помимо внутрикомандных стен… twitter.com/i/web/status/1…
19:19@jsunderhood Я обычно использую <img src=my.svg> в доме, а затем динамически подгружаю и заменяю инлайновым <svg>
Еще один способ решения задачи :)
@jsunderhood Я обычно использую <img src=my.svg> в доме, а затем динамически подгружаю и заменяю инлайновым <svg>
19:19
# Четверг 81 твит
@jsunderhood Ну а как вы на питоне вырезаете все фетч запросы что бы сходить на сервер за данными?
Расскажу как работает роутинг:
Для роутинга используем обычный react-router. Для SPA переходов между страницами ест… twitter.com/i/web/status/1…
@jsunderhood Ну а как вы на питоне вырезаете все фетч запросы что бы сходить на сервер за данными?
8:19
Выглядит это вот так: gist.github.com/xnimorz/5a2783…
preload для компонентов вытаскивается через React-loadable
За chunk с данными ходим, чтобы данные в стор записались в тот момент, когда chunk будет предзагружен и страница ср… twitter.com/i/web/status/1…
8:19Чтобы серверная нода не слала запросы, мы в коде конфигурации стора проверяем наш environment и в случае сборки для… twitter.com/i/web/status/1…
8:19Какое бы вы решение выбрали?
Результаты голосования по иконкам. 60% за вариации inline иконок
Какое бы вы решение выбрали?
8:41
@jsunderhood Еще в защиту такого подхода - большинство проблем можно нивелизровать, загрузив иконку через iframe.
Л… twitter.com/i/web/status/1…
Еще про иконки :)
Но мне такой вариант кажется усложнённым, по сравнению с ленивой загрузкой и использованием use… twitter.com/i/web/status/1…
@jsunderhood Еще в защиту такого подхода - большинство проблем можно нивелизровать, загрузив иконку через iframe.
10:04
Л… twitter.com/i/web/status/1…
Понадобилось отрендерить табличку 500х50 ячеек, клик на каждую ячейку тогглит её в инпут и обратно. React убивает б… twitter.com/i/web/status/1…
Я решал похожую задачу на реакте, и учитывая, что в реакте есть встроенное делегирование событий, проблема может бы… twitter.com/i/web/status/1…
Понадобилось отрендерить табличку 500х50 ячеек, клик на каждую ячейку тогглит её в инпут и обратно. React убивает б… twitter.com/i/web/status/1…
10:21
Ну, и в подобных историях наиболее правильный подход: это сделать замер через performance и посмотреть, на что дейс… twitter.com/i/web/status/1…
10:21@jsunderhood @PaulMaly Да, про него. Ага, понял. Ну да, можно наверное попробовать какой-то такой вариант. Потому ч… twitter.com/i/web/status/1…10:35
Хм. My bad. Где-то накосячил и нагрешил на React. Он вполне себе отрендерил 25к ячеек и никто не умер @jsunderhood @andrey_sitnik
К прошлому треду про производительность либ:
Хм. My bad. Где-то накосячил и нагрешил на React. Он вполне себе отрендерил 25к ячеек и никто не умер @jsunderhood @andrey_sitnik
10:55
Мы тут немного поговорили про оптимизацию, в дополнение расскажу 3 маленьких и очень простых, но интересных момента… twitter.com/i/web/status/1…
13:081) При вызове setState, который мы получаем из хука useState реакт проводит сравнение prev и next результата (==).… twitter.com/i/web/status/1…
13:08Это означает, что если вы сделаете что-то вроде const [a, setA] = useState(1); ... setA(1);, то компонент не будет перерендерен.
13:08Но если ваш родитель ререндерится, то child также будет ререндериться, никаких сравнений props не будет, все полнос… twitter.com/i/web/status/1…
13:08Вот тут небольшой пример codesandbox.io/s/fervent-shad…
13:08Я пару раз сталкивался с непониманием коллег, почему в стейте поведение одно, а в пропс другое. Дело в том, что одн… twitter.com/i/web/status/1…
13:08По этой причине, недостаточно просто обернуть все мемоизацией. Чтобы избежать вызова render функций, компонент долж… twitter.com/i/web/status/1…
13:08Для функциональных компонентов memo также принимает второй аргумент. Он нужен для кастомного компаратора, аналогичн… twitter.com/i/web/status/1…
13:082) Важный момент, о котором многие забывают: контексту плевать, обернут ли у вас компонент в memo или он pure. Если… twitter.com/i/web/status/1…
13:08Проверить и поэкспериментировать очень легко: codesandbox.io/s/agitated-wil…
13:08Обратите внимание, что изменение контекста не просто обновляет компонент, но он получает еще и самый последний prop.
13:083) Все привыкли использовать useEffect для сайд-эффектов, каких-то DOM расчетов. Может появиться вопрос: а почему я… twitter.com/i/web/status/1…
13:08Если хочется рассчитать ДО того, как компонент отрисуется (как раньше с componentDidUpdate), то стоит использовать… twitter.com/i/web/status/1…
13:08Hint, если в codesandbox хочется снять performance можно открыть урл, который они предоставляют:… twitter.com/i/web/status/1…
13:08useEffect: pic.twitter.com/R3xdOkEGAE
13:08UseLayoutEffect: pic.twitter.com/gPeRXhvcZo
13:08Обратите внимание на разницу в количествах и характере paint :)
13:08В @biocad_ltd, ищем QA-инженера, вместе со мной работать над системой управления лабораторным оборудованием.14:02Сейча… twitter.com/i/web/status/1…
2) Важный момент, о котором многие забывают: контексту плевать, обернут ли у вас компонент в memo или он pure. Если… twitter.com/i/web/status/1…
Напутал с ссылками на примере. Правильная ссылка вот: codesandbox.io/s/fancy-feathe…
2) Важный момент, о котором многие забывают: контексту плевать, обернут ли у вас компонент в memo или он pure. Если… twitter.com/i/web/status/1…
14:08
Для истории с контекстом правильная ссылка codesandbox.io/s/fancy-feathe…
14:08@jsunderhood Будет тред о том как стать хорошим специалистом? (не xslt 😁 спецом, а в общем)
Вчера был вопрос о развитии. У меня нет хорошего ответа на него. Поэтому дальше будет тред о том, как я представляю… twitter.com/i/web/status/1…
@jsunderhood Будет тред о том как стать хорошим специалистом? (не xslt 😁 спецом, а в общем)
14:09
Для меня есть несколько больших мазков в градациях. Джун => Мидл => а вот тут все сложнее.
14:09Сюда традиционно добавляют senior, что это человек, который может взять задачу, проанализировать, выбрать подходящи… twitter.com/i/web/status/1…
14:09Сделаю отдельные треды для развития начального и дальнейшего, сюда потом добавлю ссылки
14:09Давайте с вопросом развития начнем с простого и дальше будем двигаться к сложному. Начнем об обучении джунов. В хх… twitter.com/i/web/status/1…
14:14Школа устроена следующим образом. На входе будущие студенты решают несколько задач онлайн, затем офлайн интервью. Э… twitter.com/i/web/status/1…
14:14Как подготовиться к подобным интервью как раз писал предыдущий автор этого твиттера :)
14:14Сама школа разделена на 2 части: лекции и работа над проектом. Лекции проходят 2-3 раза в неделю.
14:14В прошлом году лекции записывали: youtube.com/watch?v=7tULJl…
Обучение идет по 2-м направлениям фронтенд и бекенд. Бек… twitter.com/i/web/status/1…
У лекций есть ДЗ. Я обычно стараюсь после выдачи ДЗ отвечать на вопросы, проводить ревью решения студента как можно… twitter.com/i/web/status/1…
14:14Список моих лекций есть здесь: xnim.ru/projects/schoo…
14:14У меня была пара веселых моментов. Провожу лекцию по базовому js, в конце даю домашку. Добираюсь до дома (мне ехать… twitter.com/i/web/status/1…
14:14Вторая история. Мои лекции часто расположены перед НГ. В таких случаях я даю дедлайн в новогодние каникулы плюс 2-3… twitter.com/i/web/status/1…
14:14После блока лекций начинается практика. Студенты делятся на группы и занимаются школьными проектами. Я в свое время… twitter.com/i/web/status/1…
14:14Эти проекты нужны, чтобы вчерашние студенты попробовали работу в команде, у них появились первые конфликты (возможн… twitter.com/i/web/status/1…
14:14В последних двух школах студенты делали проекты, которые потом нашли свое использование. В школе 2017-2018 года я б… twitter.com/i/web/status/1…
14:15Также знаю, что есть стажировки у avito start.avito.ru/tech, школа интерфейсов яндекса yandex.ru/promo/academy/… Возможно еще что-то?
14:15Не могу не упомянуть очень крутой кейс от @idelpivnitskiy youtube.com/watch?v=Kw1gQT…
Идель, привет :) Кстати, Идель т… twitter.com/i/web/status/1…
С началом пути в разработке разобрались. Дальше от средних-крепких джунов в мидлы и развитие мидлов. Это тот момент… twitter.com/i/web/status/1…
14:23В части компаний есть менторы, где-то этим занимаются тимлиды, где-то делают основательный подход с составлением ИК… twitter.com/i/web/status/1…
14:23Мне сложно дать рецепт, у меня нет правильного ответа на вопрос. Только мои личные наблюдения. Мне кажется, что раз… twitter.com/i/web/status/1…
14:23Хочешь прокачаться во фронтенд скиллах — возьми ответственность за часть проекта, стань мейнтейнером страниц или пр… twitter.com/i/web/status/1…
14:23Другой способ прокачаться — брать сложные задачи. Но это тоже определенная ответственность.
14:23Без ответственности это работает сильно хуже. Как то так:
— Привет. Я хочу развиваться давай обсудим?
— Хорошо, у н… twitter.com/i/web/status/1…
Тут также работает следующее: без желания людей насильно "развивать" их не будешь.
14:23На мой взгляд тимлид — один из наиболее заинтересованных персонажей в развитии своих сотрудников.
14:23Кроме этого, в некоторых компаниях практикуется "добровольное менторство" — когда часть более опытных сотрудников,… twitter.com/i/web/status/1…
14:23Если свести все в пункты, то:
Я хочу развиваться:
1) Брать ответственность, принимать решения
2) Участвовать в обсуждения фронтенд-группы
3) Если в компании не видно точек роста, то смотреть на опен-сорс, сообщества в своем городе
4) Если на 3-й пункт н… twitter.com/i/web/status/1…
Конечно же, эти советы будут работать, если у вас уже "набита рука" и вы без проблем делаете типовые задачи разной сложности.
14:23Если "Я хочу помогать сотрудникам в развитии", то:
1) Ненавязчиво предлагать ответственность — ни в коем случае нел… twitter.com/i/web/status/1…
3) Давать сотрудникам задания сложнее их текущего уровня.
14:23Как я пришел к таким пунктам? Вот мой личный опыт:
14:23В хх я пришел в команду поиска. Нас было 2 фронтендера. За полгода текущие задачи поиска были закрыты и я заскучал.… twitter.com/i/web/status/1…
14:23Настроили его подключение через npm, отделили от проекта, сделали сборку на gulp вместо make файла. Развили саму би… twitter.com/i/web/status/1…
14:23Затем перешел в команду мобильного сайта, где взял ответственность на архитектуру резюмебилдера на клиенте. Очень б… twitter.com/i/web/status/1…
14:23И затем перешел в проект talantix.ru, где был, по сути, создателем всей архитектуры проекта.
В конце пу… twitter.com/i/web/status/1…
С каждым разом в том числе изучал этот вопрос и приходил к мысли: "если бы не ответственность, то всегда можно было… twitter.com/i/web/status/1…
14:23Так я и пришел к выводам из начала этого треда :)
14:23Я не затронул тему развития софт-скиллов в своем рассказе, это отдельная и очень сложная тема. Ответственность в ко… twitter.com/i/web/status/1…
14:23С началом пути в разработке разобрались. Дальше от средних-крепких джунов в мидлы и развитие мидлов. Это тот момент… twitter.com/i/web/status/1…
Начало пути в разработку: twitter.com/jsunderhood/st…
О росте мидлов:
С началом пути в разработке разобрались. Дальше от средних-крепких джунов в мидлы и развитие мидлов. Это тот момент… twitter.com/i/web/status/1…
14:24
Помогите мне определиться с темой на завтра: я думал о том, чтобы рассказать о performance и клиентских метриках ил… twitter.com/i/web/status/1…
14:30Если что другая тема вполне может быть в субботу :) мне интересен порядок
14:32@m0rg0t @jsunderhood Мы в @mtdvio делаем материалы и коммьюнити про холистическое развитие (вне рамок одной компани… twitter.com/i/web/status/1…15:40
@jsunderhood Плюсую. В целом правильный общий совет.15:40Стать сильным Senior можно, если рутинно берёшь на себя зада… twitter.com/i/web/status/1…
@jsunderhood Вообще всего это будет неявно и капать по капле. Пока в один прекрасный день ты не осознаешь, что ты и… twitter.com/i/web/status/1…15:59
@jsunderhood Но при этом смотришь на других и все равно видишь что много где отстаёшь от багажа знаний других людей.
Ощущение, что «все вокруг круче меня» складывается потому что Вова умеет лучше верстать, Маша сильнее в алгоритмах,… twitter.com/i/web/status/1…
@jsunderhood Но при этом смотришь на других и все равно видишь что много где отстаёшь от багажа знаний других людей.
16:03
Сейчас направлений и специфики везде очень много. Всё знать никогда не будешь.
16:03@jsunderhood @Oleg75113370 Пару готовых рецептов подкину.16:04Общего плана про планирование карьеры, основанные на на… twitter.com/i/web/status/1…
Помогите мне определиться с темой на завтра: я думал о том, чтобы рассказать о performance и клиентских метриках ил… twitter.com/i/web/status/1…
В голосовалке победили пятничные байки :) Завтра будем говорить о разных смешных, интересных случаях из рабочей и н… twitter.com/i/web/status/1…
Помогите мне определиться с темой на завтра: я думал о том, чтобы рассказать о performance и клиентских метриках ил… twitter.com/i/web/status/1…
19:37
@vfurso @jsunderhood Повлиять на бизнес анализ, продукт, решения других отделов разработчик практически никогда не… twitter.com/i/web/status/1…20:08
# Пятница 73 твита
Сегодня травим байки о разработке!
Начнем прямо со вчерашнего фейла. У кого не бывает фейлов, тот явно что-то недоговаривает :)
Обновляю картинки-иконки в статике. Релиз выходит, и вроде бы все хорошо.
Прилетает бага. На… twitter.com/i/web/status/1…
У нас единое приложение для hh.ru, jobs.tyt.by и других доменов. На основном домене… twitter.com/i/web/status/1…
7:33Оказывается проблема с политиками кеширования, с nginx.org/ru/docs/http/n… На всех региональных сайтах политика жестч… twitter.com/i/web/status/1…
7:33Все картинки у нас запрашиваются с GET запросом, если uri не поменялся, nginx отдаст старую картинку. Сравните:… twitter.com/i/web/status/1…
7:33Причина: в большой инфраструктуре сложно держать в голове все условия и переменные :) Не забывайте про кеш.
7:33@jsunderhood Ооо! А какие отличия между сайтами на разных доменах? А как организовано? С какими проблемами столкнул… twitter.com/i/web/status/1…
Нет, про это не рассказывал. Попробую описать фактами:
@jsunderhood Ооо! А какие отличия между сайтами на разных доменах? А как организовано? С какими проблемами столкнул… twitter.com/i/web/status/1…
8:10
1) Кодовая база одна, отличия между сайтами описываются явно в коде (даже до уровня if (domain === DOMAINS.KAZAHSTAN))
8:112) Есть необходимость учитывать страновую политику: сервера, определенные законы. Например, была история, когда в о… twitter.com/i/web/status/1…
8:11Лично для меня (я не девопс все же), это главная особенность: в странах отличаются законы, эти законы необходимо уч… twitter.com/i/web/status/1…
8:113) Обычно мониторим все законы в странах и заранее пишем код. В нужный момент просто переключаем рубильник
8:114) Страновые сайты отличаются не только логикой в определенных местах, но и, например, кешированием статики, так ка… twitter.com/i/web/status/1…
8:115) Домены разруливаются на nginx, почти любой бекенд при необходимости может узнать о том, на каком сайте был вызва… twitter.com/i/web/status/1…
8:116) Каждому домену соответствует константа, констаны в том числе есть в конфигах yml, чтобы при сборке использовать… twitter.com/i/web/status/1…
8:117) Переводы хранятся в базе, каждый сервис подгружает переводы себе на старте. Используем marisa-trie структуру дан… twitter.com/i/web/status/1…
8:118) Возможно для меня привычно, но это все особенности, на первый взгляд. Возможно есть какие-то определенные вопросы?)
8:11Совсем забегался и упустил выход интереснейшего интервью с @iamakulov 😢8:31Всем любителям производительности и оптими… twitter.com/i/web/status/1…
Небольшая залипашка: matthewrayfield.com/goodies/inspec…
(нужна консоль разработчика)
Следующая занимательная история:
Теплое весеннее утро. Кто-то ползет к офису, кто-то, зевая, заваривает кофе. Приле… twitter.com/i/web/status/1…
Разработчики бегут к ноутам, начинают разбирать проблему... Все работает, все хорошо. Жалобы продолжают поступать.… twitter.com/i/web/status/1…
9:26Начинаем проверять все возможные цепочки, какие запросы уходят, что происходит. Все равно все хорошо.
9:26Потратив около 3 человеко-дня (3 разработчика на 1 день ушли в проблему), выяснилось, что им просто не повезло. Они не собачники 0_о
9:26Все дело в том, что поставщик рекламы добавил новый баннер для пользователей, рекламирующий собачий корм. Этот банн… twitter.com/i/web/status/1…
9:26Так как записи performance у нас не было на тот момент от пользователя, проблему приходилось искать руками.
9:26We are interested in what you think about your next 3-5 years.10:18What do you personally want to focus on?
This is… twitter.com/i/web/status/1…
@jsunderhood А разве сейчас не принято пихать рекламные банеры в iframe? Типа безопасность, вот это вот всё
История давняя. Именно по результатам истории приняли два решения:
1) Реклама ломать нас не должна
2) Реклама должн… twitter.com/i/web/status/1…
@jsunderhood А разве сейчас не принято пихать рекламные банеры в iframe? Типа безопасность, вот это вот всё
12:14
Пришлось отвлечься, сейчас делаем одну интересную штуку: на получение страницы создаем общий action, который инкапс… twitter.com/i/web/status/1…
12:16Когда я говорил про layout, вспомнил одну штуку: вы пользуетесь performance вкладкой чтобы оценить время исполнения… twitter.com/i/web/status/1…
12:18Кликаем на строку кода, получаем красоту: pic.twitter.com/CTmrJDtWAW
12:18С сурсмапами у меня нормально не завелось :(
12:18Детективная история. История вымышлена от начала до конца, любые совпадения абсолютно случаны. В главных ролях: ком… twitter.com/i/web/status/1…
12:41А: Сайт не работает.
С: Стандартное выяснение проблем, статусов ответа
А: Уточняют, что открывают страницу, страниц… twitter.com/i/web/status/1…
С: Передает данные КР.
КР: В консоли ничего нет.
КР: (Замечают часы в углу скриншота, грепают логи)
КР: За это вр… twitter.com/i/web/status/1…
КР: Сделайте har файл с запросами
С: рассказывает как сделать har файл
А: вот
C: эй, КР, вот har файл
КР: так, что тут у нас... Так все ж хорошо?
С: сейчас узнаем
А: Да, мы чтобы записывать har файл файрвол отключали
КР: :facepalm:
В чем соль — файрвол резал запросы и они просто не доходили до нас.
12:41Этот момент настал!12:51
Я ищу работу - HTML-верстальщик, frontend-разработчик.
Естественно, я ещё джуниор.Ссылки на р… twitter.com/i/web/status/1…
Сейчас будет сложная история с техническими подробностями. История о сложностях работы с переводами на сайте.
Исто… twitter.com/i/web/status/1…
1) Переводов больше десятка мегабайт
2) Не все переводы интерфейсные (интерфейсных только пара мегабайт), но тоже н… twitter.com/i/web/status/1…
Как решать такую проблему?
13:19Мы пришли к такой модели:
1) В реакт-компонентах появляется поле static trls поле, которое является обычной Map<Str… twitter.com/i/web/status/1…
2) В контексте храним информацию, какой язык перевода нужен (потому что может быть часть сайта на русском, а резюме — на английском).
13:193) При сборке кода babel плагин выдирает поле trls, собирает большую мапу "страница: список переводов". Этот файл п… twitter.com/i/web/status/1…
13:194) На бекендах переводы подгружаются из базы при старте и затем время от времени получают обновления. В рантайме хр… twitter.com/i/web/status/1…
13:19Кстати, плагин, который выдирает статические поля вот: github.com/hhru/babel-plu…
13:19Казалось бы, хорошее решение, легко использовать.
Все так, но в сентри начинают приходить баги, что перевода нет.
Добавляем логирование, начинаем трекать, в каких случаях происходит ошибка, что лежит в сторе, какие последние action происходили.
13:19Делаем первый заход, понимаем, что страница например bla-bla, а данные в сторе от страницы foo-bar.
13:19Разбираемся в проблеме, понимаем, что в некоторых редьюсерах данные применяются вот так: (state, action) => bla-bla… twitter.com/i/web/status/1…
13:19Quite a tricky thing in spread operator: you can spread `undefined` in object like `{...undefined}`, but you can't… twitter.com/i/web/status/1…
В чем соль 1: Оператор ... очень хитрый оператор. Я писал об этом здесь: twitter.com/xnimorz/status… И поэтому он может… twitter.com/i/web/status/1…
Quite a tricky thing in spread operator: you can spread `undefined` in object like `{...undefined}`, but you can't… twitter.com/i/web/status/1…
13:19
В чем соль 2: мы используем batch actions и делаем батчевый редьюсер. Если падает применение данных в одно из полей… twitter.com/i/web/status/1…
13:19Переводы хранятся в сторе. И по стечению обстоятельств — переводы первыми вызываются на странице. Вот они и падают.
13:19Окей, почему мы не получали правильную ошибку? Оказалось, потому что случайно поставили на promise, который обрабат… twitter.com/i/web/status/1…
13:19Вот так один неверный reject привел к долгой истории и правкам редьюсеров.
13:19Но на этом все не закончилось! Ошибка всплывает опять. Начинаем разбираться, находим проблему в фетчере и асинхронн… twitter.com/i/web/status/1…
13:19Пять подобных итераций и полгода спустя мы из-за этой ошибки отрефакторили кучу мест, каждый раз получалось ее восп… twitter.com/i/web/status/1…
13:19Немного расскажу о концепции батчевых экшенов и батчевом редьюсере в Redux
В редьюсерах у нас много полей. Я не счи… twitter.com/i/web/status/1…
TL;DR Сразу решение: gist.github.com/xnimorz/352a6c…
В коде привел объяснение подхода. Дальше в треде будет история: какую… twitter.com/i/web/status/1…
Мы сделали систему, где при SPA переходе вызывается middleware, она делает GET запрос самостоятельно на нужный урл.… twitter.com/i/web/status/1…
14:02У нас нет списка "вызови такие-то экшены при открытии такого-то урла", вместо этого, мы проходим по полям JSON и со… twitter.com/i/web/status/1…
14:02Базовый экшен — у каждого редьюсера у нас есть экшен, который занимается тем, что передает данные as is в редьюсер… twitter.com/i/web/status/1…
14:02Мы сейчас идем к тому, чтобы такие редьюсеры описывались еще проще: в конфиге стора была запись currency: typicalReducer();
14:02Таких экшенов на большой JSON получается много. Они все записываются в массив actions и затем мы делаем dispatch(actions).
14:02Мы диспатчим сразу массив экшенов, который на уровне рутового редьюсера итерируется и применяется вот так (ссылка с… twitter.com/i/web/status/1…
14:02Какие преимущества подхода:
1) Мы не завязаны на порядок применения. Либо все редьюсеры разово применились, либо н… twitter.com/i/web/status/1…
@jsunderhood Добрый вечер! Расскажите, пожалуйста, подробнее о том, как удается при таком серьезном продукте и боль… twitter.com/i/web/status/1…
У каждой команды свой продакт (1 продакт может быть заказчиком у нескольких команд). И у каждой команды свой беклог… twitter.com/i/web/status/1…
@jsunderhood Добрый вечер! Расскажите, пожалуйста, подробнее о том, как удается при таком серьезном продукте и боль… twitter.com/i/web/status/1…
17:05
У команды Поиск свой беклог, и когда она сможет взять задачу команды А — непонятно. Это бы сделало выход фичей непрогнозируемым.
17:05Вместо этого у нас единый набор технологий на большей части проектов. Где-то есть специфика (например поисковой дви… twitter.com/i/web/status/1…
17:05Тестирует задачу, пишет автотесты (иногда автотесты делаем после выхода задачи) Во время и после выхода релиза у на… twitter.com/i/web/status/1…
17:05Большое количество фичей выходит под настройкой (переключателем). Если что-то идет не так, то команде достаточно пе… twitter.com/i/web/status/1…
17:05Если все же баг случился через некоторое время после выхода задачи, то по blame видим, какая команда и назначаем на… twitter.com/i/web/status/1…
17:05И если проблема произошла на странице поиск — баг летит в команду поиск. Они, в свою очередь, могут определить чей… twitter.com/i/web/status/1…
17:05Пока вел @jsunderhood, мне сказали что бек на nodejs - это "поделка из желудей", а тут dartup.ru пров… twitter.com/i/web/status/1…
Я за желуди ¯\_(ツ)_/¯
Пока вел @jsunderhood, мне сказали что бек на nodejs - это "поделка из желудей", а тут dartup.ru пров… twitter.com/i/web/status/1…
21:56
# Суббота 103 твита
Доброе утро! Сегодня будем говорить о performance, клиентских метриках и все, что с этим связано.
6:37Я выступал на РИТ++ youtube.com/watch?v=4joeMk…, рассказывал о сборе метрик и частично затрагивал эксперименты с производительностью.
6:39Материалы по докладу: github.com/xnimorz/Fronte…
Сегодня подробнее поговорим про это.
Ссылка уже была, но она крайне хорошо коррелирует с историями, о которых поговорим сегодня.
6:39Желание трекать метрики и реагировать на них зародилось у нас очень давно. Вначале это был обычный набор метрик, на… twitter.com/i/web/status/1…
8:28Затем мы сделали более серьезный заход на эту задачу и организовали подсчет таких метрик как FMP (first meaningful… twitter.com/i/web/status/1…
8:28Дальше будут треды с подсчетом метрик.
8:28FMP — от него хотим следующего: понимание нашего critical path, количества времени которое уходит на него. Дальше… twitter.com/i/web/status/1…
9:07TL;DR: мы пришли к такому решению: gist.github.com/xnimorz/8ec4fc…
Это позволяет нам трекать critical path, понимать, когда… twitter.com/i/web/status/1…
Дальше история того, как мы к этому шли и графики, графики!)
9:07С одной стороны, FMP говорит о том, что нужно трекать, когда контент отобразился. И тогда код будет что-то вроде та… twitter.com/i/web/status/1…
9:07Offtop, но если вы сделаете блокирующий вызов для того, чтобы кеш сработал, я вас удивлю: кеш может не сработать та… twitter.com/i/web/status/1…
9:07Если затрекать такое время от gist.github.com/xnimorz/6b939a… и выводить на график, получим вот такую чушь: pic.twitter.com/j0mFLQiKek
9:07Почему чушь?
1) 99 перцентиль составляет больше 100 секунд. Представьте людей, которые настолько терпеливы? :)
2)… twitter.com/i/web/status/1…
Вспоминаем вчерашнюю историю про "сайт грузится и не работает 30 секунд". Понимаем, что если пользователям приходил… twitter.com/i/web/status/1…
9:07Почему так происходит? Если пользователь переключит вкладку, то raf не будет исполняться, пока вкладка не станет ак… twitter.com/i/web/status/1…
9:07Какое может быть решение? Трекать активность страницы!
В коде это будет так: gist.github.com/xnimorz/917a57… здесь скрипт,… twitter.com/i/web/status/1…
Насколько отличается первый и второй вариант? Вот графики:
Первый вариант 95-я перцентиль (без трека visibility pag… twitter.com/i/web/status/1…
Вот вариант, когда убираем значения, если пользователь уходил со страницы, или открывал фоновую вкладку: pic.twitter.com/z63MCQDFd0
9:07Здесь уже видим, что значения похожи на правду: 1 секунда загрузка резюме, самая тяжелая страница: 2.6 секунды.
9:07У второго варианта есть проблема. Он не трекает многих пользователей, так как один из популярных паттернов у пользо… twitter.com/i/web/status/1…
9:07Здесь может прийти идея трекать новые DOM метрики, которые уже есть в браузерах, но они также плохо учитывают неакт… twitter.com/i/web/status/1…
9:07Как научиться трекать остальных пользователей? Исполнять скрипт, который не зависит от raf 🙂
Это можем сделать, пр… twitter.com/i/web/status/1…
Это позволяет нам делать аналитику, потому что у нас уже есть renderTree.
Делаем это вот так:… twitter.com/i/web/status/1…
Если сравнить со вторым вариантом, разница оказывается не такой большой, как можно было предположить 100-300мс. А о… twitter.com/i/web/status/1…
9:07На график выводим 95-ю перцентиль. Т.е. у 95% пользователей страница отображается не дольше, чем за это время на гр… twitter.com/i/web/status/1…
9:0795" график важного контента (+/- первый экран): pic.twitter.com/RTIy4vfenp
9:0795" то же время, но с засечкой body: pic.twitter.com/ASnZ10M0A9
9:07Для сравнения вот 50 перцентиль за тоже время у body: pic.twitter.com/S3XczudxEY
9:07Эти графики не отображают мобилка \ десктоп. Но если это сделать, будет очень необычно.
9:07Вот мобилки: pic.twitter.com/X5zLAW5rIE
9:07Десктоп: pic.twitter.com/q55VrEYFoF
9:07@jsunderhood Померил посчитали, ок. Какие выводы это позволяет сделать?
Чуть дальше я расскажу, что мы делали с графиками.
А сейчас немного о том, зачем мы все затеяли.
@jsunderhood Померил посчитали, ок. Какие выводы это позволяет сделать?
10:29
Почему это важно: перед задачей исследовательского характера, у тебя обычно есть гипотезы. Они могут быть подтвержд… twitter.com/i/web/status/1…
10:29То есть, чтобы мы могли прийти к бизнесу и сказать: если мы потратим месяц разработки на улучшение загрузки вот это… twitter.com/i/web/status/1…
10:29Это наша идеальная цель. Но на пути как обычно, появилась куча уточнений.
10:29И проводить эксперименты без правильно настроенных метрик бесполезно, у нас не будет определенных зависимостей. Поэтому с метрик и начали.
10:29Дальше TTI: TL;DR: gist.github.com/xnimorz/0b6080… Мы трекаем лонгтаски, ресурсы и не отправляем TTI, если пользователь ухо… twitter.com/i/web/status/1…
11:06Изначально делали мы без visibility page API, но получили те же проблемы, что и с FMP. В коде нет raf, но есть setT… twitter.com/i/web/status/1…
11:06Поэтому добавляем API и графики также стабилизируются: pic.twitter.com/c6kmRUGSS3
11:06Чем крут этот график? у нас есть явный фаворит, оптимизацией которого нужно заниматься в первую очередь — страница вакансии.
11:06То, что эта страница будет явным аутсайдером — у нас были догадки. Замер и график позволили гипотезу подтвердить.
11:06Чтобы не писать свой код для TTI, можно использовать готовое решение от google: github.com/GoogleChromeLa…
11:07Для FID мы используем также готовое решение: github.com/GoogleChromeLa…
11:08Для framework render \ init \ hydrate time делаем просто:
ReactDOM.hydrate(root, reactRootNode, () => performance.… twitter.com/i/web/status/1…
Важное уточнение, мы считаем разницу, между началом рендера и этим колбеком.
Это нужно, чтобы каждый этап был отдел… twitter.com/i/web/status/1…
Мы используем SSR, поэтому пользователь видит страницу еще до того, как пройдет гидрейт.
11:20Как мы собираем метрики? Для сохранения данных мы делаем запрос на наш служебный урл `/stat`, в котором описываем наши метрики.
11:25Затем эти данные парсятся и отправляются в хадуп. Кроме хадупа отображаем данные в okmeter.io. Собственно, все графики оттуда.
11:25Пример такого запроса: pic.twitter.com/KbDoKfs5jx
11:25okmeter платный, но всегда можно поднять Prometheus с grafana: prometheus.io grafana.com
11:25Зачем вообще метрики на клиенте? Зачем так заморачиваться, если есть lighthouse? web page test?
11:291) Страницы динамические, на них меняется контент, есть код подрядчиков
11:292) У клиентов разные устройства. Мы получаем не репорт в вакууме, а реальные данные
11:293) Данные собираются постоянно (все обезличено), это открывает много возможностей для аналитики
11:294) Мы можем реагировать максимально быстро на деградации, как во время релиза, так и после
11:29@jsunderhood Одно не могу понят, почему при проверке сайта, всегда разные показатели получаются. По паджу все ок а… twitter.com/i/web/status/1…
Много процессов еще в системе запущено? Возможно, кто-то тянет одело процессорного времени на себя.
И опять же: у с… twitter.com/i/web/status/1…
@jsunderhood Одно не могу понят, почему при проверке сайта, всегда разные показатели получаются. По паджу все ок а… twitter.com/i/web/status/1…
12:15
Эксперименты с производительностью. В начале года мы запустили 4 эксперимента.
два на улучшение производительности… twitter.com/i/web/status/1…
Эксперименты на улучшение производительности
12:401) Используем brotli вместо gzip. Это влияет на всю статику. Точные цифры экономии в Kб не вспомню, но это >100 Кб.
12:402) Используем кеширование через Service worker
12:40На технических измерениях во время разработки, профит был заметен. Когда раскатили на клиенты большой производитель… twitter.com/i/web/status/1…
12:40Мы сделали два вывода:
1) Нужно будет повторить эксперименты с более сильной оптимизацией
2) На небольшие оптимизац… twitter.com/i/web/status/1…
Затем мы запустили 2 эксперимента на деградацию. Эксперименты на деградацию нужно запускать очень осторожно, потому… twitter.com/i/web/status/1…
12:401) Мы замедляли инициализацию наших компонентов (TTI)
2) Увеличили размер загружаемого css (FMP)
Про инициализацию компонентов. Мы сделали небесконечный цикл, который тормозил инит каждого компонента на небольшое… twitter.com/i/web/status/1…
12:40Какое же было удивление, что бизнес-метрики ничего не почувствовали. Мы запускали эксперимент несколько раз (на раз… twitter.com/i/web/status/1…
12:40Этот эксперимент позволил нам сделать вывод: пользователям главная ценность _нашего_ сайта — это возможность читать… twitter.com/i/web/status/1…
12:40Так как текстового контента много, они не замечают, что сами компоненты становятся интерактивными через некоторое время.
12:40Подтвердил нашу гипотезу эксперимент с увеличением загружаемого css. Это напрямую влияло на FMP. В бизнес-метриках… twitter.com/i/web/status/1…
12:40Результаты экспериментов получились такие:
1) Наиболее важный параметр, на котором нам нужно сосредотачиваться FMP.… twitter.com/i/web/status/1…
К прямой зависимости (некоторой формуле) денег от производительности мы, к сожалению, не пришли. Нашли только харак… twitter.com/i/web/status/1…
12:40Что дают нам графики и подсчет метрик
13:211) Триггеры: если мы достигаем пика в 5/10 секунд (в зависимости от метрики), то к нам в чат прилетает сообщение о… twitter.com/i/web/status/1…
13:212) Динамика релиза: Как только выходит релиз мы видим на графике все деградации и оптимизации. Если деградация боль… twitter.com/i/web/status/1…
13:213) Также мы трекаем данные с клиента для аналитики: мы можем посчитать и сравнить метрики для части пользователей (… twitter.com/i/web/status/1…
13:21Может появиться вопрос, а почему SSR за оптимизацию производительности не считаете?
Почему с ним не проводили экспериментов?
>>>
Я склоняюсь к тому, что SSR крайне важен, чтобы на сайте, который доступен неавторизованному пользователю его отклю… twitter.com/i/web/status/1…
13:25Я писал, что можно не получить профитов от кеширования:
Вот статья первая статья, для меня оказалась крайне полезн… twitter.com/i/web/status/1…
TL;DR: Используйте Cache API для статики в Service Worker. Этим вы экономите время исполнения кода, улучшаете TTI.
14:06Дело в том, что не все браузеры кешируют файлы меньше 1Кб. За счет этого мы можем не получить профита от того, что… twitter.com/i/web/status/1…
14:06Как устроено кеширование в хроме? Здесь на эту тему хорошо написано: v8.dev/blog/code-cach…
14:06Вся информация дальше — это компиляция из этих статей. Эдакий TL;DR. Справедливо для chromium браузеров
14:06У нас есть 3 способа "запуска" кода. Cold run, warm run и hot run: pic.twitter.com/0ihk6hR6Af
14:06Cold run — пользователь пришел впервые. Браузер скачал файл, скормил его компилятору (транспилятору)
14:06Warm run — пользователь пришел повторно. Браузер взял код из кеша, скормил его компилятору.
14:06Hot run — пользователь пришел в 3-й раз за последние 72 часа.
Браузер взял код и метаданные из кеша. Метаданные де… twitter.com/i/web/status/1…
Всем хочется исполняться на в hot run версии. Очевидно, что она экономит время.
14:06Первый способ экономить время — не пишите код ¯\_(ツ)_/¯
Кроме того, не забывайте про etag и заголовки для кеширования кода.
Есть интересный хак, чтобы забустить hot run. Используйте Cache API от Service worker
14:06"Магия" здесь в том, что файл, кешированный сервис воркером не будет парситься повторно, метаданные будут присутствовать.
14:06Вот так сейчас выглядит загрузка hh.ru: pic.twitter.com/tbwFYUqV8U
14:06Еще одна ссылка: youtube.com/watch?v=bZfULA…
Здесь рассказываю о способах увеличения производительности и затрагиваю тему кеширования.
Еще приведу доклад @iamakulov о performance: youtube.com/watch?v=iEv1rF…
14:19FMP — от него хотим следующего: понимание нашего critical path, количества времени которое уходит на него. Дальше… twitter.com/i/web/status/1…
(1/2) Ссылки на темы за сегодня:
Кеширование в chrome: twitter.com/jsunderhood/st…
Профит от графиков:… twitter.com/i/web/status/1…
FMP — от него хотим следующего: понимание нашего critical path, количества времени которое уходит на него. Дальше… twitter.com/i/web/status/1…
15:07
Я выступал на РИТ++ youtube.com/watch?v=4joeMk…, рассказывал о сборе метрик и частично затрагивал эксперименты с производительностью.
(2/2) Зачем собирать метрики: twitter.com/jsunderhood/st…
Зачем мы все затеяли: twitter.com/jsunderhood/st…
TTI… twitter.com/i/web/status/1…
Я выступал на РИТ++ youtube.com/watch?v=4joeMk…, рассказывал о сборе метрик и частично затрагивал эксперименты с производительностью.
15:07
Пара причин для этого:
1) SEO — поисковым ботам нужно что-то индексировать
2) отсутствие SSR заметно оттягивает вре… twitter.com/i/web/status/1…
@jsunderhood какой есть хороший ssr для реакта кроме некста?
Я не могу взять и сказать: используйте next.js, gatsby или react-static. Зависит от решаемой задачи.
@jsunderhood какой есть хороший ssr для реакта кроме некста?
17:03
Готовые решения имеют свои ограничения. Мы сделали свое простое решение без излишеств twitter.com/i/web/status/1…
gats… twitter.com/i/web/status/1…
17:03react-static никогда не пробовал, говорят удобен для статических сайтов. Но
1) Статический сайт можно сделать на то… twitter.com/i/web/status/1…
@jsunderhood Ну Некст используется на проекте главным образом для seo оптимизации реакт приложенияА вот csr сдел… twitter.com/i/web/status/1…
Классный вопрос. На самом деле "все очень плохо".
Мои коллеги смотрели, какие деградации для SEO будут, если исполь… twitter.com/i/web/status/1…
@jsunderhood Ну Некст используется на проекте главным образом для seo оптимизации реакт приложения
А вот csr сдел… twitter.com/i/web/status/1…
18:25
И пара статей:
Для гугла: developers.google.com/search/docs/gu…
Для яндекса: yandex.ru/support/webmas…
18:25Коротко: что-то работает, но что получится — на ваш страх и риск.
18:25# Воскресенье 60 твитов
@jsunderhood @andrey_sitnik Для статического сайта, если не реакт, то другой шаблонизатор. Соль в том что (п)реакт… twitter.com/i/web/status/1…
Здесь есть несколько особенностей:
1) Полностью статический сайт всегда можно прекомпилировать и получить на выход… twitter.com/i/web/status/1…
@jsunderhood @andrey_sitnik Для статического сайта, если не реакт, то другой шаблонизатор. Соль в том что (п)реакт… twitter.com/i/web/status/1…
7:40
2) Иногда сайт нельзя полностью прекомпилировать. Например, будут небольшие кусочки типа "комментарий пользователя"… twitter.com/i/web/status/1…
7:403) Главная же проблема в реакте для такой задачи — что на клиент обычно поставляют весь бандл кода, который большую… twitter.com/i/web/status/1…
7:40А полезного кода, который отправит и красиво добавит комментарий без перезагрузки страницы — это от силы останется… twitter.com/i/web/status/1…
7:40Если делается такой сайт, а условный (п)реакт, вью хочется, я бы рассматривал такой вариант:
Сделайте 2 точки вход… twitter.com/i/web/status/1…
Это позволяет вам не делать лишние телодвижения на клиенте. Код, который ничего не делает, на клиент не попадет.
К… twitter.com/i/web/status/1…
Единственное, еще и сама библиотека имеет свой размер. Например, вот реакт-дом: bundlephobia.com/result?p=react…
7:40@jsunderhood В скраме дедлайн раз в две недели, а при канбане в умелых руках аврал и дедлайн каждый день, какое уж… twitter.com/i/web/status/1…
Любой инструмент можно превратить в кошмар исполнителей. При удобном инструменте, который понимают, принимают и не… twitter.com/i/web/status/1…
@jsunderhood В скраме дедлайн раз в две недели, а при канбане в умелых руках аврал и дедлайн каждый день, какое уж… twitter.com/i/web/status/1…
7:56
Поэтому Я бы сказал, что это другая проблема. Проблема "эффективных" менеджеров. Такие "друзья" могут встречаться ч… twitter.com/i/web/status/1…
7:56Если у вас скрам, то не будем закладывать баги и мелкие задачи, вместо мелкой задачи возьмите пару фич. А потом на… twitter.com/i/web/status/1…
7:56Если у вас waterflow, то дедлайн будет идти только от такого менеджера.
7:56Если канбан, то менеджер не будет делить задачи по классам поставки — "ха, зачем? вы вот эту задачку закончили за 3… twitter.com/i/web/status/1…
7:56В канбане такой "эффективный" менеджер не хочет разбираться, что у команды есть, например 3 класса поставки (сроки… twitter.com/i/web/status/1…
7:56Если вы хотите попробовать канбан, но боитесь такого подхода со стороны менеджеров: оставьте оценку задач и прогова… twitter.com/i/web/status/1…
7:56Мы успели обсудить много тем за неделю.
Браузерные плагины, процессы, kanban, визуализация, иконки, миграция стеко… twitter.com/i/web/status/1…
Сегодня не будет много твитов. Предлагаю поговорить на ваши темы. Если вам интересно какое-то направление, какая-то… twitter.com/i/web/status/1…
7:57@jsunderhood Берём приложения на React, и делаем что хотим, а всякие там комментарии и другие отчуждаемые элементы… twitter.com/i/web/status/1…
Еще один вариант через server side includes :)
@jsunderhood Берём приложения на React, и делаем что хотим, а всякие там комментарии и другие отчуждаемые элементы… twitter.com/i/web/status/1…
8:29
@jsunderhood Если доступа до ngnix нет или не надо - React-prerendered-component делает ровно тоже самое через Stre… twitter.com/i/web/status/1…8:29
@jsunderhood Спасибо за продуктивную неделю! Вопрос: какой подход на собеседовании для кандидатов вы считаете наибо… twitter.com/i/web/status/1…
Я занимаюсь собеседованиями в HH уже 3 года без одного месяца :) Сейчас наше техническое интервью — это часть вопро… twitter.com/i/web/status/1…
@jsunderhood Спасибо за продуктивную неделю! Вопрос: какой подход на собеседовании для кандидатов вы считаете наибо… twitter.com/i/web/status/1…
8:43
За это время мы несколько раз переделывали наш подход к собеседованиям, потому что всегда "что-то не то". Был этап,… twitter.com/i/web/status/1…
8:43Каждый раз, когда меняли собеседование мы в том числе пытались оценить: насколько подход удобный? Насколько собесед… twitter.com/i/web/status/1…
8:43Сейчас наше собеседование состоит из 3 частей. Разговор о прошлом опыте и об удобных процессах в компании для канди… twitter.com/i/web/status/1…
8:43В техническом интервью мы всегда хотели понять: умеет ли рассуждать и решать проблемы кандидат?
8:43Нас очень вдохновила вот эта статья от @vas3k: vas3k.ru/inside/46/
8:43В последней итерации мы сделали переходы между разговором о прошлом опыте и техническом интервью в виде небольшого… twitter.com/i/web/status/1…
8:43Но не все так хорошо как на бумаге. Например, мы периодически скатываемся только в технические вопросы. Есть немало… twitter.com/i/web/status/1…
8:43Есть кейсы успешных собеседований. И я прям рад во время таких интервью: мы разговариваем с кандидатом о его опыте.… twitter.com/i/web/status/1…
8:43Например, кандидат делал обработку табличных данных, как в гугл доках.
Мы разговариваем об этой специфики. Затраги… twitter.com/i/web/status/1…
Когда наступает в нашем воркфлоу этап технического интервью мы просто говорим о паре вещей важных для нас (например… twitter.com/i/web/status/1…
8:43Мне кажется, у большинства нас есть примеры задач, который нас драйвили. Рассказывайте об этом на собеседованиях. И… twitter.com/i/web/status/1…
8:43Также у меня есть пара провальных опытов, но уже в качестве собеседуемого. Самая главная боль — когда собеседующему… twitter.com/i/web/status/1…
8:43И второй: когда собеседующий считает, что ответ должен быть не просто однозначным, но еще и слова должны быть точь-… twitter.com/i/web/status/1…
8:43@jsunderhood Полностью согласен. Я проходил такое собеседование: двое интервьюеров и ноутбук с заданиями. Было не п… twitter.com/i/web/status/1…9:37
@jsunderhood Самым интересным и эффективным до сих пор считаю способ с пробным днём в компании (это не так легко ор… twitter.com/i/web/status/1…9:42
@maRx_flowers @jsunderhood Ещё веселее когда:
Я с таким, благо, не сталкивался 🙂
@maRx_flowers @jsunderhood Ещё веселее когда:
9:46
@maRx_flowers @jsunderhood Тестовый день — супер. Можно понять не только круг задач, но и присмотреться к обстановк… twitter.com/i/web/status/1…11:56
@sexymuhamedik @jsunderhood В реакт бандл SSR встроен из коробки, хоть экспрессом раздавай, ещё и производительней next будет.12:07
@almost_bergman @jsunderhood У меня была два таких дня и оба были успешные(получал оффер). В одной из компаний этот… twitter.com/i/web/status/1…12:07
@maRx_flowers @jsunderhood а в чём поинт пробного дня? ты вряд ли сможешь сделать какую-то задачу (в сам проект ещё… twitter.com/i/web/status/1…
Тут должен процесс у работодателя быть настроенным. Чтобы человек познакомился с командой и поковырялся в небольшой… twitter.com/i/web/status/1…
@maRx_flowers @jsunderhood а в чём поинт пробного дня? ты вряд ли сможешь сделать какую-то задачу (в сам проект ещё… twitter.com/i/web/status/1…
12:09
@YouSysAdmin @maRx_flowers @jsunderhood Основной гайдлайн в Майкрософте нынче - задачи на интервью должны быть напр… twitter.com/i/web/status/1…12:54
@7rulnik @jsunderhood @YouSysAdmin @maRx_flowers Как и везде, кандидат мучается - а мы издеваемся ;)
Не могу не ретвитнуть 😀
@7rulnik @jsunderhood @YouSysAdmin @maRx_flowers Как и везде, кандидат мучается - а мы издеваемся ;)
13:25
@7rulnik @jsunderhood @YouSysAdmin @maRx_flowers А если на серьезных щах, то кандидат драйвит, а интервьюер помогае… twitter.com/i/web/status/1…
Хороший тред о собеседовании-задаче 🙂
@7rulnik @jsunderhood @YouSysAdmin @maRx_flowers А если на серьезных щах, то кандидат драйвит, а интервьюер помогае… twitter.com/i/web/status/1…
13:35
@jsunderhood 1. Зачем разработчику математика? (Ответ «не нужна» не принимается)
Какие софт-скиллы она тренирует?… twitter.com/i/web/status/1…
Какие софт-скиллы она тренирует?
Расскажу одну историю: когда я учился в 11 классе, я брал уроки репетиторства у вузовского преподавателя высшей мат… twitter.com/i/web/status/1…
14:22В самой олимпиаде занял первое место, но как подойти к задаче не осознал.
На уроке разговорились с преподавателем… twitter.com/i/web/status/1…
К концу занятия (1.5) человек, у которого не было бекраунда в разработке дал четкий алгоритм, который решал задачу оптимальным способом.
14:22Математика — это не только про найти интеграл.
Это навык решать задачи, оценивать их и оптимизировать. А иксы ли у… twitter.com/i/web/status/1…
В той же высшей математике исходя из входных данных можно не знать \ забыть алгоритм нахождения интеграла — но его можно вывести.
14:22Аналогично и в разработке.
И да — это нормально считать иначе :)
@jsunderhood 1. Зачем разработчику математика? (Ответ «не нужна» не принимается)
Какие софт-скиллы она тренирует?… twitter.com/i/web/status/1…
Пересечение и взаимное влияние я наблюдал во время своей работы.
Категоризовать: "ты однозначно софт скилл, ты — хард скилл" — мне сложно.
Например: обучаемость? она тоже бывает очень разная. Это может быть идеальная память на механические вещи. А может… twitter.com/i/web/status/1…
14:30Но сказать — первый плохой, второй хороший — нельзя. У этих людей обучаемость прокачена по разным "веткам развития"… twitter.com/i/web/status/1…
14:30@jsunderhood 1. Зачем разработчику математика? (Ответ «не нужна» не принимается)
Какие софт-скиллы она тренирует?… twitter.com/i/web/status/1…
Мне удалось поработать с разными HR менеджерами. Некоторым было "глубоко все равно", что происходит в процессах ком… twitter.com/i/web/status/1…
14:35Такие _хорошие_ hr менеджеры, могут выступать не просто консультантом \ источником бюджета, но и драйвером в прокач… twitter.com/i/web/status/1…
14:35Затем выработать рекомендации, помочь с поиском подходящих курсов.
В общем, да, роль HR отдела может сильно варьироваться в компании.
14:35Мое выступление на тему "Есть ли жизнь после Senior?" в Харькове подъехало:15:46
youtu.be/CiSLUYwdyac?li…Смотрите, кри… twitter.com/i/web/status/1…
Спасибо, что были со мной эту неделю 🙂
С вами был @xnimorz . В своем твиттере я пишу редко и обычно связанное с раз… twitter.com/i/web/status/1…
И большое спасибо @DmitryMakhnev и @rage_monk вы очень прокачали мой доклад и сделали его круче :)
15:48# Ссылки
github.com
- https://github.com/sveltejs/svelte/issues/3671
- https://github.com/sveltejs/svelte/issues/3649
- https://github.com/snipsco/yett/blob/master/src/monkey.js#L4-L7
- https://github.com/hhru?utf8=%E2%9C%93&q=babel&type=&language=
- https://github.com/hhru/eslint-config-hh
- https://github.com/hhru/frontik
- https://github.com/hhru/babel-plugin-static-value-extractor
- https://github.com/xnimorz/FrontendConf-2019-materials
- https://github.com/GoogleChromeLabs/tti-polyfill/
- https://github.com/GoogleChromeLabs/first-input-delay
www.youtube.com
- https://www.youtube.com/watch?v=0cFoEPhv2II
- https://www.youtube.com/watch?v=7tULJl-eW2s&list=PLGn25JCaSSFQQOab_xMXI3vJ0tDUkFaCI
- https://www.youtube.com/watch?v=Kw1gQTqFPVY
- https://www.youtube.com/watch?v=4joeMk5v8Rw
- https://www.youtube.com/watch?v=bZfULA8PPgE
- https://www.youtube.com/watch?v=iEv1rFujYm4
gist.github.com
- https://gist.github.com/xnimorz/8dfe0c5135315c306e3ddf7a9cbf8808
- https://gist.github.com/xnimorz/543dc894ce0c98168f4cb3dd6b7c3e2e
- https://gist.github.com/xnimorz/2a62834971f8fd7911fd809c2e8bbd38
- https://gist.github.com/xnimorz/5a2783da12e8e31b8fb0c02a8064f5a7
- https://gist.github.com/xnimorz/352a6c8cca7b9967ffc3bee2e50edaf0
- https://gist.github.com/xnimorz/8ec4fc21f0d7da855b772c6404b733f3
- https://gist.github.com/xnimorz/6b939a15050000b853e73fb33af5114f
- https://gist.github.com/xnimorz/917a57c624a24923dee002be5edce24d
- https://gist.github.com/xnimorz/0b608077a2b190e16904a134765e6dc3
other
- http://hh.ru/
- https://chrome.google.com/webstore/detail/%D0%BA%D0%BD%D0%BE%D0%BF%D0%BA%D0%B0-%D0%B8%D0%BC%D0%BF%D0%BE%D1%80%D1%82%D0%B0-%D1%80%D0%B5%D0%B7%D1%8E%D0%BC%D0%B5-%D0%B2-t/njiecgjpookikhndnojndhfidpmjpakj
- https://chrome.google.com/webstore/detail/hh-chat/ggkobleeillcknceaalmjhiegpkicmpa
- https://codesandbox.io/s/svelte-input-mask-demo-xurgr
- https://codesandbox.io/s/fervent-shadow-6emy1
- https://codesandbox.io/s/agitated-wilbur-997j4
- https://codesandbox.io/s/fancy-feather-3smxo
- https://stackoverflow.com/questions/27657617/how-to-disable-google-chrome-extension-autoupdate
- http://youtube.com/watch?v=AEhO2q2fx0Y
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/require-sri-for
- https://holyjs-moscow.ru/2019/msk/talks/5ahmolcm5xcbo4f8wpcfrk/
- https://holyjs-moscow.ru/people/2eqmuhqcu9gmrext4llwgq/
- https://tech.hh.ru/about.html
- http://a11y-guidelines.orange.com/web_EN/exemples/simple-menu/simple-menu.html
- http://w3.org/TR/wai-aria-practices/examples/listbox/listbox-collapsible.html
- https://gist.githubusercontent.com/xnimorz/e0f107f67d7ce2211dab59976389b6d9/raw/91b1153601cf03d6e69fb8c89d38f37ff0b4a58b/icon.svg
- https://codepen.io/sosuke/pen/Pjoqqp
- https://css-tricks.com/solved-with-css-colorizing-svg-backgrounds/
- https://okmeter.io/
- http://okmeter.io/
- https://xnim.ru/projects/school-lectures
- https://start.avito.ru/tech
- https://yandex.ru/promo/academy/shri
- https://yandex.ru/support/webmaster/robot-workings/ajax-indexing.html
- http://talantix.ru/
- http://jobs.tyt.by/
- https://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_cache_key
- https://matthewrayfield.com/goodies/inspect-this-snake/
- http://career.ru/
- https://prometheus.io/
- https://grafana.com/
- https://v8.dev/blog/code-caching-for-devs
- https://developers.google.com/search/docs/guides/fix-search-javascript?hl=ru
- https://bundlephobia.com/result?p=react-dom@16.11.0
- https://vas3k.ru/inside/46/
- https://youtu.be/CiSLUYwdyac?list=PLnkLrCUX4Qh5q2yvd-mfq2kD2DgMSCahO