Defront — про фронтенд-разработку и не только
24.3K subscribers
21 photos
1.09K links
Ламповый канал про фронтенд и не только. Всё самое полезное для опытных web-разработчиков

Обсуждение постов @defrontchat

Также советую канал @webnya
Download Telegram
В прошедшую субботу в Яндексе был митап "Я❤️Frontend". На нём выступал мой коллега Антон Кастрицкий с докладом «Вебпак, вид сквозь монокль». Для меня это был один из самых интересных и полезных докладов.

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

В общем, рекомендую посмотреть, даже если вы давно пользуетесь Webpack. Информации много и представлена она очень хорошо и доступно.

#webpack #talk

https://www.youtube.com/watch?v=iWPu3Crpys0&t=6077
Сэм Сакконе из Google написал статью про профилирование webpack-сборки — "Why is my webpack build slow?"

В статье описывается три подхода к профилированию сборки:
1. Использование webpack-плагина ProfilingPlugin
2. Использование встроенных в node.js средств профилировки
3. Использование профилировщика Chrome Dev Tools

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

Статью точно стоит почитать, если вы используете webpack и хотите выяснить, что негативнее всего влияет на сборку проекта.

#webpack #performance #build

https://samsaccone.com/posts/why-is-my-webpack-build-slow.html
Попалась на глаза подборка туториалов Робина Вирух про настройку React-проекта с нуля от создания package.json до настройки enzyme и hot module replacement.

Туториалы очень хорошие. В них всё написано по делу, понятно и аккуратно. Автор поддерживает их в актуальном состоянии; несмотря на то что некоторые статьи были опубликованы более двух лет назад, в них рассматриваются последние версии библиотек. Я немного запутался с перекрёстными ссылками, поэтому вот список ссылок на статьи в корректном порядке:

1. How to set up a modern JavaScript project
2. How to set up a Webpack project
3. How to set up Webpack with Babel
4. How to set up an advanced Webpack application
5. How to set up React with Webpack and Babel
6. How to test React components with Jest
7. How to test React components with Jest & Enzyme

Очень рекомендую пройти туториалы, если вы не настраивали сборку проекта самостоятельно.

#tutorial #webpack #react #jest
Вчера я написал про первую часть цикла статей Джереми Вагнера про производительность. Сегодня прочитал вторую — "Responsible JavaScript: Part II".

В этой статье Джереми приводит конкретные практические примеры, которые могут помочь в снижении объёма JavaScript-бандлов. Начинается она с обсуждения tree-shaking. Надо помнить, что он работает только благодаря статической природе модульной системы из ES2015. Поэтому, если вы используете babel, надо убедиться, что в настройках @babel/preset-env стоит modules: false, чтобы экспорты и импорты не преобразовывались в CommonJS. Для определения мест, где можно добавить code splitting, можно проанализировать те точки приложения, где происходит обработка пользовательского взаимодействия. Если приложение использует загружаемые скрипты со сторонних сайтов, следует убедиться, что они помечены в конфиге webpack как externals, для того чтобы исключить их из бандла.

Ещё можно настроить сборку так, чтобы собиралось два бандла (один для старых браузеров, второй для современных), и с помощью такого трюка загружать только необходимый код:
<!-- Modern browsers load this file: -->
<script type="module" src="/js/app.mjs"></script>
<!-- Legacy browsers load this file: -->
<script defer nomodule src="/js/app.js"></script>


Если первая часть была из категории "интересно почитать", то вторая попадает в категорию "must read".

#js #performance #webpack

https://alistapart.com/article/responsible-javascript-part-2/
Эяль Эйзенберг из Wix рассказал про свой опыт уменьшения бандла приложения с помощью React Lazy/Suspense и код-сплиттинга — "Trim the Fat From Your Bundles Using Webpack Analyzer & React Lazy/Suspense".

В начале статьи автор пишет про меры, которые можно предпринять на этапе разработки, чтобы размер приложения внезапно не вырос. Для оценки размера подключаемой библиотеки её стоит проверить c помощью сервиса Bundlephobia. Для того чтобы размер импортируемых библиотек всегда был на виду, можно использовать плагин import-cost (есть поддержка VS Code, Vim, WebStorm, Atom). Далее в статье разбирается пример динамической загрузки кода с помощью React.lazy и React.Suspense, который позволяет вынести часть кода в отдельный чанк. Выглядит он так:
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
return (
<div>
<React.Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</React.Suspense>
</div>
);
}


После всех оптимизаций размер бандла удалось уменьшить на 80%.

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

#performance #webpack #react

https://www.wix.engineering/post/trim-the-fat-from-your-bundles-using-webpack-analyzer-react-lazy-suspense
Последние дни занимался настройкой webpack. Сегодня прикручивал загрузчик для SVG. Пока не стал заморачиваться со спрайтами, воспользовался svg-url-loader. Этот загрузчик в отличии от url-loader при инлайне изображений не кодирует их в base64, а использует url-encoded XML. Стало интересно, какими принципами следует лоадер — нашёл статью Тейлора Ханта "Optimizing SVGs in data URIs", в которой объясняется самая лучшая стратегия для инлайна.

Простого преобразования с помощью encodeURIComponent недостаточно, так как в результате обычно получается закодированный текст, который длиннее исходного текста SVG. Поэтому SVG кодируется "точечно", так чтобы закодированное сообщение содержало как можно меньше закодированных "unsafe URL" символов. Наибольший эффект получается от замены двойных кавычек апострофом, так как он попадает в категорию "safe URL" символов. Благодаря этому вместо трёх байтов для кодирования двойной кавычки используется один байт. Если кодируется сложный SVG с большим количеством атрибутов, это легко может сократить сотню байт.

У вас может возникнуть вполне резонный комментарий, что получившаяся экономия совсем ни о чём. Но в некоторых случаях, она может помочь избавиться от пары запросов к серверу (при использовании limit в svg-url-loader ), ускоряя отображение SVG в браузере.

#performance #svg #webpack

https://codepen.io/tigt/post/optimizing-svgs-in-data-uris
https://github.com/bhovhannes/svg-url-loader
Сергей Мелюков (контрибьютор Webpack) написал статью про новую экспериментальную фичу Webpack 5 Beta — Asset Modules.

Традиционный подход работы с ассетами (svg, png, woff, etc.) подразумевает установку и настройку дополнительных загрузчиков: file-loader, url-loader, raw-loader. Asset Modules — это новая фича, благодаря которой Webpack может работать с ассетами "из коробки" без установки дополнительных загрузчиков.

Asset Modules добавляет несколько типов ассетов:
asset (копирование файла в dist при превышении лимита на размер файла и инлайн файла, если его объём меньше лимита)
asset/inline (аналог url-loader — файлы, попадающие под этот тип, инлайнятся всегда)
asset/resource (аналог file-loader — файлы, попадающие под этот тип, всегда копируются в dist)
asset/source (аналог raw-loader — инлайн файла в бандл в неизменном виде)

Asset Modules — это экспериментальная фича. Разработчики ждут от пользователей обратную связь.

#webpack #bundler #experimental

https://habr.com/ru/post/488464/ (на русском языке)
https://dev.to/smelukov/webpack-5-asset-modules-2o3h
Джонатан Лай из Etsy рассказал, как его команда ускорила Webpack-сборку приложения — "The journey to fast production asset builds with Webpack".

Первая версия приложения собиралась самописным сборщиком "builda". Команда Etsy занималась его поддержкой, но не успевала за развитием js-экосистемы, поэтому было принято решение перевести сборку на Webpack. Главными требованием было время сборки — не более 5 минут.

Проект состоит из более 12000 модулей, которые с учётом одиннадцати локалей собираются в 13200 ассетов. Подход "в лоб" с использованием готовых Webpack-плагинов увеличил время сборки до 40 минут (сборка с использованием legacy-сборщика проходила за 5 минут). Основная проблема заключалась в лишней работе при генерации локалей. В итоге ребятя сделали своё решение, в котором ассеты для всех локалей генерируются один раз. Решили проблему со скоростью минификации файлов. Terser-webpack-plugin в их случае неэффективно работал с большим количеством модулей из-за того, что главный поток упирался в работу с диском и сериализовывал большое количество данных перед отправкой в воркеры. Процесс минификации вынесли из сборщика в отдельный шаг пост-процессинга.

Очень интересная статья. Рекомендую почитать, если используете Webpack.

#webpack #performance

https://codeascraft.com/2020/02/03/production-webpack-builds/
Команда разработчиков Chrome активно контрибьютит в инструменты js-экосистемы и фреймворки. Хуссейн Джирде написал статью про один из таких кейсов сотрудничества — "Improved Next.js and Gatsby page load performance with granular chunking".

В Next.js и Gatsby в бандл commons попадал код, который использовался более чем на 50% страниц. Такая настройка была не очень эффективна, так как общий код оставшихся 50% страниц не разделялся между чанками. Для решения этой проблемы была адаптирована стратегия, в которой с помощью SplitChunksPlugin:
— все модули больше 160kb выносятся в индивидуальные чанки;
— создаётся отдельный чанк frameworks с кодом, который используется на всех страницах ( react, react-dom и т.п.);
— создаётся столько общих чанков, сколько webpack посчитает нужным создать, но не более 25.

Такие настройки позволяют улучшить скорость загрузки и улучшить утилизацию кеша при переходе между страницами. При переходе на новую стратегию разделения чанков общий размер генерируемого js-кода на production-сайтах уменьшился в среднем на 20%.

Рекомендую почитать статью, если интересуетесь темой производительности.

#webpack #performance

https://web.dev/granular-chunking-nextjs/
Вчера зарелизился Webpack 5 с огромным количеством изменений.

TLDR

В новой версии была улучшена скорость сборки. Была улучшена поддержка долгосрочного кэширования бандлов. Улучшен tree shaking. Реализован новый подход для работы с ассетами. Добавлена новая фича Module Federation. Удалены полифиллы для Node.js-модулей. Код сборки может генерироваться в стандарте ES2015.

Подробнее

Улучшена скорость сборки благодаря кэшированию на диске служебных данных между разными сборками (Persistent Caching).

Было проделано много работы для улучшения tree-shaking. В новой версии Webpack использует статический анализ для построения графа зависимостей, благодаря чему удаляется больше неиспользуемого кода. Также Webpack благодаря статическому анализу определяет модули без сайд-эффектов и не включает их в бандл, если они не используются. Был улучшен tree-shaking CommonJS-модулей.

Было упрощено использование ассетов. Теперь не нужно устанавливать дополнительные загрузчики, например, file-loader, url-loader, raw-loader. Сергей Мелюков в феврале публиковал статью про ассеты в Webpack 5, рекомендую почитать.

С пятой версии стала доступна ещё одна новая фича — Module Federation. Благодаря ей приложение может прозрачно заимствовать код из других приложений. Это позволяет делать интересные вещи, например, разделить одно большое SPA на несколько небольших. Это SPA с точки зрения пользователя будет работать как одно целое, но может разрабатываться и деплоиться разными командами независимо друг от друга.

Улучшена совместимость с Web-платформой: добавлена поддержка Top Level Await, JSON Modules, WASM Modules, import.meta.

Четвёртая версия Webpack могла генерировать код сборки только в стандарте в ES5. С пятой версии код сборки может генерироваться в стандарте ES2015.

Были удалены полифиллы для Node.js ( node.Buffer, node.console, node.process, crypto и т.п.) Когда появился Webpack, npm чаще всего использовали для распространения Node.js-модулей, поэтому в то время имело смысл поставлять со сборщиком полифиллы. Сейчас ситуация изменилась — в npm есть много кода, который можно использовать и в Node.js, и в браузерах. Также очень много внимания сегодня уделяют размеру генерируемого кода, а полифиллы Node.js могут добавлять очень много кода. Но не все рады удалению полифиллов. Синдре Сорхусу — автору многих библиотек в экосистеме Node.js — это решение не понравилось. Он пишет про то, что не будет исправлять проблемы, связанные с Webpack 5.

В общем, релиз очень большой. Ребята проделали огромную работу. В статье написано, что есть вероятность появления проблем при использовании свежей версии, но начинать миграцию сборки уже можно. Разработчики ждут нашего фидбека и сообщений об ошибках.

#webpack #release #bundle

https://webpack.js.org/blog/2020-10-10-webpack-5-release/
Поиск причины деградации времени сборки Webpack 5

Оуэн Хэннесси поделился историей поиска бага, из-за которого время запуска dev-сервера Webpack замедлилось в пятнадцать раз — "Understanding why our build got 15x slower with Webpack 5".

Проблема возникла после добавления невинной тёмной темы. Первые подозрения упали на CSS-in-JS-библиотеку Linaria. С помощью профилировщика внутри библиотеки была найдена проблемная функция, в которой использовался метод массива .concat(). Переписывание кода без использования .concat() решило проблему. Однако оставались вопросы, из-за того что в оригинальном коде просадки скорости не было при сборке проекта с помощью Webpack 4. Надо было исследовать исходники V8.

В V8 у метода .concat() есть две ветки выполнения кода — медленная и быстрая. Медленная ветка начинает работать в том случае, если движок хотя бы один раз устанавливал Symbol.isConcatSpreadable. В Webpack 5 это происходило в коде, отвечающем за обратную совместимость с четвёртой версией. Для решения проблемы разработчики Webpack добавили экспериментальную опцию backCompat, которая полностью отключает обратную совместимость, избавляясь от ещё большего количества проблемного кода.

#v8 #performance #webpack

https://engineering.tines.com/blog/understanding-why-our-build-got-15x-slower-with-webpack
Statoscope — тулкит для анализа Webpack-бандлов

На Smashing Magazine был опубликован транскрипт доклада Сергея Мелюкова про тулкит для анализа Webpack-бандлов — "Statoscope: A Course Of Intensive Therapy For Your Bundle".

С помощью Statoscope можно сравнить две сборки между собой и получить информацию об увеличении размера бандла, времени сборки и т.п. Он помогает обнаруживать дубликаты пакетов в бандле и, в отличие от webpack-bundle-analyzer, показывает конкретные файлы, в которых происходит импорт этих пакетов. Его можно использовать в CI для блокирования пулл-реквестов, если какой-либо критический показатель выходит за установленное порог. В нём поддерживается создание кастомных отчётов с помощью Jora и DiscoveryJS.

Statoscope используется в проектах Яндекса: в Яндекс.Маркете, Яндекс.Картах, Кинопоиске. Также он используется в библиотеке size-limit.

#webpack #bundle #tool

https://www.smashingmagazine.com/2022/02/statoscope-course-intensive-therapy-bundle/
https://www.youtube.com/watch?v=aAkmZ0gMYQ8 (доклад на русском)