Архив недели @thekashey
Понедельник
Говорят понедельник - день тяжелый. И как же хорошо что он для меня уже закончился.
Так что всем привет, давайте не будет покуда гадать кто же ведет @jsunderhood, давайте попробуем отгадать откуда 😉
Так и знал что не надо было крокодила добавлять.
Но на всякий случай - крокодилов в Сиднее нет, они обитают немного севернее, где по теплее будет (звучит странно?)
А вот кто тут есть, так ребята с шестью лапами. Например это фото я сделал у себя на кухне.
И оно с руку!
Насчет "звучит странно" - кто помнит странную такую песенку из детства:
- Это было прошлым летом, В середине января
Так вот, Мэри Поппинс была написана в Сиднее, и у нас вот как один день назад закончилось лето.
В любом случае на этой неделе вас ожидают:
- много красивых фото
- парочка историй от бывалого
- тройка советов
- и немного javascript
Но самое главное - практически весь "ваш" день я буду спать, а просыпаться буду ровно в полночь по Москве.
Поехали?
Тред (@thekashey)
Итак, будем знакомы - на этой неделе с вам @theKashey
Карьера моя как fulltime js dev началась, если не ошибаюсь в 2012 году в @yandexmaps, и последние три года я работаю в @Atlassian. И не в @Jira, и не в @Confluence, а в "коммерсе"
Так что, как и все вы, я могу не любить Jira
Вообще моя профессиональная деятельность началась еще в 1999 году - C++, VoIP, OpenGL и GameDev.
В 2008 году я в первый раз начал работать на "сайт" - @wikimapia (C++)
Потом @gdeetotdom (PHP), там же переключился более на "карты"
Потом @yandex, и с тех пор я 100% js dev
Я был тут, когда лучший редактор js был NotePad++
Я был тут, когда выпустили prototype.js
Я был тут, когда jQuery вызывал восторг
Я был тут, когда мы делали просто ужасные вещи (зачем!!!)
И все еще тут. Стрижка только началась.
Про бытность мою в Яндексе скажу только одно - никогда на свете, не работайте дети, не работайте дети, 5 или 6 лет над одним продуктом.
Это не полезно ни вам, ни продукту.
Очень важно выходит из своей зоны комфорта.
(хотя да - в Яндексе было очень даже ничего)
Что я могу сказать про работу в Сиднее?
Процессы совершенно по другому поставлены. И люди другие. И отношение другое. Особенно в work/life балансу.
Тут любят любить жизнь, а не работу.
Примерно вот так -
medium.com/@antonkorzunov…
Тред (@thekashey)
Кто-то мечтает уехать из России, устроится в крутой западный стартап, но думает что это очень сложно - это не совсем так.
На самом деле вас там только и ждут - разработчиков реально не хватает, тем более хороших, и если вы один, или одна из таких - оторвут с руками!
Возьмем меня:
- я старый, 82 года выпуска
- у меня нет высшего образования
- у меня трое детей
- еще и домашние животные связывают по рукам и ногам
- ипотека!
не программист, а недвижимость!
- в Финляндию? Так клево, но язык сложный
- в Германию? Я как-то не очень шпрехаю
- в Англию? Льет как в Питере!
- в США? Кому ты там без образования нужен!
- в Японию? Только через мое харакири!
- Привет, Австралия на проводе, что значит далековато?
На самом у нас были друзья в Австралии, они получили Permanent Residency и умотали. Английский язык почти год ботали.
Мы знали что дело это не простое, но там у них классно.
Потом узнали, что в Сиднее Яндексоидов уже просто толпа, и "профессиональная иммиграция дело простое"
- Приезжаешь
- 2 года, компания говорит - чувак ок, и ты получаешь PR
- еще 2 года и у тебя местный паспорт в кармане
Сейчас правила ужесточили - чтобы получить PR надо будет сдать тест на знание английского языка, доказать что ты его немного знаешь. Совсем чуть чуть (50 PTE, 6 IELTS)
Чтобы пройти интервью знание языка НЕ НУЖНО!
Это так и написано в наших правилах - обращаем внимание на то что к работе относиться, а что не относиться - то не относится.
Если вас можно понять, можно вести разговор - то и ок, уже на месте нормально говорить научишься.
Примерно тоже самое относится к детям - мои вышли в школу через неделю, без какого либо знания языка.
Через полгода они свободно на нем говорили, через два года они говорят в принципе практически только на нем.
Так что не надо боятся.
Попасть сюда действительно легко, как и "остаться" есть только одна проблема - мы на острове, все очень далеко (в том числе AWS us-east ), хрен выберешься :)
Тред (@thekashey)
На часах 9 вечера, а это значит что на сегодня все. Тут принято рано ложиться (в 8!), и рано вставать - не позже 7, а лучше в 6, чтобы перед школой/работой было время на семью, или покупаться сходить.
А пока вы будете спать, напишу ка я про приемочное тестирование в @Atlassian
Вторник
Наступает ночь, просыпается мафия.
И да, давайте в начале про опенсорс, так как это очень сильно изменило мое отношение и к коду, и к жизни.
Мне этот оперсорс как-то был не нужен - намного интереснее было делать конечные продукты и зарабатывать на этом реальные деньги.
Так для примера - в лучшие годы @eSosedi приносили $100.000 в год, после налогов. И лично мне.
В Яндексе опенсорс тоже был так себе распространен.
В Яндексе было банально все свое - или что-то уже придуманное до нас (и для нас), или почему бы не сделать самим?
У нас был свой js бандер - ymb/yms. У нас был свой линтер - JSCS был написан за соседним столом (но мы его НЕ использовали).
В общем можно было просто работать!
По приезду пришлось окунуться в другую экосистему, построенную на вообще-то "стандартных" инструментах. Которые (внезапно?!) НЕ РАБОТАЛИ!
Я долго и упорно страдал от proxyquire, пока не написал proxyquire2("оригинальный" не принял PR). Потом еще один и еще один. И понеслась.
Пришлось заодно написать пару статей про nodejs dependency mocking, разобраться в вопросе, и вообще в принципах построение "хороших библиотек".
Особого распространения проект не получил, но все кто пользуется (и не использует Jest) - пищат от восторга.
github.com/theKashey/rewi…
Вторым делом я напоролся на проблему контрола фокуса, которая не была проблемой в jQuery, там с этим все окей, но в React экосистеме была большая дыра.
Так на свет появился focus-lock, react-focus-lock, dom-focus-lock и даже vue-focus-lock.
github.com/theKashey/reac…
Потом, как и многие из нас, я споткнулся о React-Hot-Loader, и в итоге практически в одиночку тяну его уже более двух лет.
Прекратите его использовать, пожалуйста, замена уже подросла - github.com/gaearon/react-…
На самом деле "проблемные" библиотеки очень полезные - к вам приходят разные люди, жалуются, вы с ними знакомитесь, общаетесь, лучше понимаете проблему, лучше понимаете людей.
Главное ко всему подходить позитивно.
С тех пор режим найти-проблему/найти-решение поставлен на поток.
Главное научится видеть проблему, и не соглашаться с предложенным решением.
Второй плюс - нельзя взять и выпустить новую библиотеку. Надо в начале доказать себе и людям почему твоя версия более правильная.
Так я начал писать статьи, и в принципе выправлять свой английский. И то и другое до сих пор ужасно, но СИЛЬНО лучше чем в начале.
За первый год я написал больше чем за 30 лет до этого, и мне это начало нравится. Заодно это был самый простой способ общения с командой - дать им простыню текста и сказать - читай..
Читать набралось уже много -
dev.to/thekashey/me-a…
(но никто не читает)
Сейчас я или могу ответить на любой вопрос, или могу дать почитать свою статью на тему, или что-то сам уже читал по тебе, копая материал, и скину ссылку.
В итоге сейчас я "technical representative", а не "разработчик" - моя работа следить чтобы все винтики и шестеренки крутились
И на этой теме пора переходить в приемочному тестированию, которое я обещал вчера.
Тред (@thekashey)
Итак, вы сделали то, что менеджер вас попросил и хотите это зарелизить. Святое дело, только как это сделать?
У нас тут есть аш три разных способа!
1, самый популярный - просто мержим в мастер. Далее CI/DI и максимум через полчаса вы в продакшене.
"Правильно" мержить, так чтобы твой "зеленый" билд не уронил мастер нам помогает landkid
github.com/atlassian/land…
2, самый древний - это когда раз в неделю/месяц/квартал выпускается новая коробочная версия 357.0, и отправляется клиентам.
Скучно, но очень надежно.
3, золотая середина - это когда релиз происходит один раз в день.
Все десятки микросервисов и вроде как "отдельных" продуктов деплоятся в специальный env, тестируются как одно целое, и если все окей - уходят в прод.
Если нет - приходите завтра.
С финансами по другому нельзя - некоторые "сервисы"(например по подсчету налогов) поставляются "другими компаниями" как черные боксы, и... в общем с этим шутки плохо.
SOX Compliance очень сильно ограничивает что мы можем делать с продом.
en.wikipedia.org/wiki/Sarbanes–…
Но на этом дело не заканчивается - после выкладки запускается PDV, Post Deployment Verification, которое проверяет что система "на самом деле" работает (а не с этими вашими моками).
Чуть что не так - rollback.
После этого за системой следит "Semantic Check" - простые браузерные тесты, которые запускаются каждые 5 минут
Вот только этого совсем недостаточно чтобы построить даже чуточку надежное приложение.
Нужно добавить немного "до" выкладки, и надо бы добавить немного "после".
Это долгая история с кучей ошибок сделанных по пути, но если кратно - YBIYRI( You Build It You Run It)
А как это сделать, если неизвестно что происходит в глубине проекта?
Так что начинается веселая история с аналитикой, мониторингом, SLI и SLO.
Банально надо "измерять" каждый бизнес процесс - он должен не только проходить тесты, но и РАБОТАТЬ!
И нам пришлось потратить много времени, чтобы изменить философию с разработки "больше тестов зеленых и разных" до реального понимания и отслеживания бизнес процессов (и других проблем в рантайме)
Тред (@thekashey)
Текущая философия очень проста: не надо делать плохо, надо делать хорошо.
Проще сказать, чем сделать
Что такое плохо: когда SLO просран, когда клиент не доволен, когда время требуемое на поддержку превалирует над временем доступным для разработки.
Что такое хорошо: когда у разработчик не может положить прод, когда результату работы можно доверять, когда не надо переписывать все заново через полгода-год.
И на все три средства
- feature flags чтобы "безопасно" включать/выключать функционал. Просто, дешево, сердито.
Мы используем LaunchDarly для всего этого
launchdarkly.com
- изоляция компонент. Это и монорепы и просто компонентный подход.
За "качеством" следят различные инструменты, в том числе специально обученные люди с дубинками
reactconfau.com/talks/the-trag…
youtube.com/watch?v=UsEaqe…
- тот самый мониторинг, чтобы понимать взлетело или нет.
Тут было МНОГО различных попыток и разные команды использую различные подходы, и какой из них в итоге приживется сказать сложно.
Давайте рассмотрим каждый из них.
Тут главное помнить что результат всегда и везде один - какой-то дашборд, какие-то графики, какие-то циферки. Меняется только "транспорт"
Аналитика версия 1/2 - вы просто шлете некий event с неким value. Никаких стандартов. Шли что хочешь, твои проблемы.
Для большинства это и есть аналитика, и так оно не работает
Аналитика версия 3 - вы шлете UI/Track/Operation event, с четкой структурой. Каждое событие должно быть описано в "Регистре", где будет сказано что это такое, кто его шлет, какие доп аргументы, и вообще зачем это событие существует.
И сразу появился смысл.
"Бизнес процессы" - некий React компонент дает им старт, некий другой компонент завершает с неким статусом. Если компонент был просто unmounted - это abort.
И стало просто "изолировать" такие процессы и чуть более правильнее их проектировать
"Циклы" - которые слушают любые события от систем описанных выше и как-то на них реагируют.
Например если пришло screenEvent:paymentDetailsForm - значит кто-то начал процесс изменения своих данных, и каким либо другим событием как либо закончит.
Достаточно просто построить модель того по какому событию процесс начинается, по какому завершается.
В основе сидит классический CEP
en.wikipedia.org/wiki/Complex_e…
Единственная проблема - понять "где мы", и как-то без ошибок отобразить "виртуальный" бизнес процесс на реальное приложение.
Виртуальный - потому что его нет коде, мы его придумали.
Решили что он у нас есть, и вот как он работает. Это как проблема курицы и яйца.
Если вам хочется спать - у вас будут слипаться глаза. Если у вас слипаются глаза - значит вам хочется спать!
Логика! Интуиция! Знамения! Приметы! И Duck Typing.
Я тут недавно написал реально большую, и сложную к пониманию, статью на эту тему
dev.to/thekashey/the-…
Почему DuckTyping? Обратимся к CEP еще раз:
Среди входящих событий система наблюдения может получить
- звонят колокола церкви
- появление мужчины в смокинге с женщиной в белом платье
- в воздух бросают рис
По этим событиям система наблюдения может вывести «событие»: свадьбу.
- !!x
- x.forEach
- 'length' in x
🙀 Да у нас тут array!
Поиск "важных" принципов в случае DuckTyping и CEP примерно одинаков. И в обоих случаях есть вероятность сделать:
- GooseTyping, ну крякает немного по другому
- FishTyping, it swims and lay eggs, прям как Duck
Тред (@thekashey)
Вы когда-нибудь слышали выражение "Root cause"?
По-русски это будет типа "зри в корень", но тут это именно про проблему "caused by roots".
Сантехников тут много и они очень востребованы, потому что корни деревьев проникают в трубы и полностью их блокируют.
Совсем труба!
Проблема тут простая - в трубах большие стыки через которые эти корни внутрь и проникают. Единственное решение - замена труб.
Меняет ли кто их? Конечно же нет. Продолжают жрать кактус.
Дома еще хуже - самый распространенный вариант кирпич + гипсокартон. Между ними ничего. Зимой очень холодно, летом очень жарко.
Крыша тут обычно из черепицы, и очень модно ее красить в ЧЕРНЫЙ цвет. Никакой изоляции там тоже нет. Температура на чердаке до 80 градусов доходит.
Как мне сказал агент - "Наши дома приспособлены как можно быстрее выпускать тепло наружу".
Потом выпустили "ГОСТ" - типа вообще надо бы, но даже сейчас, при строительстве нового дома, какая либо изоляция - не более чем опция.
К чему я это - десятками лет тут строят дома, которые к жизни, в нашем понимании этого слова, НЕ приспособлены.
И кондеры тут не в каждом доме, часто обходятся вентиляторами. Местным норм. Им не надо лучше.
Что у вас там в code base?
В северных странах с этим проще - ты или строишь дом нормально, или, простите, ты труп.
Тут - страна непуганных идиотов. Потому заморских разработчиков и ценят - они пуганные.
Кстати да, тут вся заграница "overseas" - "за морем".
Буквально.
Тред (@thekashey)
И давайте немного разбавим скучные треды фоточками.
Тут реально есть что посмотреть, куда сходить, и где просто посидеть в одиночестве.
Я вот думаю - начать чтоли еще один топик про фотографию? Но так чтобы было связано с JS?
"Фотоаппарат" я себе купил лет 10 назад. Использовал его десятки тысяч раз, и обычно по назначению - фотографировал семью, лес, город.
Разок пофотографировал "ивент" - YaC 2014, и как-то на этом дело и завершилось
Вообще я на конференции меня компания отправляла достаточно часто, в основном поговорить, а вот на локальные митапы - как не получалось.
На Moscow JS я был только один раз. Опять же поговорить.
А потом как-то заметил клевые фотки от @tenphi - он многие митапы "показывал" таким образом - и я подумал - ну почему бы и нет?
У меня же есть камера!
С тех пор я фотографирую SydneyJS, ReactSydney, и вот на неделе был ReactConfAU.
Почему-то никто кроме меня это не делает, что позволяет мне в итоге познакомиться со всеми жертвами моей камеры.
В итоге все знают меня, я опять же знаю всех - реальный Life Hack!
Тред (@thekashey)
Среда
Главный топик на сегодня - разделяй и властвуй:
- Containers & Dumb Components
- Packages, Modules, Functions
- Block, Element, Modifiers
Я не постесняюсь сказать, что это разделение САМОЕ важное в нашем деле.
Все развивается по спирали.
- То разделять хорошо, руки прочь от Business Layer, SOLID, микросервисы, мухи и котлеты.
- То разделять плохо, монолиты, хуки, CSS-in-JS, и E2E тесты.
E2E тесты я тут упомянул потому становиться как-то "не модно" писать unit тесты, а именно они просто ТРЕБУЮТ разделения, и вообще чтобы функции были маленькие и потому тестируемые.
Чем больше обьект, тем сложнее его протестировать.
Разделение между Stateful/Stateless компонентами из той же оперы
- легко протестировать тупой view, он полностью контролируется из-вне
- легко протестировать умный (redux) connect - он маленький и без сайт эффектов.
- вместе их "unit" протестировать уже нельзя
В общем каждый раз когда у вас есть что-то большое - сделайте его меньше. И заодно "это" станет проще.
Как говорит моя теща из Сибири - медведя надо кушать по частям. Именно так я назвал одну статью с примером рефакторинга простого TODO + Redux
dev.to/thekashey/eat-…
Packages, Modules, Functions?
Мы все "знаем", что функции надо делать маленькими. Мы все "знаем", что можно копонетизировать крупные блоки в отдельные пакеты, особенно в монорепах. Но знаем ли мы когда файл бить на более мелкие файлы?
Принцип тут простой - если какая-то часть модуля использует что-то в импортах, что вторая не использует - это два файла.
Таким образом при изменении какой либо из этих не-"shared" зависимостей сломается только один файл. И оба файла будут ПРОЩЕ.
👉 чем меньше импортов - тем лучше
Второй принцип более относиться к dependency mocking и юнит тестированию.
Вот есть у вас функция А, которая вызывает Б и что-то делает в зависимости от результата. Как ее протестировать? Как "замокать" Б?
Есть только один "правильный" вариант - вынести Б в отдельный файл и замокать весь тот файл.
Почему надо использовать dependency level mocking а не sinon.spy? Держите меня трое
habr.com/ru/post/352918/ - как тестировать SkyNet
dev.to/thekashey/plea… - почему sinon 💩
И на этом переходом к БЕМ. Столь нелюбимом мною в Яндексе, и столь же любимым сейчас.
БЕМ это не__этот-тупой--синтаксис, а разделение между Блоком и Элементом.
- Блок не может иметь "размеры"
- Элемент не может иметь "стили"
- Каждый Блок это Элемент
- Банально два className/div
Покуда современный UI все думает чего делать с reusability и composability - БЕМ просто работает.
- Я хочу Button, Button--blue, и вот как я ее хочу MyForm__button.
Готово. Никакие свойства друг с другом не конфликтуют*, никаких specificity wars*, все окей*
- ну почти
Про БЕМ можно найти ОЧЕНЬ много информации - главное ее переварить.
Но если душа к этому не лежит - можно пойти CSS-in-JS путем.
Дорогая! Где мои портки?!
github.com/danieldelcore/…
В итоге каждый раз, КАЖДЫЙ РАЗ, основная задача состоит в нахождении чего-то минимального, но жизнеспособного в своем одиночестве
Маленькая библиотека, Атомарный стиль, Простая функция, Сервис, Unix команда
Проще понять зачем что-то нужно, проще понять (и ограничить) требования
Мельчить тоже не надо - сложно будет собрать все воедино. И проще будет создать то, чего вообще-то не надо.
Разбили код на функции, разнесли функции по файлам, файлы по директориям, директории про проектам, проекты отдали разным командам и все довольны.
После каждого шага разбиения должно получаться "ок". Мухи отдельно, котлеты отдельно, кишки имплементаций не торчат, абстракции не текут.
Мы все любим "компонентный подход" - давайте любить его чуть более усерднее.
Тред (@thekashey)
Хорошим примером "борьбы" со "сложностью" является проблема мемоизации в state management.
Это прям ОЧЕНЬ фундаментальная проблема, затрагивающая практически любой аспект
- Начнем с #Redux - он без мемоизации банально не работает. Просто потому что таковы "правила игры".
Reselect, с его cacheSize==1 решением НЕ является. Он сам по себе проблема.
Было много попыток улететь - re-reselect, или engineered redux-views
github.com/reduxjs/resele…
Были и есть еще более over-engeneered варианты, в частности Proxy based, которые решила 99% селекторов, кроме одной:
github.com/theKashey/memo…
github.com/dai-shi/reacti…
github.com/reduxjs/react-…
"Одна проблема" - это именно хранение "одного"(последнего) значения "внутри" себя
React.hooks в этом плане сильно лучше - он хранит свое значение в React Fiber.
Для не-реакта можно использовать kashe(cache+@thekashey) - простое решение на основе WeakMaps
dev.to/thekashey/memo…
Есть другие варианты решения. Просто ДРУГИЕ - например @ReatomJS или XState, где мемоизация вообще не нужна.
Ну или MobX, опять же, хотя он из рода proxy-based вариантов.
(и кто-то сказал VueJS?)
Давайте остановимся на proxy варианте, потому как на нем легко обьяснить почему "разделение" важно.
Работает он просто - state оборачивается в proxy, трекается в какие дебри вы залезли, и результат будет пересчитываться только если изменилось что-то что было "использовано"
- было a.b.c
- вы сказали if(a.b.c)...
- это значит что
a
и b
были "промежуточными", и "ненужны"
- а вот c
важно.
Логично? Давайте немного изменим код- if(a.b.c) return a.b;
^ внезапно получается что
b
тоже важен, это именно то что функция возвращает!
И что-бы это понять должна быть функция, которая должна что-то возвращать!
Логично? Давайте немного изменим кодДавайте заинлайним все это в компонент!
const MyComponent = ({a}) => (
a.b.c
? <OtherComponet data={a.b} />
: <OtherComponent data={a.d} />
);
a.b пройдет незамеченным, только если не распарсить ответ render, что я делать не советую
- Поэтому с reactive-react-redux/useTrackedSelector можно выстрелить себе в ногу (там хуки, все в куче )
- А с connect-based beautiful-react-redux все будет окей
Банально потому что есть "забор".
Больше разделения == больше контроля.
habr.com/ru/post/350562/
Упс, оказывается полностью перевести статью на русский я немного поленился.
Самая полная версия сейчас живет на dev.to
dev.to/thekashey/how-…
The word "complex" is often misused when describing software. If something is difficult to understand, it is "complicated", not complex. If something introduces exponentially many more possible ways it can interact with other things, it is "complex". en.wikipedia.org/wiki/Programmi…
Тред (@thekashey)
Четверг
@jsunderhood Альтернатива BEM - css modules github.com/css-modules/cs…
И так везде - люди думают что БЕМ это про__эти--селекторы, чтобы свойства не пересекались, и CSSModules прям отличная замена всему__этому-старому--говну.
НЕТ. БЕМ это не только naming convention - это про РАЗДЕЛЕНИЕ на Блоки и Элементы. twitter.com/nastia_splin/s…
Буду честен - я сам это немного не понимал все те годы что провел в Яндексе. А там не только БЕМ из всех щелей, но и конкретно в нашей команде был BEViS от Вадима "37" Макишвили.
И я честно B и E не догонял.
github.com/bevis-ui/docs/…
Сильно позже, когда жена пошла на курсы @htmlacademy_ru, другой Вадим - @pepelsbey_ - обьяснил что и как.
Шестеренки вошли друг в друга, зацепились, 🤯
И я уверен, что официальна документация ru.bem.info/methodology/qu… в понимании ключевого момента не помогает.
- Любой Блок Является Элементом
- Любой Блок принимает className от Родителя
- DOM нода Блока содержит минимум ДВА className : от блока, и от элемента.
Сами Блоки не имеют ни размеров, ни маржинов, и тем самым являются
- независимыми
- переиспользуемыми
- удобными
А CSSModules это все отлично дополняет. "БЕМ" даже на CSS-in-JS можно, потому что это не про именование, а про разделение.
Тред (@thekashey)
За три года в Сиднее я ни разу не серфил. Вот такая большая часть местной жизни прошла мимо меня.
В то же время у меня в гараже стоят мои горные лыжи, которые (как и я) три года снег не видели.
Поэтому тема на завтра у нас #codesplitting
Хотя, не, вру. На доске я стоял. И именно так я узнал что iPhone XR не являются water proof.
Thanks to @theKashey for capturing the Buildspotting intro to my talk at @sydjs in January :) (not my best delivery but you get the gist ;)) pic.twitter.com/qKrf4rSZLC
Choose webpack - одно из лучших выступлений на @sydjs
twitter.com/200okpublic/st…
Пятница
Итак его величество #codesplitting, или "техасская резня бензопилой", потому что я разрежу тебя на части.
На самом деле codesplitting более про собирание из частей, чем про разрезание. В общем поехали!
Codesplitting вообще очень старая тема. В те времена когда мы отдельно подключали jQuery, отдельно Google Analytics, и отдельно чего там нужно нашей странице - это был тот самый code splitting.
Счастливые времена RequireJS! Но потом пришел Browserify/Webpack и все испортил.
Первым делом бандлер "обьяснил" что загружать один большой бандл - БЫСТРЕЕ, даже с http2 и компанией
1 - engineering.khanacademy.org/posts/js-packa…
2 - medium.com/webpack/webpac…
3 - github.com/theKashey/requ…
Проблема в том, что у всего есть пределы и если бандл уже под 100 мегабайт (Jira), ну или хотя бы 10 - это СЛИШКОМ много.
Так что:
- мельчить плохо - оно работает медленно
- крупные куски переварить или сложно, или невозможно
ЧТО ДЕЛАТЬ!!
Первым делом - сохраняем спокойствие и пытаемся вспомнить зачем нам этот codesplitting нужен.
💡чтобы работало быстрее!!!
Так что давайте разберем почему codesplitting может что-то сделать быстрее 🚀, и почему он может что-то сделать медленнее 🐢
🚀 Почему быстрее? 🚀
- потому что можно загружать меньше кода, что не так чтобы большая проблема, особенно в России (а Австралии со скоростью все СИЛЬНО хуже)
- потому что можно исполнять меньше кода, и это самое главное, именно это делает "быстрее" 😉
The “inline requires” optimization has been enabled at FB for so long that we take it for granted now. Open source bundlers (beyond Metro) need to catch up! If you care about bundle size you should start caring about how much code executes eagerly. instagram-engineering.com/making-instagr…
"Исполнять меньше" можно разными средствами:
- у бабеля есть lazy режим, который импортирует файлы по фактическому использованию
- у ReactNative есть примерно тоже самое - inline requires
В обоих случаях работает прям очень круто.
Никто не использует.
twitter.com/dan_abramov/st…
На самом деле это просто - можно банально начать использовать require когда нужно.
Например был у меня код в redux приложении, который требовал различные нормализации и другой jsonapi - 11kb gzip. Я заменил import в шапке на require в самом action, и тем отложил исполнение js.
Откладывая исполнения js можно добиться замечательных результатов, особенно в тестах и SSR, которые многие куски кода вообще никогда запускать не будут, но на деле это не так чтобы прям просто.
Иногда нам нужны side-effects, иногда разделить что-то на две части просто сложно.
В прошлом году меня зашеймили за react-focus-lock, что немного жирноват - 5kb min gz, и я придумал как это проблему решить.
Теперь есть react-focus-lock/UI - 2kb, и "sideCar", который 3kb.
Две части - UI и логика которая для SSR или неактивного lock не нужна.
Вроде как фигня, но react-focus-on, который focus+scroll lock - все те же 2kb на UI, и уже 5kb на sidecar
Плям идеальный кейс для size-limit: github.com/theKashey/reac…
Как всегда есть статья с теоретическим обоснованием концепта:
dev.to/thekashey/side…
🐢 Почему медленнее 🐢
Потому что "fetch-then-render". Если нарезать приложение на части, то для того чтобы только понять какую часть надо загрузить надо в начале загрузить все части "до" нее.
Это формирует "волны", или "смерть через 1000 спинеров"
React.lazy и другие Suspense проблему не решают от слова совсем. По определению.
Ну Suspense быть может(в concurrent mode) задержит показ нового экрана, но 🚀быстрее🚀 его не сделает. А нужно то именно "быстрее"!
Быстрее возможно только в одном случае - если мы начинаем загружать код как можно "раньше", чтобы побороть latency.
Опять же - "render-as-you-fetch".
Таким образом когда наступит время показа элемента - он уже будет загружен. Получится "быстрее"
Варианта тут 2
- первый это SSR. Просто отрендерите страницу на сервере, где все скрипты уже загружены, да и данные "близко", и можно сходить за ними пару раз.
Это создаст как бы "инструкцию" того, что нужно сделать на клиенте, чтобы получить аналогичную картинку.
- второй это "умный" CSR. Например с использованием "плоского" раутинга, где можно заранее понять что будет отрендерено на странице, и сделать что-то типа prefetch.
Почти никто так не делает 🤷♂️, хотя иногда встречаются прям супер навороченные решения
github.com/Shopify/quilt/…
На "работе" у нас чистый SPA без SSR, так что там сидит "плоское" CSR решение, а после работы я мейтейню loadable-components и react-imported-components... да, одновременно.
Вообще React code splitting немного хитрая чтука - работает просто на соплях.
dev.to/thekashey/insi…
Основная проблема в SSR + Code Splitting хорошо показана в @stereobooster's react-snap
- с сервера пришла красивая картинка
- стартовал реакт и все похерил
- загрузились lazy компоненты, опять все хорошо
Разные библиотеки решают это по разному:
- async-components ручками рендерил приложение чтобы найти "себя" и создать "инструкции". Не пережил React 16.
- react-loadable/loadable-components патчат код и лезут в webpack
- imported-components добавляет сахар в imports.
Далее библиотеки или сами вставляют нужные скрипты в ответ (получается что они "знают" какие правильные), или повторяют те же imports на клиенте до старта приложения.
В итоге почти все работает только с @webpack, и для @parceljs я знаю только одно решение - imported-components.
Проблема в том, что разрабочики "фреймворков" не так чтобы думают как их поделки будут использовать, или никто кроме них их использовать не может.
Тот же React.lazy - не работает на сервере, от слова совсем. И на клиенте особо не помогает(нет prefetch)...
When discussing Concurrent Mode, we haven’t focused on server rendering as much. However, it’s an essential part of the picture! For example, it enables Progressive Hydration — making individual React components interactive before all JS loads. Demo: codesandbox.io/s/floral-worke… pic.twitter.com/7QfC4g3JIK
Решение? Partial hydration, который у Фейсбука то есть, а у нас еще нет.
Вот у @dan_abramov это работает хорошо из коробки
twitter.com/dan_abramov/st…
У @_developit тоже работает - github.com/GoogleChromeLa…, но не хорошо
И у меня работает, тоже не так чтобы, но уж как пару лет - medium.com/@antonkorzunov…
(никто не пользуется)
Самое главное, на что я до сих пор, ни смотря на весь мой опыт, напарываюсь...
CODESPLITTING МОЖЕТ СДЕЛАТЬ ТОЛЬКО ХУЖЕ!
Или вы можете добавить кучу imports в свой код, разбить бандл на кучу файлов, и для показа любой страницы все еще потребуются почти! все! файлы!
Codesplitting это не про imports, и не про Lazy - это про контроль зависимостей. Про то как ваше приложение живет и дышит. Не только про то "где" резать, но и про "когда".
В том числе как и когда собирать обратно.
Тред (@thekashey)
Я думаю следует сделать мини spin-off про "lazy require"
react-imported-component сам по себе к бандлеру не привязан, и загрузить "нужные скрипты" может только вызвав imports повторно.
В итоге - сильно проигрывает в скорости бандлерам с более плотной "интеграцией"
Но что если вначале вызвать все импорты, а потом, буквально "через два промиса" сделать require entryPoint?
Что будет? Браузер начнет загружать новые чанки, и только потом главный тред заблокируется за компиляцию и исполнение кода entry point.
А пока он будет исполнятся - новые блоки будут загружаться. Результат - 🚀
Подробности как всегда упакованы в статью
dev.to/thekashey/reac…
Если кто прочитал основной тред про codesplitting, и захотел "умный Lazy на плоских routes" - вот его надо запускать до того как ЛЮБЫЕ библиотеки будут импортированы.
Особенно реакт.
Тред (@thekashey)
Еще один момент, который про codesplitting, и про который мало кто знает (потому что его только только сделали) - "чанки" можно шарить между разными проектами.
Принцип все тот же - вы делаете import, и получаете код. Только вот этот ваш import может запросить что-то "из-вне"
Изначально это так и называлось - webpack external import.
Не "нативный", нормально не работающий import, а именно согласованная работа двух независимых сервисов.
Есть плагин для webpack4, поставляется в core webpack5
dev.to/marais/webpack…
В принципе это немного приравнивает js codesplitting к таким классическим вариантам как shared library(.so), или виндовый .dll
Внезапно codesplitting становится не только средством "разрезания" бандла, но и механизмом доставки отдельных частей.
Ой! Сегодня же пятница!
По пятницам работа заканчивается в 4 дня, и начинается Пиво. Точнее не Пиво, а пиво, а если еще точнее - Эль.
Время социальной раскрепощенности, и обсуждения правильных архитектур и стейт менеджмента.
После пива - мясо. Его тут много и на любой вкус.
Суббота
Выходной. Время расслабиться, порубиться с детьми в приставку, походить по лесу и покупаться. Заодно решить пару открытых issues. И как не странно - это связано.
Многие знают как ценен режим "фокусировки" для программиста, когда он входит в "поток" и хуячит-хуячит код...
Но вы не подумайте что я ругаюсь - это именно то что этот программист делает - бездумно пишет код.
Сосредоточенность - это не всегда хорошо. Это именно тот случай когда 🐢 тише едешь - дальше будешь 🚀
Какие советы я могу дать:
Никогда ничего не мержите по готовности. Я любою открыть PR и замержить его на день позже, даже если все тесты зеленые и вроде все окей.
Очень важно с проблемой(и даже решением!) "переспать" - утро вечера мудренее, и многое столь клевое вчера не будет клевым сегодня.
Парное программирование, даже если второй программист резиновая уточка.
Прийдется обьяснять что ты делаешь напарнику или напарнице, ну или вторая половинка будет перебивать вопросами к месту и не очень, выбивая из потока. По сути будет работать как центр торможения в мозгу.
QA-demo в принципе что-то среднее между первым и вторым, когда надо обьяснить QE что ты сделал и почему.
Если при разработке просто помнить об этом моменте, и думать "а как же я это обьясню QE" - уже будет хорошо.
Делайте перерывы.
Как часто вы находили решение проблеме, над которой бились весь день, как только за вами закрылась дверь офиса, лифта, или просто вставали с месте? Или как только решались задать вопрос коллеге?
4+ раньше мне очень помогало в этом обычное курение, и после того как я бросил - сильно просел по эффективности.
Хорошее решение - бег. Сложно в Москве и зимой.
Хорошее решение - душ. Сложно в офисе.
Хорошее решение - вождение (не по пробкам)
Хорошее решение - бассейн.
Почти все "хорошее" что я сделал за последний год - я сделал когда все надежды пропали, и я ушел топиться.
Сделал пару кругов, и вот оно решение. Сделал еще пару - и можно приступать к разработке.
Но смысл всегда один - делайте паузы. Не погружайтесь глубоко в поток. Ничего кроме высера неких рандомых мыслей (как например этот тред) вы не получите.
Тише едешь - дальше будешь.
Тред (@thekashey)
Если спросить меня - "что сформировало меня как специалиста", то я скажу - 3 вещи. И все они случилось сильно позже чем следовало.
Если бы я только знал, если бы я только начал это делать раньше...
Дорогу идеям.
Мне всегда было немного сложно следовать "стандартам", использовать std:string, Oracle и другой кактус.
Старшие коллеги любили меня почмырить, что я вечно велосипеды изобретаю, хотя часто это и было моей работой - скрестить MFC с std, портировать Win32 на posix
C приходом в Яндекс (и javascript) стало как-то попроще - ничего стандартного не было в принципе, так что велосипеды - наше все.
Потом компания обьявила охоту за патентами, и стало еще интереснее - достаточно было прислушаться к тому что "жмет" - а найти решение уже проще.
Весь фронтенд этим только и занимался - клепал аналоги реакта, стейт менеджеры со скоростью пулемета.
Потому что хотели чтобы "не жало". За пару лет обувка кажись сама разносилась, и вот мы тут.
Все нужно обьяснить.
В первую очередь себе. Так что ко всем проектам пишите, и учитесь писать, хорошие readme. Плюс статьи про что почему надо использовать ваше 💩, а не старый 💩.
Банально со временем учит более правильно излагать свои мысли.
Многие жалуются на лонг риды, говорят - если кратко описать что-то не умеешь, то лох.
Это не так - по своему опыту и опыту коллег знаю что только пока "в свои тапки не сунешь" - суть чего-то там не дойдет.
Лучше один раз, но долго, чем быстро, но много раз.
Возьмем различные конференции - обычно в начале рассказывают какой REST плохой, потом рассказывают почему GraphQL лучше, а потом применяют это "лучше" обратно на REST, и всем понятно почему предложенное решение - решение
> Я про это видео
youtube.com/watch?v=cdsnzf…
Нельзя просто сказать - jQuery ацтой, Effector лучше. Потому что 🤷♂️.
Возьмем $mol - это офигительная чтука. И все статьи про нее(или от "автора") - просто кладези.
Вот только...
habr.com/ru/post/491120/
И все "4 года" никакой другой реакции на $mol я не видел - у всех течет кровь из глаз, прям как когда-то у нас текло от JSX (у кого-то до сих пор капает)
Просто пропущен тот самый этап длительного знакомства, расшаркивания, привыкания.
Не надо было лаконичным - люди не поймут.
Это вообще немного пересекается с принципами развития OSS проектов от @andrey_sitnik, согласно которым описание должно быть простым и коротким, потому что у людей времени читать нет.
Это не всегда так - кто-то прочитает, обьяснит на пальцах коллеге, и пошло поехало.
Умение обьяснять, аргументировать, аппелировать к уже известным решениям, проводить сравнения, расписывать плюсы и не прятать минусы - это не древнегреческое ораторское искусство - это "пункт #2"
И в принципе часть обязательных скилов для "сеньера"
Это менторство.
Пункт 3 основан на .1 и .2 - поддержать идеи новичка, обьяснять что и как, отревьювить по полной, и остаться друзьями.
Это такие очень аккуратные человеческие отношения, с легким привкусом проффесионализма.
Я начал постигать это искусство обучая жену, и по началу часто оставался без ужина, а то и вовсе спать на коврике (после особо удачного рефакторинга)
Я урок усвоил, и теперь в принципе только этим и занимаюсь - помогаю решать задачи и писать код.
Менторство - оно более про понимание как правильнее работать с конкретным человеком. Направить в нужное русло, поработать rubber duck, обьяснить почему мы на классах более не пишем, и так далее.
И с каждым свой подход.
Иногда приходишь домой вечер, открываешь чужой PR, копаешься в нем часок, так чтобы шестеренки сошлись, и делаешь git stash.
Утром приходишь на работу, спрашиваешь - ну как у тебя дела? Опять это ТайпСкрипт жить не дает? Ну давай попробуем вместе решить...
Итого:
- не стесняйтесь фонтанировать идеями. Только желательно их как-то структурировать и оформлять.
- учитесь обьяснять. С этим у многих проблема, и я в первых рядах.
- учитесь слушать/получать фидбек. Это позволит понять как надо было делать на самом деле.
Последний пункт для нашего брата самый простой - habrahabr по сути единственный сайт где тебе и спасибо скажут, и грязью обольют, и в карму насрут, и ничего похожего более нигде не встретить, даже на реддите, или "haternews"(aka hackernews)
Если сдюжите хабр - сдюжите все.
Тред (@thekashey)
Воскресенье
@jsunderhood о да. немного дополню, надеюсь в тему. очень важно не предлагать готовых решений человеку когда он в чём то разбирается. нужно понять где его проблемы и в этих местах задать ему нужные вопросы, чтобы он научился ходить этой дорогой сам
Хочешь накормить человека один раз — дай ему рыбу. Хочешь накормить его на всю жизнь — научи его рыбачить. twitter.com/Kuraushka/stat…
Я точно знаю что "Federated Modules", aka webpack external import, кому-то так и не зашли.
Буду честен - что статья от @ScriptedAlchemy(так что на @Medium), что от @codervandal(на @ThePracticalDev) так так чтобы продающие.
Исправляем ситуацию - youtube.com/watch?v=D3XYAx…
Для справки:
- dev.to/marais/webpack…
- medium.com/@ScriptedAlche…
Хотя следует признать - старшеклассники катаются очень даже.
На часах 7.25. Воскресенье.
А значит мое время практически завершилось.
С вами был @theKashey, из далекой Австралии, стране родоначальнице CSS-in-JS - CSSModules, StyledComponents, Emotion были написаны тут :)
Стране диких @wallabyjs и kan-ga-roo
Меня всегда можно найти:
- в твиттере 👉 @theKashey
- гитбахе(react-hot-loader, loadable-components, и 160 других пакетов) - github.com/thekashey
- инстаграмме, я же фотограф 😅 - instagram.com/thekashey