İçeriğe geç
Все услуги

Веб-разработка

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

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

Наше определение веб-разработки

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

Шесть решений внутри веб-проекта

Шесть заголовков ниже охватывают решения, которые дороже всего отменять. Первые два задают скорость сайта: когда генерируется страница и где измеряется производительность. Третий отвечает на вопрос, останется ли код безопасным для изменений со временем. Четвёртый и пятый касаются числа языков публикации и того, кому разрешено трогать содержимое. Шестой включается только тогда, когда есть старый сайт, который надо перенести.

Стратегия рендеринга: когда генерируется страница

Вариантов три. При статической генерации страница собирается во время сборки, и если набор адресов известен, это самый быстрый и дешёвый путь. При серверном рендеринге страница собирается на каждый запрос, чего требует персональное или постоянно меняющееся содержимое. При инкрементальной регенерации страница остаётся статической и обновляется тогда, когда меняется содержимое. Важная деталь относится к третьему варианту: обновление следует привязывать к событию, а не к таймеру. На сайте, который вы читаете, каждое сохранение в панели управления сбрасывает только соответствующий тег кэша, поэтому пересборка не нужна. Архив сайта bebekistiyorum.com, состоящий из 66 медицинских статей, сотен видеостраниц и профилей специалистов, публикуется на платформе с MongoDB, которая рендерится на сервере средствами Next.js App Router и React Server Components.

Core Web Vitals и измерение по реальным пользователям

Лабораторная оценка и полевые данные не одно и то же: Lighthouse измеряет одно устройство, один профиль соединения и пустой кэш, тогда как данные, которыми пользуется Google, приходят из браузеров реальных посетителей. Поэтому мы сдаём не зелёную оценку, а три полевые метрики: время отрисовки самого крупного элемента, задержку между действием пользователя и следующей отрисовкой, накопленное смещение макета. Круг вещей, которые их ломают, узок: изображения без указанных размеров, поздно загружаемые шрифты, слишком большой пакет JavaScript и код, который измеряет элемент сразу после монтирования и тут же меняет стиль. Последнее заставляет браузер выполнить синхронный пересчёт макета, поэтому на страницах, которые видит посетитель, мы взяли за правило брать результат измерения из самого колбэка ResizeObserver. Мобильная производительность входила в число известных проблем прежнего сайта bebekistiyorum.com, а на новой платформе выполнена работа над производительностью с опорой на Core Web Vitals.

Типобезопасность и сопровождаемость на TypeScript

Ценность TypeScript проявляется не тогда, когда код пишут, а тогда, когда его меняют. Переименуйте поле, и компилятор покажет каждое место, которое его касается; без типов ту же работу делают текстовым поиском и надеждой. У этой гарантии три условия. Строгий режим: неявный any, то есть тип, который TypeScript присваивает значению сам, если его тип нигде явно не указан, должен быть выключен, иначе система типов превращается в украшение. Граница данных: всё, что приходит из базы, из внешнего сервиса или из формы, проверяется схемой во время выполнения, а не утверждением типа, потому что типы стираются при сборке и ни одно описание интерфейса не остановит ответ неверной формы. Третье условие состоит в том, что проверка типов должна выполняться в конвейере, а не держаться на человеческой дисциплине. Долгосрочный эффект архитектурных решений мы разобрали в статье об архитектуре программного обеспечения.

Многоязычная архитектура и RTL

Многоязычность представляет собой задачу не про файл перевода, а про адреса и вёрстку. У каждого языка должен быть свой адрес, связь между версиями объявляется поисковым системам через hreflang, а сами сегменты пути должны поддаваться переводу. На сайте, который вы читаете, локализуется и сам адрес: одна и та же страница живёт под hizmetlerimiz по-турецки, под услуги по-русски и под خدماتنا по-арабски. Языки с письмом справа налево добавляют второй слой. Арабский переворачивает не только направление текста: зеркалятся отступы, направление иконок и выравнивание форм, и если строить это на «слева» и «справа» вместо логических свойств CSS, каждый компонент придётся писать дважды. Сайт bebekistiyorum.com выходит на турецком, английском, русском и арабском, причём для арабского все компоненты спроектированы работающими справа налево. Самые частые ошибки этой части мы собрали в заметках о локализации.

Управление контентом и независимость редактора

Настоящим владельцем сайта является тот, кто может менять его содержимое. Если каждая правка текста требует разработчика, сайт со временем перестаёт обновляться. Поэтому модель контента мы строим на уровне полей, а не страниц: заголовок, аннотация, тело, медиа и метаданные описываются отдельно, и редактор публикует, не ломая вёрстку. HTML, приходящий из визуального редактора, очищается на сервере по списку разрешённых тегов, потому что очистка в браузере очисткой не считается. Для bebekistiyorum.com была разработана собственная админ-панель с визуальным редактором Tiptap и массовым импортом контента. Разница со старым сайтом видна отчётливее всего именно здесь: раньше каждое обновление содержимого требовало технической поддержки, а теперь контент-редакция публикует без помощи разработчика и не платит за лицензию CMS.

Миграция и сохранение ценности адресов

При обновлении существующего сайта самая дорогая ошибка состоит в тихой смене структуры адресов. Накопленная за годы поисковая ценность держится на адресе, а не на странице, и вместе с адресом исчезает она сама. Порядок работ выглядит так: все адреса старого сайта выгружаются из карты сайта, серверных журналов и поисковой консоли, каждый сопоставляется с местом в новой информационной архитектуре, затем это сопоставление выкладывается постоянными редиректами. Массовая переадресация на главную сопоставлением не является и ценности не переносит. На bebekistiyorum.com более 1200 адресов старого сайта на ASP.NET были сопоставлены с новой информационной архитектурой и сохранены слоем 301-редиректов на основе базы данных. Карту мы держим в базе: пробелы, которые обнаруживаются после запуска, закрываются без ожидания новой выкладки. Наблюдение за индексацией и позициями после переезда относится к услуге SEO.

Куда мы смотрим в первую очередь в унаследованных проектах

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

Как ставится бюджет производительности

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

Вопрос о том, кто будет вести сайт

Мы задаём его до начала дизайна, потому что ответ меняет архитектуру: кто, как часто и с какими правами будет трогать сайт? Ответов обычно три. Для сайта, содержимое которого меняется несколько раз в год, отдельная панель управления оказывается расходом без отдачи: текст может жить в коде. Для небольшой команды, которая вносит контент несколько раз в неделю, правильным ответом становится собственная панель: поля описываются вокруг реальной работы этой команды, и обучение занимает мало времени. Там же, где есть десятки редакторов, шаги согласования и переводческий процесс, разумнее купить зрелую headless CMS, то есть систему управления контентом без собственного пользовательского интерфейса, которая отдаёт контент через API, и мы прямо об этом говорим. Каким бы ни был ответ, три вещи входят в поставку: разделение ролей, предпросмотр до публикации и письменная записка о работе с панелью. На bebekistiyorum.com ответом стала собственная панель, а проверкой послужило простое условие: контент-редакция публикует без помощи разработчика.

Пять пунктов в пакете передачи

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

Всё это в одном проекте

Большую часть решений с этой страницы можно увидеть в одном проекте: сайт bebekistiyorum.com центра ЭКО Eurofertil перешёл со старого стека ASP.NET WebForms на четырёхъязычную платформу Next.js. Первые пять пунктов ниже описаны на странице самого проекта, шестой представляет собой сайт, который вы читаете.

  • Рендеринг и данные: платформа с MongoDB, которая рендерится на сервере средствами Next.js App Router и React Server Components.
  • Миграция: более 1200 адресов старого сайта сопоставлены с новой информационной архитектурой и сохранены слоем 301-редиректов на основе базы данных.
  • Многоязычность: турецкий, английский, русский и арабский; для арабского все компоненты спроектированы справа налево, языковые версии объявлены через hreflang.
  • Управление контентом: собственная панель с редактором Tiptap и массовым импортом; контент-редакция ведёт весь сайт без лицензии CMS.
  • Техническое SEO: динамические метаданные по страницам, автоматическая карта сайта, структурированные данные schema.org и работа над Core Web Vitals.
  • detartech.com: та же архитектура: Next.js App Router, четыре языка, локализованные сегменты пути и вёрстка справа налево на арабском.

Преимущества

  • Стратегия рендеринга выбирается по типу страницы, обновление привязано к событию
  • Core Web Vitals отслеживаются по полевым данным, а не по лабораторной оценке
  • Строгий режим TypeScript и проверка схемой на границе данных
  • Локализованная структура адресов и вёрстка справа налево для арабского
  • Панель, из которой контент-редакция публикует без разработчика
  • При переезде адреса сопоставляются один к одному и держатся 301-редиректами

Часто задаваемые вопросы

Сколько длится веб-проект и как он оценивается?

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

Остаются ли у нас код, инфраструктура и содержимое, есть ли лицензионные платежи?

Репозиторий лежит в вашей учётной записи со всей историей версий, сервер и база данных разворачиваются на записях, открытых на ваше имя, содержимое остаётся выгружаемым из базы. Если нужен закрытый компонент с лицензионной платой, мы пишем об этом до договора. На bebekistiyorum.com контент-редакция ведёт весь сайт без какой-либо лицензии CMS.

Потеряем ли мы позиции в поиске, если перенесём существующий сайт?

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

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

Да, и мы считаем это проверкой качества поставки. Панель описывается вокруг полей, которые ваша команда действительно заполняет; вывод редактора очищается на сервере, разделение ролей и предпросмотр идут по умолчанию, а письменная записка о работе с панелью входит в передачу. Разработчик нужен для нового типа страниц или нового поля, но не для правки текста.

Нужна ли заказная разработка каждому сайту?

Не всегда, и мы говорим об этом прямо. Для сайта-визитки на десять страниц, содержимое которого меняется несколько раз в год, обычно хватает готовой темы, и работа с нами себя не окупит. То же верно на другом полюсе: там, где есть десятки редакторов, шаги согласования и переводческий процесс, покупка зрелой headless CMS выигрывает у панели, написанной с нуля.

Next.js и TypeScript не избыточны ли, не дешевле ли готовая платформа?

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

Как мы предоставляем эту услугу

Обсудим ваш проект

Как применить эту услугу к вашему проекту?

Заполните форму заявки для бесплатной 30-минутной консультации.