1. HTML:
- минификация
- потоковая отрисовка (помогает уменьшить TTFB (time to first byte))
Статья про обработку html сервис воркерами: https://philipwalton.com/articles/smaller-html-payloads-with-service-workers/
2. CSS:
- минификация
- критический css:
заинлайнить в html
<head> <style /> </head>
потому что пока не пришел ответ со стилями, браузер не начнет отрисовывать render tree- загрузка не блокирующая рендер (хак: использовать
<link href... media="print" onload="this.media='all'" - будет грузить стили, но т к медиа - print, не будет блокироваться рендер, а как загрузится, проставляем ему медиа - all (стили начинают применяться к рендеру))Посмотреть размер неиспользуемого css можно в devtools -> coverage
Полезные плагины для webpack:
- html-critical-webpack-plugin
- critters-webpack-plugin
Статья про блокирующий CSS https://timkadlec.com/remembers/2020-02-13-when-css-blocks/
3. Шрифты
- предзагружаем через link rel=preload
- указываем системный fallback шрифт
- кеширование
- используем font-display (swap или fallback)
4. Картинки
Статья https://evilmartians.com/chronicles/images-done-right-web-graphics-good-to-the-last-byte-optimization-techniques
5. JS
загрузка и исполнение js может блокировать парсинг html
долгое исполнение js делает сайт не отзывчивым
- использовать async или defer аттрибуты
Теперь кстати парсинг html не блокируется при загрузке скриптов https://v8.dev/blog/v8-release-78
Уменьшаем размер
- минификация
- удаление ненужного:
dead-code elimination при помощи terser и env vars
- code splitting
devtools -> coverage посмотреть что нужно сразу после загрузки
https://webpack.js.org/guides/code-splitting/
обратить внимание на дудепликацию зависимостей
После code splitting возможно, что какой то функционал будет подгружаться динамически и где-то это может быть неприемлемо. Для этого нужно делать предзагрузку с preload/prefetch/preconnect/prerender/modulepreload.