А еще, я ищу JS-разработчиков, прямо в мою команду инфраструктуры фронта 🚀
Если для вас это актуально, то присылайте резюме в личку ☺️
https://yandex.ru/jobs/vacancies/dev/front_develop_market/
https://yandex.ru/jobs/vacancies/dev/nodejs_market/
Если для вас это актуально, то присылайте резюме в личку ☺️
https://yandex.ru/jobs/vacancies/dev/front_develop_market/
https://yandex.ru/jobs/vacancies/dev/nodejs_market/
Привет! Небольшая заметка о том, как я затаскивал поддержку больших статов в генерируемые Статоскопом HTML-отчеты.
Как мы с вами уже знаем, у JS-движков есть ограничение на максимальный размер строки (например 512мб для V8)
Это значит, что при попытке получить строку большего размера, мы получим ошибку
Очевидно, что для статов размером больше 512mb тот же
Обойти ограничение можно при помощи поточного JSON-парсера. Такому парсеру нужен источник строки, который будет отдавать ее не целиком, а кусочками (например по 64кb). По мере того, как парсер получает кусочки, он пытается их распарсить - превратить в объект. Очевидно, что этот объект растет по мере парсинга. Смысл в том, что мы не обрабатываем большие строки, а следовательно, у нас не возникает исключения
Ну хорошо, делаю первый подход - взял поточный парсер от @rdvornov, формирую HTML и инъекчу в него код вроде такого:
Запускаю - не работает, браузер просто зависает 🤔
Методом проб и ошибок выяснил, что бразуер просто не переваривает такой большой тег скрипт (несколько сот мегабайт). Никакой особо полезной информации я по этому ограничению не нашел, но стало ясно, что теперь я воткнулся в проблему лимитов самого браузера. Стал думать что здесь можно сделать. Пришла идея попилить на куски не только JSON, но и теги noscript:
Запустил, заработало! Теперь я смог обойти и ограничение на
Учитывая то, что загружать в отчет можно сразу несколько файлов со статами, например, для сравнения сборок, предусмотрел пуш чанка по идентификатору стата:
Таким образом даже не важен порядок, в котором статы сбрасываются в отчет.
Прошло какое-то время и @rdvornov задал интересный вопрос: "Слушай, а почему бы не использовать теги noscript не как скрипт, а как текст, тогда можно было бы сэкономить на парсинге?"
И действительно, если сказать браузеру, что содержимое noscript - это не скрипт, а текст, то браузер не будет тратить время на парсинг сожержимого. А, на минуточку, 64kb x Nk тегов noscript - это ощутимо.
В итоге получилось что-то вроде:
Там конечно чуть сложнее, полную версию изменений можно посмотреть тут
Итог этой простой манипуляции такой: время загрузки отчета со статами в 650mb сократилась с 21 секунды до 14 (профит в 33%!!!)
Мораль: почти всегда можно что-то придумать, чтобы стало лучше (даже когда кажется, что нельзя) 😉
Как мы с вами уже знаем, у JS-движков есть ограничение на максимальный размер строки (например 512мб для V8)
Это значит, что при попытке получить строку большего размера, мы получим ошибку
RangeError: Invalid string lengthОчевидно, что для статов размером больше 512mb тот же
JSON.parse работать не будет, но как раз JSON.parse нам и нужен.Обойти ограничение можно при помощи поточного JSON-парсера. Такому парсеру нужен источник строки, который будет отдавать ее не целиком, а кусочками (например по 64кb). По мере того, как парсер получает кусочки, он пытается их распарсить - превратить в объект. Очевидно, что этот объект растет по мере парсинга. Смысл в том, что мы не обрабатываем большие строки, а следовательно, у нас не возникает исключения
RangeError, а сам объект путь себе растет пока хватает оперативной памяти.Ну хорошо, делаю первый подход - взял поточный парсер от @rdvornov, формирую HTML и инъекчу в него код вроде такого:
const chunks = [
сюда вставляю большой JSON порубленный на строки по 64kb
];
const data = await jsonExt.parseChunked(() => chunks);
Statoscope(data);
Запускаю - не работает, браузер просто зависает 🤔
Методом проб и ошибок выяснил, что бразуер просто не переваривает такой большой тег скрипт (несколько сот мегабайт). Никакой особо полезной информации я по этому ограничению не нашел, но стало ясно, что теперь я воткнулся в проблему лимитов самого браузера. Стал думать что здесь можно сделать. Пришла идея попилить на куски не только JSON, но и теги noscript:
<noscript>
chunks.push(КУСОК_JSON)
</noscript>
<noscript>
chunks.push(СЛЕДУЮЩИЙ_КУСОК_JSON)
</noscript>
..... здесь еще много подобных тегов noscript
<noscript>
const data = await jsonExt.parseChunked(() => chunks);
Statoscope(data);
</noscript>
Запустил, заработало! Теперь я смог обойти и ограничение на
JSON.parse и ограничение браузера на размер тега noscript.Учитывая то, что загружать в отчет можно сразу несколько файлов со статами, например, для сравнения сборок, предусмотрел пуш чанка по идентификатору стата:
<noscript>
api.pushChunk("stat1.json", КУСОК_JSON)
</noscript>
<noscript>
api.pushChunk("stat2.json", КУСОК_JSON)
</noscript>
<noscript>
api.pushChunk("stat1.json", КУСОК_JSON)
</noscript>
Таким образом даже не важен порядок, в котором статы сбрасываются в отчет.
Прошло какое-то время и @rdvornov задал интересный вопрос: "Слушай, а почему бы не использовать теги noscript не как скрипт, а как текст, тогда можно было бы сэкономить на парсинге?"
И действительно, если сказать браузеру, что содержимое noscript - это не скрипт, а текст, то браузер не будет тратить время на парсинг сожержимого. А, на минуточку, 64kb x Nk тегов noscript - это ощутимо.
В итоге получилось что-то вроде:
<noscript type="text/plain" data-id="stat1.json">КУСОК_JSON</noscript>
<noscript type="text/plain" data-id="stat1.json">КУСОК_JSON</noscript>
......
<noscript>
for (const element of document.querySelectorAll('noscript')) {
api.pushChunk(element.dataset.id, element.textContent);
}
const data = await jsonExt.parseChunked(() => api.getChunks());
Statoscope(data);
</noscript>
Там конечно чуть сложнее, полную версию изменений можно посмотреть тут
Итог этой простой манипуляции такой: время загрузки отчета со статами в 650mb сократилась с 21 секунды до 14 (профит в 33%!!!)
Мораль: почти всегда можно что-то придумать, чтобы стало лучше (даже когда кажется, что нельзя) 😉
GitHub
(feat): improve HTML-report loading time · smelukov/statoscope@9b58295
Analyzes webpack stats and shows detailed info about it on the screen. - smelukov/statoscope
Выпустил Statoscope 3.5
Туда вошло изменение, ускоряющее получения списка npm-пакетов и их инстансов https://github.com/smelukov/statoscope/pull/43
Это значительно уменьшило время генерирования отчета при помощи плагина.
Кстати, это первый сторонний ПР в Statoscope, который что-то улучшает 🚀
А еще, видимо что-то пошло ТАК и Statoscope начали использовать на CI, т.к. количество скачиваний резко возросло https://npm-stat.com/charts.html?package=%40statoscope%2Fui-webpack 🤘🏻
Хотя, если вы большой проект, то лучше использовать кеширующий npm-proxy, например Verdaccio
Туда вошло изменение, ускоряющее получения списка npm-пакетов и их инстансов https://github.com/smelukov/statoscope/pull/43
Это значительно уменьшило время генерирования отчета при помощи плагина.
Кстати, это первый сторонний ПР в Statoscope, который что-то улучшает 🚀
А еще, видимо что-то пошло ТАК и Statoscope начали использовать на CI, т.к. количество скачиваний резко возросло https://npm-stat.com/charts.html?package=%40statoscope%2Fui-webpack 🤘🏻
Хотя, если вы большой проект, то лучше использовать кеширующий npm-proxy, например Verdaccio
Привет!
Году в 2017 я залип на соревновании return true
Вам дается функция, нужно изучить исходный код и понять что нужно передать в функцию в качестве аргумента так, чтобы функция вернула true.
Проблема в том, что задание нужно не просто решить, а сделать это за минимальное количество символов.
Есть простые задания, а есть и зубодробительные.
Я тут раскопал свои решения из первого сезона соревнования, но с тех пор вышло много других задач.
Интересно было бы видеть тут разбор этих задачек с моими размышлениями и комментариями? В виде ссылок на статьи в телеграфе (чтобы не спойлерить тем, кто хочет решить все сам)
Году в 2017 я залип на соревновании return true
Вам дается функция, нужно изучить исходный код и понять что нужно передать в функцию в качестве аргумента так, чтобы функция вернула true.
Проблема в том, что задание нужно не просто решить, а сделать это за минимальное количество символов.
Есть простые задания, а есть и зубодробительные.
Я тут раскопал свои решения из первого сезона соревнования, но с тех пор вышло много других задач.
Интересно было бы видеть тут разбор этих задачек с моими размышлениями и комментариями? В виде ссылок на статьи в телеграфе (чтобы не спойлерить тем, кто хочет решить все сам)
Telegraph
Telegra.ph is a minimalist publishing tool that allows you to create richly formatted posts and push them to the Web in just a click. Telegraph posts also get beautiful Instant View pages on Telegram.
27 февраля пройдет конференция Я Люблю Фронтенд и в рамках конференции был запущен челледж в формате Capture The Flag
Прошел где-то за 3.5 часа ✅
Рекомендую, помогает встряхнуть мозг 😉
Прошел где-то за 3.5 часа ✅
Рекомендую, помогает встряхнуть мозг 😉
Я ❤ Фронтенд
27 февраля тысячи неравнодушных разработчиков и разработчиц подключились к конференции «Я люблю фронтенд», чтобы посмотреть доклады от классных спикеров, поучаствовать в воркшопах и разобраться, что скрывается за улыбкой Айзелуортской Моны Лизы.
https://www.joinclubhouse.com/event/M1zov8YL
Сегодня в 19:00 по МСК мы с коллегами будем болтать про сборку и отвечать на вопросы, подключайтесь ;)
Сегодня в 19:00 по МСК мы с коллегами будем болтать про сборку и отвечать на вопросы, подключайтесь ;)
Сергей Мелюков
Хотите разбор return true?
Привет! Судя по результатам опроса, почти все проголосовавшие хотят разбора.
Подготовил для вас первую статью серии
Милости прошу в комменты с вопросами/предложениями по содержимому и формату 😉
Подготовил для вас первую статью серии
Милости прошу в комменты с вопросами/предложениями по содержимому и формату 😉
Teletype
return true: length
Привет! Разбираем решение задачки length из второго сезона RT.
За что люблю return true, так это за то, что он побуждает вгрызаться в особенности языка и иногда заставляет читать спеку, даже если не очень-то и планировалось. Например, с удивлением обнаружил, что при постинкременте, старое значение тоже приводится к числу:
f = () => 0
f++ // NaN
Я ожидал увидеть здесь f вместо NaN, т.к. это ПОСТинкремент.
Но спека говорит примерно следующее:
...
oldValue = ToNumeric(lhs)
...
Return oldValue
В результате чего, мы вполне логично получаем NaN при попытке привести функцию к числу.
О некоторых вещах часто не задумываешься и не замечаешь, пока дело не доходит до нестандартных кейсов 🤷🏻♂️
f = () => 0
f++ // NaN
Я ожидал увидеть здесь f вместо NaN, т.к. это ПОСТинкремент.
Но спека говорит примерно следующее:
...
oldValue = ToNumeric(lhs)
...
Return oldValue
В результате чего, мы вполне логично получаем NaN при попытке привести функцию к числу.
О некоторых вещах часто не задумываешься и не замечаешь, пока дело не доходит до нестандартных кейсов 🤷🏻♂️
А вот и вторая статья цикла про разбор задач из return true 🏆
Teletype
return true: countOnMe
Привет! Сегодня разбираемся с задачкой countOnMe из второго сезона RT.
А давайте немного поболтаем и порешаем задачки? 🙂
Как вы уже знаете, я люблю всякие челледжи и недавно я наткнулся на такую вот задачку:
Иначе говоря: На вход функции поступает число, каждый разряд которого нужно возвести в квадрат. Полученные квадраты разрядов нужно объединить и вернуть из функции.
На входе и на выходе должны быть именно числа (`typeof x === 'number'`). Примеры:
Как вы решали бы эту задачу? При условии, что вам надо сразу сделать так, чтобы с точки зрения кода все было круто и эффективно.
Будет круто, если пришлете кусочки кода в какой-нибудь code pen. Или просто поделитесь мыслями.
PS: очевидно, не все так просто, иначе я бы не поднял этот вопрос 😉
Чуть позже поделюсь своими мыслями и решением 😉
PPS: Возможно такой формат окажется интересным.
Как вы уже знаете, я люблю всякие челледжи и недавно я наткнулся на такую вот задачку:
You are asked to square every digit of a number and concatenate them.
For example, if we run 9119 through the function, 811181 will come out, because 9^2 is 81 and 1^2 is 1.
Note: The function accepts an integer and returns an integer
Иначе говоря: На вход функции поступает число, каждый разряд которого нужно возвести в квадрат. Полученные квадраты разрядов нужно объединить и вернуть из функции.
На входе и на выходе должны быть именно числа (`typeof x === 'number'`). Примеры:
fn(3212) // 9414
fn(9119) //811181
Как вы решали бы эту задачу? При условии, что вам надо сразу сделать так, чтобы с точки зрения кода все было круто и эффективно.
Будет круто, если пришлете кусочки кода в какой-нибудь code pen. Или просто поделитесь мыслями.
PS: очевидно, не все так просто, иначе я бы не поднял этот вопрос 😉
Чуть позже поделюсь своими мыслями и решением 😉
PPS: Возможно такой формат окажется интересным.
Сергей Мелюков
А давайте немного поболтаем и порешаем задачки? 🙂 Как вы уже знаете, я люблю всякие челледжи и недавно я наткнулся на такую вот задачку: You are asked to square every digit of a number and concatenate them. For example, if we run 9119 through the function…
А вот и небольшая статейка про решение этой задачки https://teletype.in/@smelukov_dev/codewars-square-every-digit
Teletype
codewars: square every digit
⚠️ Статья наполнена спойлерами. Если вы хотите сами решить задачу, то вернитесь к статье только после того как решите ее сами или если...
❤1
Читатели задают вопросы о том, что делает
Оператор
Итак, зачем это всё? Дело в том, что побитовые операции можно производить только с целыми числами, поэтому при попытка применить побитовые операции к числу с плавающей точкой, дробная часть будет отброшена и это дешевле нежели использовать
Тут встает вопрос в том, какой побитовый оператор использовать, ведь каждый их них как-то модифицирует число. То есть применив побитовый оператор, мы так или иначе модифицируем число, а значит нам нужно применить такой оператор, чтобы биты числа можно было восстановить в их изначальный вид. Таким оператор как раз является ~:
А теперь, если мы снова применим этот оператор к получившемуся числу, то получим изначальный порядок бит:
Таким образом мы очень дешево избавились от дробной части при помощи битовых операций, не повредив само число.
~~(number / 10). Давайте разбираться, ведь одна из целей разборов этих задач - узнать что-то новое.Оператор
~ - это "побитовое НЕ", он инвертирует биты числа на противоположные: 10101 -> 01010.Итак, зачем это всё? Дело в том, что побитовые операции можно производить только с целыми числами, поэтому при попытка применить побитовые операции к числу с плавающей точкой, дробная часть будет отброшена и это дешевле нежели использовать
Math.floor и т.п.Тут встает вопрос в том, какой побитовый оператор использовать, ведь каждый их них как-то модифицирует число. То есть применив побитовый оператор, мы так или иначе модифицируем число, а значит нам нужно применить такой оператор, чтобы биты числа можно было восстановить в их изначальный вид. Таким оператор как раз является ~:
10101 -> 01010А теперь, если мы снова применим этот оператор к получившемуся числу, то получим изначальный порядок бит:
01010 -> 10101Таким образом мы очень дешево избавились от дробной части при помощи битовых операций, не повредив само число.
Завел несложный issue в Статоскоп и пометил его тегом
Такие задачки можно смело брать в работу если хочется поконтрибьютить 😉
Если берете себе задачку, отмечайте себя
В будущем буду еще заводить 😉
Good for contributionТакие задачки можно смело брать в работу если хочется поконтрибьютить 😉
Если берете себе задачку, отмечайте себя
В будущем буду еще заводить 😉
GitHub
Show size of chunk file · Issue #46 · smelukov/statoscope
In the chunk item, now we have only parsed size. But we need filesize too, we can make it with chunk.files.size.reduce(=> $ + $$, 0).formatSize()
Привет!
Вышел Statoscope 4.0 📦
Накопилось 😊
Теперь Статоскоп показывает информацию о дочерних компиляциях. Например, если вы собираете проект с веб-воркерами, то веб-воркеры собираются дочерней компиляцией и теперь Статоскоп показывает информацию о таких компиляциях.
По умолчанию такие компиляции скрыты, но при помощи настройки
Так же хочется сказать спасибо @iamakulov и @vladkorobov за поддержку Статоскопа 🙏
PS: Впереди много планов на то, какие задачи должен решать Статоскоп и как именно он это будет делать. Оставайтесь на связи
Вышел Statoscope 4.0 📦
Накопилось 😊
- Ломающее: Удалена сборка с отдельными стилями. Теперь Статоскоп - это изолированный монолит и все его стили встроены в единый бандл.
- Добавлена обработка дочерних комиляцийТеперь Статоскоп показывает информацию о дочерних компиляциях. Например, если вы собираете проект с веб-воркерами, то веб-воркеры собираются дочерней компиляцией и теперь Статоскоп показывает информацию о таких компиляциях.
По умолчанию такие компиляции скрыты, но при помощи настройки
Hide child compilations в UI, вы можете это изменить.
- Теперь Статоскоп показывает не просто размер чанка, а отдельно, размер чанка и размер ассетов, связанных с этим чанком (это тот самый issue, который я создавал для того, чтобы вы могли поконтрибьютит в Статоскоп, спасибо пользователю с ником immitsu на гитхабе).
- Обновил версию DiscoveryJS (спасибо @rdvornov)
- Обновил стек сборки самого Статоскопа
- Обновил Foam TreeТак же хочется сказать спасибо @iamakulov и @vladkorobov за поддержку Статоскопа 🙏
PS: Впереди много планов на то, какие задачи должен решать Статоскоп и как именно он это будет делать. Оставайтесь на связи
GitHub
Release v4.0.0 · statoscope/statoscope
Changes
UI
BREAKING: remove separated-styles build
Improvement
UI
Handle all child compilations (#46d813c)
Now Statoscope will handle all child compilation.
It's useful for cases like Google...
UI
BREAKING: remove separated-styles build
Improvement
UI
Handle all child compilations (#46d813c)
Now Statoscope will handle all child compilation.
It's useful for cases like Google...
Привет! Ох и летит время... Последний пост был ровно месяц назад 😅
Со мной все хорошо, просто стало больше проектов на работе.
Сегодня я подвез вам релиз Статоскопа 4.1.
Теперь Статоскоп стартует на 25% быстрее (за счет оптимизации логики нормализации данных), а еще в разы улучшил скорость сравнения статов. Статы, которые раньше сравнивались за 25 секунд, теперь сравниваются за сотни миллисекунд.
Как только появится чуть больше свободного времени, Статоскоп ждет большой рефакторинг с целью декомпозировать его на разные независимые части. Это позволит наконец покрыть его тестами и реиспользовать логику анализа статов в разных окружениях (например в CLI на CI). А еще, я буду пробовать внедрять собственный универсальный формат статов (не webpack-specific). Это позволит в разы уменьшить потребление ресурсов при обработке статов и размер самих статов.
P.S.: Спасибо пользователю с ником TchernyavskyD за поддержку Статоскопа на OpenCollective 🙏
Со мной все хорошо, просто стало больше проектов на работе.
Сегодня я подвез вам релиз Статоскопа 4.1.
Теперь Статоскоп стартует на 25% быстрее (за счет оптимизации логики нормализации данных), а еще в разы улучшил скорость сравнения статов. Статы, которые раньше сравнивались за 25 секунд, теперь сравниваются за сотни миллисекунд.
Как только появится чуть больше свободного времени, Статоскоп ждет большой рефакторинг с целью декомпозировать его на разные независимые части. Это позволит наконец покрыть его тестами и реиспользовать логику анализа статов в разных окружениях (например в CLI на CI). А еще, я буду пробовать внедрять собственный универсальный формат статов (не webpack-specific). Это позволит в разы уменьшить потребление ресурсов при обработке статов и размер самих статов.
P.S.: Спасибо пользователю с ником TchernyavskyD за поддержку Статоскопа на OpenCollective 🙏
Друзья, я выпустил Statoscope 5.0
Главная фича этого релиза в том, что статоскоп наконец может работать как CLI-инструмент 🎉
Поднять HTTP-сервер с HTML-отчетом по указанным статам (можно указать несколько и тогда они будут объеденены)
Сгенирировать HTML-отчет из статов (можно указать несколько и тогда они будут объеденены)
И на десерт киллер фича - провалидировать статы (или разницу в статах):
Супер полезно на CI.
Примеры можно посмотреть в README
⚠️ Важно: пакет @statoscope/ui-webpack был распилен на 2:
- @statoscope/webpack-plugin
- @statoscope/webpack-ui
Если вы использовали статоскоп как webpack-плагин, то юзайте пакет @statoscope/webpack-plugin
Api не изменилось ☺️
В этом релизе я был сконцентрирован на декомпозиции большого пакета ui-webpack на несколько мелких.
Так же у статоскопа теперь своя github-организация.
Дальше будет переезд на TS и покрытие тестами. А еще дальше буду пробовать собственный формат статов и двигать его в массы, так сказать :)
А еще, хочу уделять больше времени написанию технических постов (давно ничего не писал, исправлюсь)
Главная фича этого релиза в том, что статоскоп наконец может работать как CLI-инструмент 🎉
statoscope serve stats.jsonПоднять HTTP-сервер с HTML-отчетом по указанным статам (можно указать несколько и тогда они будут объеденены)
statoscope generate stats.json report.htmlСгенирировать HTML-отчет из статов (можно указать несколько и тогда они будут объеденены)
И на десерт киллер фича - провалидировать статы (или разницу в статах):
statoscope validate rules.js stats.jsonСупер полезно на CI.
Примеры можно посмотреть в README
⚠️ Важно: пакет @statoscope/ui-webpack был распилен на 2:
- @statoscope/webpack-plugin
- @statoscope/webpack-ui
Если вы использовали статоскоп как webpack-плагин, то юзайте пакет @statoscope/webpack-plugin
Api не изменилось ☺️
В этом релизе я был сконцентрирован на декомпозиции большого пакета ui-webpack на несколько мелких.
Так же у статоскопа теперь своя github-организация.
Дальше будет переезд на TS и покрытие тестами. А еще дальше буду пробовать собственный формат статов и двигать его в массы, так сказать :)
А еще, хочу уделять больше времени написанию технических постов (давно ничего не писал, исправлюсь)
GitHub
statoscope/packages/cli/README.md at master · statoscope/statoscope
Statoscope is a toolkit to analyze and validate webpack bundle - statoscope/statoscope
Всем привет!
Я наконец написал технический пост на тему внутренного устройства Statoscope - https://medium.com/@smelukov/метаинформация-о-сборке-5469a7ab6aa4
Заходите, читайте, комментируйте, задавайте вопросы ☺️
Я наконец написал технический пост на тему внутренного устройства Statoscope - https://medium.com/@smelukov/метаинформация-о-сборке-5469a7ab6aa4
Заходите, читайте, комментируйте, задавайте вопросы ☺️
Ох, как интересно, в webpack 5.49 можно импортировать http-модули 🚀
Импортированные модули кладутся в локальный кеш, поддерживается его обновление. Консистентность обеспечиваешь хешиком(как в package-lock)
Пример из директории examples
Доступно под флагом
Импортированные модули кладутся в локальный кеш, поддерживается его обновление. Консистентность обеспечиваешь хешиком(как в package-lock)
Пример из директории examples
Доступно под флагом
experiments.buildHttpGitHub
Release v5.49.0 · webpack/webpack
Features
add experiments.buildHttp to build http(s):// imports instead of keeping them external
keeps a webpack.lock file with integrity and webpack.lock.data with cached content that should be c...
add experiments.buildHttp to build http(s):// imports instead of keeping them external
keeps a webpack.lock file with integrity and webpack.lock.data with cached content that should be c...