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

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

Также советую канал @webnya
Download Telegram
Филлип Уолтон недавно опубликовал статью про проблему каскадной инвалидации кэша — «Cascading Cache Invalidation».

Нежелательная инвалидация может возникнуть тогда, когда сборщик генерирует имена файлов с хэшами, которые напрямую импортируются в других файлах. Предположим, что во время сборки из всех файлов, находящихся в node_modules, создаётся файл vendor.<hash>.js. Если этот файл импортируется в других модулях, то из-за постоянно меняющегося хэша, будут изменяться хэши у всех зависимых модулей. Соответственно, браузер будет заново загружать тот код, который фактически не менялся.

Для решения этой проблемы Филлип предлагает использовать import maps (на данный момент поддержка есть только в Chrome за флагом), сервис воркеры или AMD-загрузчик (в статье разбирается пример SystemJS с Rollup.js).

Webpack не подвержен этой проблеме, но с ним есть другие особенности, которые могут приводить к неочевидным ошибкам.

В общем, статья полезная. Рекомендую почитать.

#performance #bundle

https://philipwalton.com/articles/cascading-cache-invalidation/
Дэвид Калхоун написал статью про влияние на производительность разных подходов к бандлингу кода — "Bundling JavaScript for Performance: Best Practices".

Самый лучший вариант отделить вендорный код от кода приложения и доставлять бандлы до пользователей с помощью CDN-провайдеров. Подключение библиотек, которые хранятся на публичных CDN (cdnjs, jsdelivr и т.п.), нежелательно. В Safari использование публичных CDN приводит к лишнему запросу даже в том случае, когда в соседней вкладке другой сайт загружал ту же самую библиотеку с того же самого сервера. Это сделано для предотвращения отслеживания пользователей. В Chrome отключение общего кеша появилось с 77-ой версии, но пока за флагом.

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

#performance #bundle

https://calendar.perfplanet.com/2019/bundling-javascript-for-performance-best-practices/
Иван Акулов проанализировал js-бандлы и флоу загрузки web-приложения Notion и дал много советов по улучшению его производительности — "Case study: Analyzing Notion app performance".

Приложение загружается долго, это особенно заметно на смартфонах среднего ценового сегмента — время загрузки достигает 12 секунд. Больше всего времени уходит на парсинг и выполнение JS. В решении этой проблемы может помочь код-сплиттинг и удаление ненужного кода. Notion использует lodash, чтобы удалить из его кода неиспользуемые методы юзают babel-plugin-lodash. Notion для работы с датами использует moment, вместо этой библиотеки лучше использовать современные и оптимизированные альтернативы, например, date-fns. Также в бандле приложения было найдено три разных версии core.js — библиотеки полифиллов. Такое происходит, когда приложение и зависимости используют core.js разных версий. Для решения этой проблемы можно настроить маппинг модулей с помощью resolve.alias в конфиге wepback. В статье есть рекомендация транспилировать модули в CommonJS с помощью babel-плагина plugin-transform-modules-commonjs с опцией lazy. Такая оптимизация позволяет отложить выполнение js-кода, который можно не выполнять на этапе инициализации приложения.

Очень большая и хорошая статья. Обязательно почитайте, если разрабатываете SPA.

#performance #bundle

https://3perf.com/blog/notion/
Для того чтобы бандлер смог безопасно применить tree-shaking, он должен понимать, что можно удалить, а что нужно оставить. Серджио Гомес написал про это статью — "Everything you never wanted to know about side effects".

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

Чтобы tree-shaking заработал, авторы библиотек добавляют в package.json поле "sideEffects": false, если в библиотеке нет сайд-эффектов, или явно перечисляют файлы, которые нельзя удалять "sideEffects": ["a.js", "b.js"]. Также в исходном коде можно использовать хинт /*#__PURE__*/. Благодаря этому хинту бандлер понимает, что такой код не содержит сайд-эффектов, и его можно безопасно удалить.

Очень рекомендую заглянуть в статью авторам библиотек и всем, кто сталкивался с проблемами tree-shaking.

#performance #bundle

https://sgom.es/posts/2020-06-15-everything-you-never-wanted-to-know-about-side-effects/
Вчера зарелизился 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/
В блоге debugbear было опубликовано исследование проблем производительности интерфейса Google Cloud — "Why is the Google Cloud UI so slow?".

Google Cloud — это SPA, написанное на Angular. Оно включает в себя несколько страниц, которые загружают по 4-5Мб сжатого JavaScript-кода. Основное содержимое страницы появляется через шесть секунд после начала загрузки страницы.

Основные идеи из статьи. Для SPA очень критично время выполнения кода. Чем больше бандл, тем больше времени требуется на его парсинг, компиляцию, инициализацию, поэтому очень важно не заставлять пользователей скачивать лишний код. В Google Cloud на момент инициализации страницы используется только 50% от всего загруженного кода. Также в разных бандлах дублируются одни и те же компоненты и конфигурационный код. Ещё в статье есть рекомендация загружать второстепенный контент (например, меню) только тогда, когда он, действительно, будет нужен.

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

#performance #js #bundle

https://www.debugbear.com/blog/slow-google-cloud-ui
На прошедшем Chrome Dev Summit Хуссейн Джирде и Джейсон Миллер рассказали про использование JavaScript-кода с современным синтаксисом. По мотивам этого доклада была написана статья "Publish, ship, and install modern JavaScript for faster applications".

Многие проекты по инерции используют транспиляцию новых фич JavaScript в ES5, из-за чего страдает производительность в современных браузерах. Транспиляция в ES5 нужна только для старых браузеров, которыми пользуются 5% пользователей. Чтобы доставить разные версии бандлов для современных и старых браузеров, можно использовать паттерн module/nomodule. Для его реализации нужно собрать два бандла: лёгкий для современных браузеров (ES2017) и тяжёлый для устаревших браузеров (ES5). В статье подробно разбирается, как это сделать с помощью webpack и rollup. Ещё в статье есть советы о том, как публиковать npm-пакеты с современным синтаксисом.

Также в докладе/статье был анонсирован новый сервис EStimator.dev, с помощью которого можно оценить прирост производительности сайта от перехода на современный синтаксис.

#js #performance #bundle

https://web.dev/publish-modern-javascript/
Несколько дней назад вышла новая версия Snowpack. Фред Шотт — автор проекта — рассказал про все новинки релиза.

Snowpack — это инструмент для сборки фронтенд-приложений. В отличие от Webpack, Rollup и Parcel, приложения, использующие Snowpack, не нуждаются в пересборке бандла на каждое изменение файлов во время разработки. Snowpack транспилирует файлы точечно без бандлинга всех файлов, делегируя процесс создания графа зависимостей и его загрузки браузерам с помощью нативных JavaScript-модулей. То есть если вы пишете большое приложение и сделали изменения, например, в файле Header.tsx, то транспилироваться будет только он, тем самым уменьшая время обратной связи на каждое изменение файлов в разы по сравнению с другими бандлерами.

В Snowpack v3.0 были добавлены Streaming Imports. Благодаря им Snowpack может загружать и кэшировать npm-модули без явного использования npm install. С этой версии Snowpack может создавать оптимизированные production-билды с помощью esbuild (очень быстрый сборщик, написанный на Go). Реализован новый API, который уже используется в SvelteKit. Сгенерированные с помощью Snowpack файлы теперь можно без проблем импортировать в Node.js.

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

#release #bundle #tool

https://www.snowpack.dev/posts/2021-01-13-snowpack-3-0
Несколько дней назад команда разработчиков Vue зерилизила Vite 2.0. В статье "Announcing Vite 2.0" Эван Ю рассказал о новом проекте.

Vite — это сборщик и dev server, использующий ESM, для ускорения применения изменений на этапе разработки. По своей философии он очень похож на Snowpack и WMR.

Vite создавался для улучшения разработки Vue-приложений, но команда разработчиков решила сделать его независимым от Vue (на данный момент есть поддержка Vue, React, Preact и LitElement). Из-за смены курса разработки первая версия так и не достигла стабильной версии, поэтому Vite 2.0 можно считать официальной первой стабильной версией.

Vite очень похож на Snowpack, но в нём есть несколько уникальных фич: поддержка автоматического код-сплиттинга для CSS, поддержка многостраничных приложений, есть режим для разработки браузерных библиотек, есть встроенная поддержка монорепозиториев и CSS-препроцессоров.

#tool #bundle

https://dev.to/yyx990803/announcing-vite-2-0-2f0a
Хью Хауорт написал обзор современных инструментов сборки — "Comparing the New Generation of Build Tools".

В статье рассказывается про esbuild, Snowpack, Vite и wmr. Esbuild — это очень шустрый сборщик, написанный на Go. Snowpack, Vite и wmr — сборщики нового поколения. Они полагаются на нативную модульную систему JavaScript, устраняя шаг сборки приложения во время разработки.

Snowpack позволяет подключать и гибко настраивать разные сборщики для production-сборки проекта. Vite, наоборот, исповедует принцип zero-configuration, предоставляя набор настроек, которые подойдут большинству проектов. Wmr — самое лёгкое решение, но из коробки поддерживает только React и Preact. Esbuild в этом сравнении стоит особняком, так как это обычный, но очень быстрый сборщик.

Большая и хорошая статья. Очень рекомендую почитать.

#bundle #tool

https://css-tricks.com/comparing-the-new-generation-of-build-tools/
Франсуа Хендрикс рассказал о том, как сделать библиотеку, у которой не было бы проблем с три-шейкингом — "How To Make Tree Shakeable Libraries".

Недостаточно поправить конфиг сборки приложения, чтобы бандлер смог выкинуть неиспользуемый код библиотеки. Сама библиотека не должна мешать этому процессу. Eё код должен быть написан с использованием ESM и разбит на большое число небольших модулей, которые экспортируют только один кусок логики. При сборке библиотеки нужно настроить её бандлинг с сохранением структуры. Это нужно делать для того, чтобы бандлеры могли применять оптимизации, опираясь на информацию из поля sideEffects package.json.

Также в статье есть рекомендация не использовать транспиляцию перед публикацией библиотеки, так как наиболее оптимальную цель транспиляции знает только пользователь библиотеки. Если от транспиляции отказаться нельзя, то нужно проконтролировать, чтобы сохранился формат ESM.

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

#performance #bundle #library

https://blog.theodo.com/2021/04/library-tree-shaking/
Использование внешних ресурсов в JavaScript без сборки

Ингвар Степанян рассказал о способе подключения ресурсов приложения без сборки — "Bundling non-JavaScript resources".

Современные бандлеры позволяют импортировать стили, wasm-модули, изображения и т.п. После сборки такие импорты превращаются в набор URL, которые без проблем загружаются браузером. С внедрением нативной поддержки esm в браузеры такой подход вызывает проблемы, так как JavaScript-код с импортом внешних ресурсов нельзя использовать без сборки.

В статье предлагается использовать альтернативный паттерн, который распознаётся всеми браузерами — new URL('./relative-path', import.meta.url). Такой подход формирует в рантайме корректный URL ресурса для дальнейшего использования. import.meta.url нужно использовать, чтобы пути резолвились относительно текущего JavaScript-файла, а не относительно HTML-документа. Выражение new URL('...', import.meta.url) также распознаётся современными сборщиками при создании чанков с кодом.

В будущем new URL('...', import.meta.url) может быть заменён методом import.meta.resolve('...') (на данный момент в спецификации не решены некоторые вопросы). Также в браузеры потихоньку начинает проникать поддержка import assertions, но она не покрывает все возможные виды ресурсов.

#bundle #esm

https://web.dev/bundling-non-js-resources/
Способы уменьшения размера JavaScript-бандла

Бэн Шварц поделился советами о том, как держать размер JavaScript-бандла под контролем — "Small Bundles, Fast Pages: What To Do With Too Much JavaScript".

В статье Бэн рассказывает про общие вещи: о влиянии больших бандлов на производительность страницы, об оптимальном размере загружаемого кода (300kb) и о бюджете производительности. Есть более конкретные советы, например, использовать плагин Import Cost во время разработки, чтобы размер подключаемых библиотек был всегда на виду. Также есть рекомендации по использованию стороннего кода: о хостинге кода на своём сервере и использовании фасадов для уменьшения времени инициализации страницы.

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

#performance #bundle

https://calibreapp.com/blog/bundle-size-optimization
Анализ JS-бандла с помощью Lighthouse Treemap

Сиа Кармаленгос написала статью про новый инструмент анализа JS-бандлов, доступный в Lighthouse — "Explore JavaScript Dependencies With Lighthouse Treemap".

В последних версиях Lighthouse появилась новая фича — визуализация JS-бандлов с помощью Treemap. Если вы знакомы с webpack-bundle-analyzer, то уже можете представить себе новый инструмент. Основное отличие Treemap в Lighthouse — возможность анализа бандлов любых сборщиков. Если сборка происходит с генерацией сорс-мапов, то в Treemap будут отображаться названия модулей. Но самая интересная функция — оценка покрытия кода. Если включить опцию "unused bytes", то можно оценить сколько кода было загружено, но не выполнено.

Поддержка Lighthouse Treemap уже доступна в сервисе PageSpeed Insights, Lighthouse Node CLI и Chrome Canary.

#tool #js #bundle #performance

https://sia.codes/posts/lighthouse-treemap/
Релиз Parcel 2

Parcel — это сборщик, который можно использовать без каких-либо настроек. Все опции используют разумные значения по умолчанию. Точка входа для сборки — основной HTML-файл приложения или сайта. В новой версии была улучшена производительность сборки, реализована новая система плагинов, три-шейкинг, код-сплиттинг, улучшение сборок библиотек, улучшена работа HMR и многое другое.

Значительно улучшена производительность сборки благодаря новому компилятору, написанному на Rust. В его основе лежит swc. Использование компилируемого языка уменьшило время инициализации кода и решило проблему медленной сериализации больших AST-объектов. Сборка теперь работает в десять раз быстрее и в три раза быстрее при использовании Terser.

Реализована новая система плагинов, которая делает Parcel полностью расширяемым. Она позволяет использовать Parcel как для небольших проектов, так и для серьёзных проектов со сложными требованиями к сборке.

Три-шейкинг включён по умолчанию. Он работает для ESM, CommonJS, динамических импортов и CSS-модулей. Есть диагностика проблем три-шейкинга, которую можно включить с помощью флага --log-level verbose. Работает автоматический код-сплиттинг с выносом общих модулей в разделяемые бандлы. Также в Parcel по умолчанию включена поддержка паттерна module/nomodule для улучшения производительности загрузки кода.

В production-режиме в Parcel включена lossless-оптимизация JPEG- и PNG-изображений. Она уменьшает объём изображений, не снижая их качество. Также появилась полноценная поддержка SVG с автоматической оптимизацией с помощью SVGO.

Реализован ленивый режим разработки, в котором собираются только те файлы, которые в данный момент запрашиваются браузером, тем самым улучшая время запуска dev-сервера.

#bundle #tool #release

https://parceljs.org/blog/v2/
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 (доклад на русском)