Перейти к содержимому

Производительность

Из коробки SvelteKit проделывает большую работу, чтобы ваше приложение было максимально производительным:

  • Разделение кода, чтобы загружался только тот код, который нужен для текущей страницы
  • Предзагрузка ресурсов, чтобы предотвратить «каскады запросов» (когда файлы запрашивают другие файлы)
  • Хэширование файлов, чтобы ваши ресурсы могли кэшироваться бесконечно
  • Объединение запросов, чтобы данные, запрошенные из отдельных серверных функций load, объединялись в один HTTP-запрос
  • Параллельная загрузка, чтобы отдельные универсальные функции load запрашивали данные одновременно
  • Встраивание данных, чтобы запросы, выполненные через fetch во время серверного рендеринга, могли быть воспроизведены в браузере без нового запроса
  • Консервативная инвалидация, чтобы функции load выполнялись повторно только при необходимости
  • Предрендеринг (настраивается для каждого маршрута при необходимости), чтобы страницы без динамических данных отдавались мгновенно
  • Предзагрузка ссылок, чтобы данные и код, необходимые для клиентской навигации, загружались заранее

Тем не менее, мы пока не можем устранить все источники замедления. Чтобы выжать максимальную производительность, стоит учитывать следующие рекомендации.

Отличными инструментами для понимания характеристик производительности уже развёрнутого сайта являются PageSpeed Insights от Google и (для более глубокого анализа) WebPageTest.

Ваш браузер также содержит полезные инструменты разработчика для анализа сайта — как в продакшене, так и при локальной разработке:

Обратите внимание: сайт, запущенный локально в режиме dev, ведёт себя иначе, чем продакшен-приложение. Поэтому тестировать производительность следует в режиме предпросмотра после сборки.

Если в сетевой вкладке браузера вы видите, что запрос к API занимает много времени, и хотите понять причину, можно добавить инструментирование бэкенда с помощью таких инструментов, как OpenTelemetry или заголовки Server-Timing.

Уменьшение размера файлов изображений часто даёт один из самых заметных приростов производительности сайта. Svelte предоставляет пакет @sveltejs/enhanced-img, который подробно описан на странице Изображения и существенно упрощает эту задачу. Кроме того, Lighthouse хорошо помогает выявить самые «тяжёлые» изображения.

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

  • Сжимайте видео с помощью инструментов вроде Handbrake. Рассмотрите возможность конвертации в веб-ориентированные форматы — .webm или .mp4.
  • Вы можете лениво загружать видео, находящиеся ниже области видимости, используя preload="none" (учтите, что это замедлит начало воспроизведения, когда пользователь всё же запустит видео).
  • Удаляйте звуковую дорожку из видео без звука с помощью инструмента FFmpeg.

SvelteKit автоматически предзагружает критические файлы .js и .css при посещении страницы, но не предзагружает шрифты по умолчанию, так как это может привести к загрузке лишних файлов (например, начертаний шрифта, которые объявлены в CSS, но не используются на текущей странице). Тем не менее, правильная предзагрузка шрифтов может существенно улучшить субъективную скорость сайта. В хуке handle вы можете вызвать resolve с фильтром preload, который включает ваши шрифты.

Уменьшить размер файлов шрифтов можно с помощью использования подмножеств.

Мы рекомендуем использовать самую свежую версию Svelte. Svelte 5 меньше и быстрее, чем Svelte 4, который, в свою очередь, меньше и быстрее Svelte 3.

Пакет rollup-plugin-visualizer помогает определить, какие пакеты вносят наибольший вклад в размер вашего приложения. Также полезно вручную изучить результат сборки (для этого временно установите build: { minify: false } в конфигурации Vite, чтобы код был читаемым, но не забудьте вернуть настройку перед развёртыванием) или проанализировать вкладку «Сеть» в инструментах разработчика браузера.

Старайтесь минимизировать количество сторонних скриптов, выполняющихся в браузере. Например, вместо JavaScript-аналитики рассмотрите серверные реализации, которые предлагают многие платформы с адаптерами SvelteKit: Cloudflare, Netlify и Vercel.

Чтобы запускать сторонние скрипты в веб-воркере (это не блокирует основной поток), используйте интеграцию Partytown для SvelteKit.

Код, импортированный через статические объявления import, автоматически попадает в бандл страницы. Если какой-то код нужен только при выполнении определённого условия, используйте динамический import(...) для ленивой загрузки компонента.

Вы можете ускорить клиентскую навигацию, заранее предзагружая необходимый код и данные с помощью параметров ссылок. По умолчанию это уже настроено на элементе <body> при создании нового проекта SvelteKit.

Для данных, которые загружаются медленно и не нужны сразу, объект, возвращаемый из функции load, может содержать промисы вместо самих данных. Для серверных функций load это приведёт к тому, что данные будут потоково передаваться уже после завершения навигации (или начальной загрузки страницы).

Одной из главных причин снижения производительности являются так называемые каскады запросов — последовательная цепочка запросов. Они могут возникать как на сервере, так и в браузере, но особенно болезненны, когда данные проходят большое расстояние или через медленные сети (например, мобильный пользователь обращается к далёкому серверу).

В браузере каскады часто возникают, когда HTML инициирует цепочку: запрос JS → запрос CSS → запрос фонового изображения и веб-шрифта. SvelteKit в значительной степени решает эту проблему автоматически, добавляя теги или заголовки modulepreload. Тем не менее, проверяйте вкладку «Сеть» в инструментах разработчика, чтобы убедиться, что все необходимые ресурсы предзагружаются.

  • Особое внимание обратите на веб-шрифты — их нужно обрабатывать вручную.
  • Включение режима одностраничного приложения (SPA) провоцирует появление таких каскадов. В SPA-режиме сначала отдаётся пустая страница, которая затем загружает JavaScript и только потом рендерит контент. Это приводит к дополнительным сетевым кругам до момента отображения первого пикселя.

Каскады также могут возникать при обращениях к бэкенду — как из браузера, так и с сервера. Например, если универсальная функция load сначала запрашивает текущего пользователя, потом на основе ответа запрашивает список сохранённых элементов, а затем для каждого элемента запрашивает детали — браузер выполнит несколько последовательных запросов. Это крайне негативно сказывается на производительности, особенно для пользователей, находящихся далеко от вашего сервера.

  • Избегайте этой проблемы, используя серверные функции load для запросов к бэкенду. Однако даже серверные load не застрахованы от каскадов (хотя они гораздо менее критичны, так как обычно не требуют долгих сетевых путешествий). Например, вместо двух отдельных запросов к базе данных (сначала пользователь, потом список) часто эффективнее выполнить один запрос с JOIN.

Фронтенд должен находиться в том же дата-центре, что и бэкенд, чтобы минимизировать задержки. Для сайтов без единого бэкенда многие адаптеры SvelteKit поддерживают edge-развёртывание — запросы каждого пользователя обрабатываются на ближайшем сервере. Это значительно ускоряет загрузку. Некоторые адаптеры позволяют настраивать развёртывание для отдельных маршрутов.

Также рекомендуется раздавать изображения через CDN (которые обычно тоже являются edge-сетями) — многие хостинги для SvelteKit делают это автоматически.

Убедитесь, что ваш хостинг использует HTTP/2 или более новую версию. Благодаря разделению кода в Vite создаётся много небольших файлов для лучшего кэширования. Это даёт отличную производительность, но требует возможности параллельной загрузки файлов, которую обеспечивает HTTP/2.

В целом, создание производительного приложения на SvelteKit мало отличается от создания любого другого быстрого веб-приложения. Вы можете смело применять знания из общих материалов по веб-производительности, таких как Core Web Vitals.