Table of 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, который раздаёт файлы с ближайших к читателю серверов.
Моё место
Я создал свой укромный и независимый уголок, где могу делать всё, что пожелаю. Нужен ли такой вам — решать не мне. Но я рад, что он мой.