Table of contents
Contents

Введение

Каждый раз посещая HackerNews, я тратил часы на просмотр сайтов разработчиков. Иногда они максимально простенькие: обычная страница, будто цветной лист бумаги, с несколькими постами. А иногда полноценный сайт с кучей разделов, фич и сложной навигацией. После пары таких вечеров я полез в Гугл со следующим вопросом: «Какой фреймворк использовать для блога?», где и познакомился с SSG (Static Site Generator) и с Hugo — одним из самых популярных генераторов.

Зачем мне веб-сайт

Изначально целью было создание простенького сайта-визитки на базе SSG, чтобы люди всегда могли найти мои контакты, ведь я и мои друзья неоднократно теряли связь после того, как удаляли свои аккаунты. Казалось бы, решение простое: не удалять аккаунты и использовать одинаковые юзернеймы. Но обстоятельства бывают разными.

Также у меня есть друзья из России, но с новой политикой закрытого интернета и объявлениями об ограничении доступа к мессенджерам и соцсетям я начал переживать, что потеряю и их.

Со временем идея переросла во что-то большее. Мне захотелось создать уголок, где я смогу публиковать свои мысли, заметки, проекты, наблюдения и просто сохранять часть своей жизни в открытом виде. Поэтому этот сайт — моё одностороннее социальное пространство.

Социальные сети

Но почему не социальные сети? Честно, у меня к ним аллергия. Не знаю почему, но я просто не могу воспринимать их как что-то «своё». Да и не хочу тратить на это ни внимание, ни время.

Сейчас существует огромное количество платформ с разной аудиторией, из-за чего появляется другая проблема — нет единого места, куда человек может просто зайти, открыть страницу и спокойно посмотреть контент без всплывающих уведомлений о куки, рекламы, просьб зарегистрироваться, установить приложение или подписаться, скрывающих сам контент.

Особенно в свете грядущей политики верификации возраста. Несколько стран уже ввели обязательную верификацию в социальных сетях: Австралия запретила детям до 16 лет пользоваться платформами, следом Бразилия, Индонезия, Малайзия. Великобритания и ряд штатов США движутся в том же направлении. Платформы обязаны соблюдать эти требования и вместе с ними усиливается сбор личных данных пользователей. Личный сайт под эти регуляции не попадает: он не платформа, не собирает данные и не требует от читателя ничего, кроме браузера.

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

Вторая проблема — рекомендации и сама культура потребления контента. Мне не интересно ежедневно следить за чужой жизнью или бесконечно листать предлагаемую алгоритмами ленту. Возможно, дело в том, что многие люди пытаются показать себя лучше, чем они есть: самые красивые фотографии, натянутые улыбки, идеальные моменты жизни. Но меня это никогда не цепляло.

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

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

Односторонность

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

Аудитория при этом никуда не исчезает. Напротив, именно читатель определяет выбор темы, язык и подачу. Разница в том, что автор принимает эти решения заранее, без оглядки на реакцию в реальном времени. Монолог требует большей подготовки, чем диалог: нельзя уточнить, нельзя переспросить, нужно сказать всё правильно с первого раза.

Выделив слово «можете», я подчеркнул возможность, а не обязанность. Вы всегда вольны высказать своё мнение или поправить меня, чему я буду искренне рад. Но для этого лучше подойдут мессенджеры: все контакты на странице связи.

Комментарии

Отдельно о комментариях под постами. Существует немало готовых решений: Giscus, Utterances, Cusdis, Disqus. Но я отказался от них по двум причинам: дизайн и уместность.

Причины взаимосвязаны. При небольшой аудитории комментарии оставит ничтожная доля читателей. Это известное правило 1%. Пустой раздел комментариев выглядит хуже, чем его отсутствие: создаёт ощущение заброшенности и отпугивает новых читателей. При этом не все комментарии несут смысл, а с ростом аудитории неизбежно возникает потребность в модерации.

Я разделяю позицию Sonia Simone: комментарии уместнее в других местах: в блогах других людей, в мессенджерах или в социальных сетях (как бы парадоксально это ни звучало). Первое предполагает тот же монолог, о котором я писал выше. Второе подходит для живой дискуссии, где проще прийти к консенсусу. Третье хотя бы пропиарит.

Дизайн

Изначально, когда я хотел сделать сайт-визитку, мне хотелось чего-то изысканного — уникального дизайна, запоминающегося визуально. Показать идентичность через эстетику. Для этого я взял образ балерины в технике halftone, танцующей на кругах. Но вскоре я понял, что абстрактные и сумбурные конструкции — далеко не самое главное на сайте: читателю важен контент, то есть текст. Поэтому я принялся разрабатывать максимально лаконичный дизайн, где читателю не придётся отвлекаться на анимации или непонятную раскладку. Всё должно быть нативным.

Раскладка

Вниманием пользователя можно управлять по-разному: главное, чтобы объекты либо следовали определённой раскладке, либо намеренно выбивались из неё. Я выбрал другой способ — не думать. Чтобы добиться максимально нативного дизайна, мне буквально пришлось отключить голову и сфокусироваться на читабельности, поэтому на сайте всё идёт сверху вниз, как в книге.

5 цветов более чем достаточно

Цвет — это инструмент. Он отвечает на один вопрос: что важно, а что нет. Как только цвет начинает решать другую задачу, он превращается в шум.

Мне хватило пяти:

  • Фон — думаю, тут всё понятно
  • Текст — основное содержание, ради которого человек пришёл
  • Яркий — отвечает за структуру: заголовки и опорные точки страницы
  • Мрачный — всё, что тише основного текста: даты, подписи, навигация, описания
  • Акцент — цепляет взгляд на деталях, которые стоит подметить: ссылки, важные слова, элементы дизайна, которые нужно выделить

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

Почему я не хочу делать этот сайт многоязычным

Сейчас я нахожусь в Бельгии, где три национальных языка. В каждом регионе вывески в основном на одном: французском, немецком или нидерландском. Всё зависит от местного населения. Нужно ли мне знать все три, чтобы свободно путешествовать по этой замечательной стране? Нет! Я могу воспользоваться вспомогательными средствами, спросить людей или заранее спланировать маршрут.

Я не хочу переводить каждую страницу на все языки, которые знаю или изучаю, поэтому предпочитаю международный — английский. Почему?

  • Во-первых, сложность поддержки: изменил одну страницу — будь любезен отредактировать и остальные версии. Я хочу, чтобы перевод оставался приятным занятием, а не обязанностью, иначе его рано или поздно захочется свалить на ИИ;
  • во-вторых, в браузеры уже встроен достаточно хороший переводчик.

Поэтому я сосредоточусь на переводе блогов как на интересном хобби и практике.

Технокухня

Сам сайт появился из интереса к SSG, поэтому я отправился искать программу, которая будет лёгкой, быстрой и с возможностью вести блог на Markdown.

Вот список генераторов, которые я просмотрел:

  • Hugo — один из самых популярных: быстрый, удобный, есть всё, что нужно, и даже больше
  • Zola — хороший аналог Hugo
  • Zine — минималистичный, написан на Zig
  • Astro — громоздкий фреймворк с SPA и подходом server-first

Также можете поискать тут.

Я остановился на Hugo из-за его зрелости и популярности. Честно, мне больше нечего добавить, кроме одного: я не стал брать готовую тему или шаблон (хотя другим советую, это экономит кучу времени). В остальном я очень доволен своим выбором.

Загружаем только часть страницы

Во время разработки всплыла ещё одна причина — белая вспышка при переходах по внутренним ссылкам. Каждый раз браузер загружает и рендерит страницу заново, и хотя уходит на это лишь пара десятков миллисекунд, их хватает, чтобы глаз поймал неприятный блик и первое впечатление было испорчено. Я подумал: зачем заново тянуть и отрисовывать CSS и HTML, если можно обновлять только body и header? Сначала мне показалось, что получается что-то вроде SPA.

Но это не SPA: страницы остаются настоящими, просто подменяется их часть. А у самого приёма, как я узнал позже, есть имя — PJAX: подменять часть страницы вместо полной перезагрузки. Велосипед оказался изобретён до меня, но собрать его с нуля всё равно было приятнее, хотя бы чтобы не тащить целую библиотеку ради одной идеи: весь роутер уместился меньше чем в две сотни строк.

Ещё я добавил предзагрузку страницы при наведении, с задержкой в 150 мс. Расчёт простой: пока курсор замирает на ссылке, до самого клика проходит больше ~200 мс, так что 150 мс дают странице фору и она успевает загрузиться заранее. А заодно эта задержка отсекает случайные наведения: когда курсор просто скользит по ссылкам, ничего лишнего не грузится. В итоге к моменту клика страница уже загружена и готова к подмене. Переход ощущается моментальным.

И всё это — лишь надстройка. Отключите JavaScript, и подмена и предзагрузка просто исчезнут, а сайт останется обычным набором статических страниц: каждая ссылка настоящая, каждая страница — реальный HTML-файл. Ломаться нечему.

Встраивать или выносить

CSS я мог бы вынести в отдельный файл, чтобы он не ехал с каждой страницей, а кэшировался один раз. Но это всего 5,7 КБ, а внешний файл добавил бы лишний round-trip к первой отрисовке. Ради такой экономии терять моментальный первый экран не стоило. К тому же даже с инлайн-CSS страница в сжатом виде укладывается в правило 14 КБ, то есть первый экран приезжает за один-единственный round-trip.

С иконками всё наоборот. Их я в страницу не встраиваю, а складываю в один внешний SVG-спрайт: каждая иконка становится <symbol>, на странице от неё остаётся лишь короткая ссылка <use href="…">. Спрайт грузится один раз, кэшируется и работает сразу на все иконки. Встрой я их в HTML, одна и та же иконка повторялась бы при каждом появлении и ехала бы заново с каждой страницей. Почему тогда CSS встроен, а иконки вынесены? CSS нужен для отрисовки страницы: без него её попросту нечем нарисовать, и ждать ради него лишний round-trip не хочется. Иконки же подгружаются динамически и ничего не блокируют, так что их спокойно можно вынести в отдельный кэшируемый файл. С JavaScript та же история.

Хостинг для статических сайтов

Пару слов о хостинге. Вариантов куча, и многие бесплатны или с очень щедрым бесплатным планом. Чтобы ускорить и без того быстрый сайт, я бы советовал Vercel или Cloudflare Pages: у них есть CDN, который раздаёт файлы с ближайших к читателю серверов.

Моё место

Я создал свой укромный и независимый уголок, где могу делать всё, что пожелаю. Нужен ли такой вам — решать не мне. Но я рад, что он мой.