Что было до нас

Бизнес-клуб TERRA ведёт бесплатный курс «Команда образования» для действующих собственников и руководителей. 12 модулей за два месяца, наставники-практики, очно в Санкт-Петербурге и онлайн. Сайт должен объяснять программу и приводить людей в Telegram-канал.

К нам пришли с черновиком, который собрал неопытный вайб-кодер. Это был один HTML-файл примерно на 140 мегабайт. Все фотографии и видео зашили прямо в код в base64. Файл почти не открывался ни в редакторе, ни в браузере. Мобильное меню не работало. Плееры были нарисованные, часть видео отдавала 404.

Голова документа была пустой. Ни описания, ни Open Graph, ни микроразметки, ни фавиконки. Поисковик видел страницу без имени и без смысла. В палитре жили 36 разных цветов, включая розовый и серый, которых нет в гайдлайне клуба.

Отдельное ограничение шло от юридической формы. Курс некоммерческий, персональные данные организация не собирает. Значит формы заявки на сайте быть не может в принципе.

Разобрали 140 мегабайт скриптом

Вручную такой файл не разобрать. Мы написали скрипт. Он распарсил base64 и вытащил картинки в отдельные файлы. Отдельно достал JSON с данными, который лежал внутри кода: 21 профиль куратора с ролями и достижениями, 16 историй выпускников из точки А в точку Б, отзывы, реальные фотографии людей.

Все изображения перевели в WebP и подогнали под размер показа. Голос основателя вытащили из вертикального видео ВК через ffmpeg и yt-dlp: 81 секунда подкаста на первом экране.

Итог по весу: 224 КБ HTML вместо примерно 140 мегабайт. Сайт целиком, вместе с 68 фотографиями людей, аудио и блогом, весит 2,6 МБ. Приём с распаковкой исходника переиспользуется на любом тяжёлом наследии.

!
Заявок нет, конверсию считать надо

У некоммерческого проекта нет права собирать персональные данные. Форм на сайте нет по решению клиента. Единственное действие посетителя: переход в Telegram. Мы развесили около 30 именованных целей Яндекс.Метрики на каждую кнопку и каждую ссылку. Теперь видно, из какой именно точки человек ушёл в канал: с первого экрана, из шапки, из расписания, из кейсов, из блока наставников, с липкой кнопки или из футера. Это заменяет воронку заявок и показывает, какая секция реально работает.

Собрали страницу заново, интерактив написали руками

Лендинг пересобрали с нуля по брендбуку курса. 10 секций со сквозной нумерацией, чередование тёмных и светлых блоков, тёмно-бирюзовая палитра, Montserrat. Фирменный мотив «лента из точек» из гайдлайна усилили до полноценного интерактива.

Внешних JS-библиотек в проекте ноль. Весь интерактив написан на Canvas и штатных браузерных API.

Параллельно собрали контентный слой: 5 SEO-статей по 1000 до 1200 слов, статья про историю курса с фотоаватарками команды, хаб блога, страница «Миссия и принципы». Сверху лёг SEO и GEO пакет: canonical, Open Graph, JSON-LD (WebSite, EducationalOrganization, NGO, Course с датами потока, FAQPage на 11 вопросов), sitemap, llms.txt и robots.txt, где явно разрешены 14 ИИ-краулеров: GPTBot, ClaudeBot, PerplexityBot, Google-Extended, YandexBot и другие.

  • Сфера из 250 точек на первом экране. Каждая точка это реальный ученик или куратор, наведение раскрывает карточку.
  • Морф точек «хаос в систему» в блоке про боль руководителя.
  • Волна из точек под финальной кнопкой записи.
  • Орбита кураторов, клик-таймлайн на 12 модулей, слайдер отзывов, модалки кейсов и профилей.
  • Две пасхалки для тех, кто до них доберётся.

Скорость при трёх работающих холстах

Анимация обычно съедает баллы производительности. Здесь её оставили и всё равно вытащили скорость в зелёную зону.

PageSpeed 99 на десктопе и 84 на мобильном. LCP 0,8 секунды. CLS 0,007 при постоянно вращающейся сфере.

Механика простая. Первый кадр сферы рисуется сразу как статичное созвездие, и именно он становится главным элементом отрисовки. Вращение включается флагом через 0,8 секунды после полной загрузки. За пределами экрана холсты останавливаются и не крутятся вхолостую. Размеры холста и слайдера отзывов считаются один раз и кешируются, пересчёт идёт только при изменении окна.

Грабли

Кейс без единой сложности читается как реклама. Вот что реально ломалось по дороге.

  • Мобильный PageSpeed отдавал ошибку NO_LCP. Lighthouse не мог поймать момент отрисовки: сфера крутилась непрерывно, страница никогда не затихала. Помог отложенный старт вращения. Балл поднялся с ошибки до 84.
  • CLS был 0,174. Montserrat грузится асинхронно, и при подмене шрифта вся страница дёргалась. Сделали свой @font-face-фолбэк на базе локального Arial с подогнанными метриками: size-adjust 112,71%, ascent-override 85,79%, descent-override 22,25%. Сдвиг упал до 0,007.
  • Глобальное правило overflow-x:clip убрало тёмную полосу справа на мобильном и заодно сломало прилипающую колонку расписания на десктопе. Ограничили медиазапросом до 880 px.
  • Четыре аватарки при обрезке в квадрат кадрировались по центру картинки и отрезали лица. Перекропили по лицу скриптом.
  • Переменную в JavaScript нельзя называть top. Это window.top, страница молча ломается. Записали в правила проекта.
  • Пуш в репозиторий не равен выкатке. Боевой домен отдаёт сервер на стороне клиента. После пуша сайт 40 минут не менялся, и сначала казалось, что мы что-то сломали. Автозабора на репозитории просто не было. Позже на стороне клиента подняли автовыкатку, теперь правка доходит до сайта примерно за полминуты.
  • Лендинг лежал в нашей общей рабочей папке, и параллельно его правил другой процесс. Массовая автозамена по всем HTML-файлам переписала биографию спикера курса. Откатили через git. После этого файлы в коммит добавляем поимённо и проверяем индекс глазами.
  • Мелочи, которые видит только заказчик. Надпись «С 0 ₽» читалась как «СОР». Точка-разделитель повисала одна на новой строке при переносе. Такие вещи автотесты не ловят никогда.

Что осталось у клиента после сдачи

Код запушен в репозиторий заказчика. Сайт переехал на боевой домен ko.business, noindex снят, страница открыта для индексации и верифицирована в Яндекс.Вебмастере. Сервером распоряжается клиент, доступа туда у нас нет и мы туда не лезем.

Сайт после сдачи ведёт сотрудница клуба, она не программист. Вместо инструкции в Word мы положили в корень репозитория файл CLAUDE.md, который её Claude Code читает автоматически. Внутри 5 разрешённых задач с точными рецептами: добавить кейс, куратора, звезду на сферу, отзыв, статью. Там же команда самопроверки кода перед пушем и жёсткий раздел про то, что трогать нельзя. Всё за пределами этого списка идёт к разработчику.

Хронология без прикрас. Старт 24 июня, приёмка 3 июля: 9 дней. Дальше переезд на домен, пачка примерно из 38 правок по мобильной и десктопной версиям, перф-фикс мобильного балла и передача поддержки. Всего 243 коммита за 12 рабочих дней с правками.

Частые вопросы

Сколько времени занимает разработка лендинга для курса?

Лендинг курса «Команда образования» сделали за 9 дней: старт 24 июня, приёмка 3 июля. В эти дни вошли разбор исходника, сборка страницы с нуля, 5 SEO-статей и блог. После приёмки был переезд на домен ko.business и примерно 38 правок по мобильной и десктопной версиям. Всего 243 коммита за 12 рабочих дней.

Сайт весит слишком много и долго открывается: что делать?

Такой файл руками не разобрать, нужен скрипт. У TERRA исходник был одним HTML на 140 МБ: фотографии и видео зашили прямо в код в base64. Мы распарсили base64, вытащили изображения в отдельные файлы, перевели в WebP и подогнали под размер показа. Страница стала весить 224 КБ, весь сайт с 68 фотографиями, аудио и блогом занимает 2,6 МБ.

Можно ли обновлять сайт самому, без программиста?

Да, если заложить это в проект заранее. Сайт после сдачи ведёт сотрудница клуба, она не программист. В корень репозитория мы положили файл CLAUDE.md, который её Claude Code читает автоматически: 5 разрешённых задач с точными рецептами, команда самопроверки кода перед пушем и раздел про то, что трогать нельзя. Всё за пределами этого списка идёт к разработчику.

Как считать конверсию сайта, если на нём нет формы заявки?

Курс некоммерческий, персональные данные организация не собирает, поэтому форм на сайте нет по решению клиента. Единственное действие посетителя: переход в Telegram. Мы развесили около 30 именованных целей Яндекс.Метрики на каждую кнопку и каждую ссылку. Теперь видно, из какой точки человек ушёл в канал: с первого экрана, из шапки, из расписания, из кейсов, из блока наставников, с липкой кнопки или из футера.

Можно ли сделать сайт с анимацией и не потерять скорость загрузки?

Можно. На лендинге TERRA работают три холста Canvas, включая сферу из 250 точек на первом экране, внешних JS-библиотек в проекте ноль. PageSpeed при этом 99 на десктопе и 84 на мобильном, LCP 0,8 секунды, CLS 0,007. Помогли три приёма: первый кадр сферы рисуется сразу статичным созвездием, вращение включается через 0,8 секунды после полной загрузки, за пределами экрана холсты останавливаются.