Insights / Технические материалы
Практические методы улучшения PageSpeed на сайте Astro
Практические методы оптимизации сайта на Astro, UnoCSS и Cloudflare Pages. Рассматриваются доставка CSS, настройка шрифтов, адаптивные изображения, текущая загрузка AdSense и GA4 и кэширование.

Содержание
- Введение
- Почему Astro?
- Стратегия доставки CSS: встроенный vs внешний
- При встраивании CSS
- При использовании внешнего CSS
- Решение: вынесение во внешний файл + неизменяемый кэш
- Оптимизация шрифтов: проверка фактической доставки
- Сравнение внешней и локальной доставки
- Текущее состояние репозитория
- Оптимизация изображений: Cloudflare Images + srcset + sizes
- Transformations Cloudflare Images
- Настройка srcset и sizes
- Точность sizes
- Улучшение LCP: preload
- Предотвращение CLS (сдвиг макета)
- Управление загрузкой рекламы и отложенная аналитика
- AdSense
- GA4
- Стратегия кэширования
- Чек-лист оптимизации производительности
- Заключение
- Серия статей
Введение
Официальный сайт Acecore построен на Astro 7.1.3 + UnoCSS + Cloudflare Pages. В статье описаны настройки оптимизации, проверенные в репозитории 29 июля 2026 года.
Результаты PageSpeed Insights зависят от времени, устройства и сети. Поэтому фиксированная оценка не приводится: сравнивайте изменения в одинаковых условиях по Core Web Vitals и объёму передачи.
Почему Astro?
Astro поддерживает статическую генерацию сайтов (SSG) и позволяет добавлять клиентский JavaScript только там, где он нужен. Текущий сайт также доставляет скрипты ClientRouter, поиска, рекламы и аналитики, поэтому не следует считать страницу полностью свободной от JavaScript: измеряйте объём доставки и показатели рендеринга.
Сайт использует UnoCSS с presetWind3(). CSS создаётся из utility-классов, обнаруженных при сборке, что может уменьшить объём доставки, но не гарантирует минимальный размер. Проверяйте сгенерированный CSS и фактически используемые классы.
Стратегия доставки CSS: встроенный vs внешний
Доставка CSS влияет на размер HTML, дополнительные запросы и кэш браузера.
При встраивании CSS
Установка build.inlineStylesheets: 'always' в Astro встраивает весь CSS в HTML. Это убирает запросы внешних CSS и в зависимости от страницы может улучшить FCP (First Contentful Paint).
Подходящие условия зависят от размера CSS и структуры страницы; одного фиксированного порога недостаточно.
При использовании внешнего CSS
Внешние файлы позволяют повторно использовать общий CSS с хэшем через кэш браузера.
Текущий сайт использует build.inlineStylesheets: 'auto' и проверяет сгенерированный вывод при настройке.
Решение: вынесение во внешний файл + неизменяемый кэш
Измените настройку Astro на build.inlineStylesheets: 'auto'. Astro автоматически примет решение на основе размера CSS, отдавая большой CSS как внешние файлы.
// astro.config.mjs
export default defineConfig({
build: {
inlineStylesheets: "auto",
},
});
Внешние CSS-файлы выводятся в директорию /_astro/, поэтому примените неизменяемый кэш через настройки заголовков Cloudflare Pages.
/_astro/*
Cache-Control: public, max-age=31536000, immutable
После изменения проверьте сгенерированный HTML, CSS-файлы и работу кэша, затем повторите PageSpeed Insights в тех же условиях.
Оптимизация шрифтов: проверка фактической доставки
Сравнение внешней и локальной доставки
Внешние шрифты могут добавить соединение в критический путь. Локальная доставка тоже отправляет CSS и файлы шрифта с сайта; сравнивайте оба подхода в одинаковых условиях.
В панели сети проверяйте запросы шрифтов, кэш и объём передачи, а в Rendered Fonts — какие шрифты браузер использовал фактически.
Текущее состояние репозитория
В package.json есть @fontsource/noto-sans-jp, но на 29 июля 2026 года он нигде не импортируется из src. Само наличие зависимости не доказывает доставку шрифта.
Текущий стек шрифтов UnoCSS:
// uno.config.ts
theme: {
fontFamily: {
sans: "'Noto Sans JP', 'Hiragino Sans', 'Hiragino Kaku Gothic ProN', 'Yu Gothic UI', 'Yu Gothic', 'Meiryo', system-ui, sans-serif",
},
}
Само это объявление не загружает веб-шрифт. При выборе самостоятельного размещения проверяйте явный import, сгенерированные CSS и файлы шрифта и результат рендеринга вместе.
Оптимизация изображений: Cloudflare Images + srcset + sizes
Transformations Cloudflare Images
Текущая утилита направляет через преобразование Cloudflare Images /cdn-cgi/image/ только внешние изображения. Root-relative файлы /uploads/... и управляемые изображения asv.acecore.net/uploads/... обслуживаются напрямую.
- Конвертация формата:
format=autoавтоматически выбирает AVIF/WebP в зависимости от поддержки браузера - Настройка качества: текущая утилита использует
quality=75по умолчанию; перед изменением проверяйте фактическое изображение - Изменение размера: параметры
width=/height=задают требуемые размеры
Настройка srcset и sizes
Для внешних изображений с адаптивной доставкой создавайте srcset и задавайте sizes через утилиту.
---
import { generateSrcSet, optimizeImage } from "../utils/image";
const remoteImage =
"https://images.unsplash.com/photo-1515879218367-8466d910aaa4?w=800&h=400&fit=crop";
---
<img
src={optimizeImage(remoteImage, { width: 800, height: 400, quality: 75 })}
srcset={generateSrcSet(remoteImage, [480, 640, 960, 1280, 1600], {
quality: 75,
aspectRatio: 2,
})}
sizes="(max-width: 768px) calc(100vw - 2rem), 800px"
width="800"
height="400"
loading="lazy"
decoding="async"
/>
Точность sizes
Если атрибут sizes оставить как 100vw (полная ширина экрана), браузер будет выбирать изображения большего размера, чем нужно. Укажите в соответствии с реальным макетом, например calc(100vw - 2rem) или (max-width: 768px) 100vw, 50vw.
Улучшение LCP: preload
Предварительно загружайте только изображение, которое действительно является кандидатом LCP. Для адаптивного изображения согласуйте href, imagesrcset и imagesizes макета с самим изображением и задайте fetchpriority="high". Лишние preload могут конкурировать за ресурсы, поэтому подтверждайте выбор измерениями.
<link
rel="preload"
as="image"
href="..."
imagesrcset="..."
imagesizes="(max-width: 768px) calc(100vw - 2rem), 800px"
fetchpriority="high"
/>
Предотвращение CLS (сдвиг макета)
Указывайте точные width и height, соотношение которых совпадает с исходным изображением. Правильные значения позволяют браузеру зарезервировать место, но сами атрибуты не гарантируют устранение CLS. Текущие пути hero и переписывания Markdown также добавляют фиксированные размеры; сверяйте их соотношение с каждым исходником и измеряйте CLS.
Часто упускаемые изображения: аватары (32×32, 48×48, 64×64px) и миниатюры YouTube (480×360px).
Управление загрузкой рекламы и отложенная аналитика
AdSense
Текущая runtime, активная на японских страницах /blog/, регистрирует для каждого рекламного блока IntersectionObserver (rootMargin: 200px) и ResizeObserver, проверяет возможность показа и выполняет первый attemptInit(). Первый вызов не ждёт intersection, поэтому при достаточной ширине рекламный запрос может начаться сразу. Observers используются для повторных попыток при intersection или изменении размера. На переведённых URL с locale-префиксом блоки вставляются, но эта runtime сейчас не загружается.
const retry = () => void attemptInit();
const intersectionObserver = new IntersectionObserver(
(entries) => {
if (entries.some((entry) => entry.isIntersecting)) {
retry();
}
},
{ rootMargin: "200px" },
);
const resizeObserver = new ResizeObserver(retry);
intersectionObserver.observe(container);
resizeObserver.observe(container);
void attemptInit(); // первый вызов не ждёт intersection
attemptInit() проверяет ширину и видимость блока, а атрибуты состояния предотвращают повторные запросы.
GA4
Google Analytics 4 ставится в очередь по pointerdown, keydown, touchstart или scroll. При наличии используется requestIdleCallback, иначе setTimeout; без взаимодействия таймер запускает очередь через 12 секунд на главной странице или через 4 секунды на остальных.
Стратегия кэширования
Ниже приведены текущие настройки файла _headers Cloudflare Pages. Эти значения не являются общей рекомендацией для всех файлов.
# Результат сборки (хэшированные имена файлов)
/_astro/*
Cache-Control: public, max-age=31536000, immutable
# Поисковый индекс
/pagefind/*
Cache-Control: public, max-age=604800, stale-while-revalidate=86400
# HTML
/*
Cache-Control: public, max-age=0, must-revalidate
/_astro/*включает хэши содержимого в именах файлов, что делает годовой неизменяемый кэш безопасным/pagefind/*сейчас получает недельный кэш + однодневный stale-while-revalidate. Поскольку файл с фиксированным именемpagefind-entry.jsonссылается на хэшированные metadata, для предотвращения смешения поколений следует revalidate файлы entry/bootstrap, а долгий кэш оставлять только хэшированным chunks- HTML с
max-age=0, must-revalidateповторно проверяется перед использованием кэшированной копии
Чек-лист оптимизации производительности
- Правильна ли стратегия доставки CSS?: проверьте вывод
autoи измерения в одинаковых условиях - Сравнивалась ли доставка шрифтов?: измеряйте самостоятельное размещение и внешний CDN в одинаковых условиях
- Проверена ли фактическая доставка шрифтов?: запросы сети и Rendered Fonts
- Есть ли srcset + sizes у изображений с адаптивной доставкой?: особенно подготовьте меньшие размеры для мобильных
- Предзагружается ли только реальный кандидат LCP?: согласуйте responsive srcset, sizes и priority
- Точны ли width/height изображений?: сопоставьте пропорции исходника и измерьте CLS
- Подходит ли управление AdSense/GA4?: проверьте первый вызов и повторы AdSense, взаимодействия и резервный таймер GA4
- Настроены ли заголовки кэширования?: применяйте immutable только к хэшированным ресурсам
Заключение
Принцип оптимизации производительности можно выразить фразой «Не отправляйте лишнее». Доставку CSS проверяйте по фактическому выводу; самостоятельное размещение — один из вариантов для шрифтов, если он подходит измерениям и эксплуатации сайта.
Не рассматривайте фиксированную оценку как результат. Повторно измеряйте Core Web Vitals и объём передачи в одинаковых условиях, включая работу рекламы и Analytics.
Серия статей
Эта статья является частью серии «Руководство по улучшению качества сайта на Astro». Отдельные статьи также посвящены SEO, доступности и улучшению UX.
Рабочий процесс оптимизации
Стратегия доставки CSS
Понимание компромиссов между встроенным и внешним CSS.
Оптимизация шрифтов
Проверка загружаемых и реально используемых при рендеринге шрифтов.
Оптимизация изображений
Оптимизация внешних изображений через Cloudflare Images + srcset + sizes.
Управление загрузкой
Первый запуск и повторные попытки AdSense, а также отложенная загрузка GA4.
До и после оптимизации
До оптимизации
- Соединения шрифтов и результат отрисовки не проверяются
- Вывод CSS и кэш не проверяются
- Изображения отдаются фиксированного размера
- Скрипт AdSense загружается немедленно
- Отслеживание фиксированных оценок без записи условий теста
После оптимизации
- Проверены сетевые запросы и реально отрисованные шрифты
- Крупный CSS вынесен во внешний файл, хэшированные ресурсы получают immutable-кэш
- srcset + sizes для доставки изображений, оптимизированных под ширину экрана
- AdSense проверяет блок при первой попытке и повторяет через observers; GA4 загружается после действия или таймера
- PageSpeed Insights повторяется в одинаковых условиях
Часто задаваемые вопросы
Что быстрее — встроенный или внешний CSS?
Зависит от размера CSS, структуры страницы и кэша. Используйте текущую настройку build.inlineStylesheets: 'auto', проверяйте сгенерированные HTML и CSS и измеряйте в одинаковых условиях.
Почему Google Fonts CDN работает медленно?
Внешний домен может добавить DNS-запрос, TCP-соединение и TLS-рукопожатие. Эффект зависит от сети и кэша; проверяйте реальные запросы и отрисованные шрифты.
Что делать, если Cloudflare Images работает медленно?
Производительность Cloudflare Images зависит от источника, трансформации и состояния кэша. Первая трансформация и промахи кэша получают исходное изображение; измеряйте кандидата LCP в одинаковых условиях и используйте responsive preload только при необходимости.
Влияет ли управление загрузкой AdSense на доход?
Эффект зависит от положения рекламы и поведения посетителей. Сравнивайте видимость, рекламные запросы и доход до и после изменения отдельно от показателей производительности.