Представьте: ваш медиаблог на Ghost тормозит при 5000 постах, страницы загружаются по 4 секунды, а Google считает LCP 4.2с. Типичная картина для тем, где Handlebars-шаблоны используют вложенные {{#get}} запросы без кэширования и не оптимизированы изображения. Мы решаем эту проблему переписыванием темы под Ghost 5 с кастомными настройками и правильным кэшированием.
В отличие от WordPress, Handlebars в Ghost не выполняет произвольный код, а только вызывает встроенные хелперы. Это плюс для безопасности, но минус для производительности, если не знать тонкостей. Наша команда с многолетним опытом разработки на Ghost (30+ проектов) создает темы, которые проходят gscan без предупреждений и набирают 90+ в Lighthouse. Расскажем, как это работает.
Проблемы, которые решаем
N+1 запросы через {{#get}}. Частая ошибка — получать данные для каждого поста отдельным запросом. Решение — использовать eager loading через параметр include в главном запросе, либо выносить данные в partials с мемоизацией.
Отсутствие адаптивных изображений. Без img_url с size и srcset тема грузит полные оригиналы: 3000px на мобильном. Это резко увеличивает LCP и CLS. Правильный подход — задать image_sizes в package.json и строить srcset для каждого изображения.
Пренебрежение кастомными настройками. Многие разработчики жёстко кодируют стили и функционал, которые редактор мог бы менять через Admin. Используем @custom в конфиге — это даёт контроль редактору без деплоя.
Как Handlebars влияет на производительность Ghost?
Handlebars позволяет создавать безопасные шаблоны без риска RCE, свойственного PHP-движкам. Ghost в версии 5.0+ стабильно поддерживает все хелперы для построения сложных интерфейсов: от пейджинга до Members. По сравнению с Nunjucks, Handlebars — родной язык, который даёт максимум контроля при минимуме возможностей для ошибки. Он в 2 раза быстрее, чем PHP-шаблонизаторы в WordPress, при равной нагрузке, благодаря отсутствию накладных расходов на выполнение кода.
Как мы это делаем: кейс оптимизации медиаблога
Клиент — медиа с 5000+ постов, тема на старом Bootstrap, LCP 4.2с, INP — 300ms. Задачи: сохранить дизайн, улучшить Core Web Vitals, добавить Members для премиум-контента.
Стек: Ghost 5.5, Handlebars, Node.js 18, Nginx, Cloudflare. Полностью переписали структуру шаблонов:
- Заменили вложенные
{{#get}}на один запрос сinclude=tags,authors. - Настроили
image_sizesс четырьмя вариантами и добавилиsizesатрибут. - Внедрили lazy loading для изображений ниже фолда.
- Использовали
@customдля выбора цветовой схемы и типа шапки.
Результат: LCP — 1.8с, CLS — 0.05, INP — 100ms. Сайт прошёл gscan без замечаний.
Почему стоит заказать кастомную тему Ghost?
Готовая тема не учитывает специфику контента и аудитории. Только кастомная разработка позволяет полностью контролировать вёрстку, настройки Members и производительность. Мы гарантируем gscan-валидацию и 30 дней поддержки после сдачи.
Процесс работы
- Аналитика: аудит текущей темы, замер метрик, выявление узких мест.
- Проектирование: создание макета структуры partials, схемы кастомных настроек, прототипирование Members-потоков.
- Реализация: написание всех hbs-шаблонов, стилизация, конфигурация
package.json, интеграция с Ghost API. - Тестирование: валидация gscan, проверка на всех устройствах, профилирование Lighthouse.
- Деплой: загрузка через Admin или CI/CD, настройка кэширования на Nginx и Cloudflare, мониторинг метрик.
Сроки ориентировочно
| Тип темы | Время |
|---|---|
| Минимальная рабочая тема | 2–3 дня |
| Полноценная (index, post, tag, author) | 5–8 дней |
| С Members и кастомными настройками | 8–12 дней |
| С Newsletter-шаблонами | +1–2 дня |
Стоимость рассчитывается индивидуально. Оценим проект за 1 день.
Типичные ошибки в темах Ghost
| Ошибка | Решение |
|---|---|
Отсутствие error.hbs |
Создать обязательный файл |
Использование {{#each}} без post_class |
Всегда применять {{post_class}} |
Игнорирование card_assets |
Включить в package.json |
| Жёсткая разметка вместо адаптивной | Использовать img_url с srcset |
Забытые @custom настройки |
Вынести все параметры в package.json |
Что входит в работу
- Исходный код темы с комментариями
- Документация по кастомным настройкам
- Настройка Members и Newsletter
- Валидация gscan с нулевыми предупреждениями
- Бесплатная поддержка в течение 30 дней после сдачи
Как реализовать Members-ограничения в кастомной теме?
Добавьте в post.hbs блок проверки доступа. Ghost предоставляет контекст {{#if access}} для платного контента и {{#unless @member}} для гостей. Пример:
{{#post}} {{#if access}} <div class="premium-content">{{content}}</div> {{else}} <div class="paywall"> <h3>Эта статья для подписчиков</h3> {{#unless @member}} <a href="#/portal/signup">Подписаться</a> {{/unless}} </div> {{/if}} {{/post}} Для отображения планов используйте {{#get "tiers"}} и выводите название и цену.
Примеры шаблонов
Основные хелперы на примере index.hbs
{{! index.hbs — список постов}} {{#foreach posts}} <article class="post-card {{post_class}}"> {{#if feature_image}} <figure> <img srcset="{{img_url feature_image size="s"}} 300w, {{img_url feature_image size="m"}} 600w, {{img_url feature_image size="l"}} 1000w" sizes="(max-width: 768px) 100vw, 50vw" src="{{img_url feature_image size="m"}}" alt="{{title}} — кастомная тема Ghost"> </figure> {{/if}} <div class="post-card-content"> <header> {{#primary_tag}} <a href="{{url}}" class="post-tag">{{name}}</a> {{/primary_tag}} <h2><a href="{{url}}">{{title}}</a></h2> </header> {{#if excerpt}} <p>{{excerpt words="30"}}</p> {{/if}} <footer> {{#primary_author}} <img src="{{img_url profile_image size="xs"}}" alt="{{name}}"> <a href="{{url}}">{{name}}</a> {{/primary_author}} <time datetime="{{date format="YYYY-MM-DD"}}"> {{date format="DD MMM YYYY"}} </time> {{#if @custom.show_reading_time}} <span>{{reading_time}}</span> {{/if}} </footer> </div> </article> {{/foreach}} {{pagination}} Динамические данные через {{#get}}
{{! Последние посты по тегу}} {{#get "posts" limit="5" filter="tag:javascript" order="published_at desc"}} {{#foreach posts}} <a href="{{url}}">{{title}}</a> {{/foreach}} {{/get}} Обязательные файлы темы
my-theme/ ├── package.json ├── index.hbs ├── post.hbs ├── page.hbs ├── error.hbs ├── tag.hbs (опционально) ├── author.hbs (опционально) ├── partials/ │ ├── header.hbs │ ├── footer.hbs │ └── post-card.hbs └── assets/ ├── css/screen.css └── js/main.js { "name": "my-theme", "description": "Custom Ghost theme", "version": "1.0.0", "engines": { "ghost": ">=5.0.0", "ghost-api": "v5" }, "license": "MIT", "config": { "posts_per_page": 12, "image_sizes": { "xs": { "width": 300 }, "s": { "width": 600 }, "m": { "width": 1200 }, "l": { "width": 2000 } }, "card_assets": true, "custom": { "header_style": { "type": "select", "options": ["Center", "Left", "Right"], "default": "Center" }, "show_reading_time": { "type": "boolean", "default": true } } } } Свяжитесь с нами для оценки проекта. Закажите разработку кастомной темы Ghost — гарантируем качественный код, проходящий gscan без ошибок. Получите консультацию по вашему проекту — мы оценим сложность и сроки за 1 день.







