company_banner

Новый сайт для популярного медиа за 2 месяца

    Давным-давно в далекой-далекой галактике появился проект The Bell, построенный на WordPress. Постепенно проект рос и развивался, добавлялись всевозможные галочки и тоглеры, накручивались фичи. Технический долг копился и тащил The Bell на тёмную сторону, а новые хотелки уже выходили за рамки возможностей CMS и превращали проект в колесо с костыликами вместо спиц. И тут редакция задумала обновить сайт и сделать редизайн новостной ленты.

    «Что в этом сложного?» — видимо, подумали люди, не очень знакомые с техническими тонкостями, и обратились к нам за разработкой. Для нас же это поначалу напоминало анекдот: есть статичный макет, который совершенно неизвестно как должен меняться в зависимости от разных условий, и заказчик, который хочет увидеть новый сайт в работе меньше, чем через два месяца.

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



    Исходные данные


    The Bell — деловое медиа, которое начиналось с ежедневной e-mail рассылки. Сейчас это ещё и основной новостной сайт, и несколько спецпроектов с отдельными площадками.

    Как вы поняли, сайт The Bell изначально был сделан на WordPress, что для стартапа вполне логично. WordPress — универсальная и простая CMS. И этим, по большому счёту, всё сказано. Она хороша для прототипирования и того, чтобы быстро стартануть; там можно реализовать всё, ну или почти всё. Но когда за несколько месяцев трафик вырос со 100 тысяч пользователей до миллиона, требовались большие усилия и кэши, чтобы WP и виртуалка, на которой он работал, не умирали. Поэтому сначала переехали на выделенный сервер и только спустя какое-то время занялись WordPress.

    В подросшем продукте большее значение имеет то, сколько усилий потребуется для реализации стратегии развития и точно ли получится так же хорошо, как если делать с нуля под конкретную задачу. В случае «старого» The Bell каждая новая доработка делала реализацию всё более запутанной, громоздкой и непригодной для поддержки и рефакторинга.

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

    Для кастомной реализации мы выбрали связку Angular + Laravel, потому что оба этих фреймворка уже так или иначе были задействованы в отдельных модулях проекта. Для рассылок уже использовался модуль на Laravel, который отправлял письма через Mailchimp и собирал аналитику в нашей админке. И подпроект Bell.Club был ещё раньше сделан без участия WordPress на Laravel.

    Что нужно сделать


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


    Для иллюстрации поместил в ленту статьи из нашего блога. The Bell пишут на острые социальные и политические темы, которые не хочется обсуждать в рамках данного поста.

    А дальше мы вместе выясняли, что должно происходить со всеми остальными статьями: бесконечная ли будет лента, как она должна обновляться и куда будут попадать новые материалы, а куда уходить более старые.

    Отдельно замечу, что заказчики — классные профессионалы в медиа, но среди них нет ни одного технического специалиста. Переложить задачу из картинок и разговоров в задачи для разработки нужно было нам самим. Работали в чистом виде по Agile и по ходу дела выясняли, что и зачем хочет клиент и что ему можно предложить по этому поводу.


    На такого рода черновики мы ориентировались, проектируя админку.

    Сроки. Ожидание vs реальность


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

    Чтобы перевезти весь проект на новый стек, нужно было переписать всё, что связано с WordPress, а именно: фронтенд и бэкенд, админку и кучу всяких мелочей типа rss, метаданных, seo, которые в WordPress были реализованы плагинами. С учётом имеющихся ресурсов (в проекте было занято всего два разработчика) это заняло бы полгода. А заказчику новый дизайн нужен был к 1 апреля — на тот момент оставалось уже меньше двух месяцев.

    Пришлось искать компромисс.

    За что хвататься, чтобы всё успеть


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

    Бэкенд. Админка для размещения постов


    У The Bell большая редакция, неудобное решение замедлит работу всего медиа. В первом собранном прототипе позицию фиксированного поста надо было просто указывать координатами вида: «Помести этот пост в третью строку на вторую позицию». Конечно, это был нежизнеспособный вариант, потому что редактору по сути требовалось самому помнить, как выглядит вся страница и что еще на ней зафиксировано.

    Мы быстро поняли, что лучшим решением будет визуальный конструктор страницы. Такой, чтобы, примерно как на скриншоте выше, располагать статьи и виджеты, сразу видеть возможные варианты и результат. По сути, в конструкторе можно задать раскладку карточек на странице, которую мы называем темой (layout_theme). Тема — основная сущность, вместе со всеми зависимыми описывающая внешний вид новостной ленты.

    Так как тема — это объект, к которому много обращений, её структура должна быть достаточно лаконичной, но при этом читаемой и понятной. У нас это набор горизонтальных объектов: линий или вложенных тем. Линия как объект определяет, сколько и какого размера блоков виджетов стоит в… в линии :) Например:

    • 3 по 33,3%


    • 33,3% + 66,6%


    • 50%+50%


    И прочие сочетания, кратные 33% и 25%.

    Сами блоки виджетов бывают нескольких видов и описываются через набор полей:

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

    Поле имеет тип и указание на обязательность — * в списке выше. Также есть карточки, не связанные с постами, например, блоки подписки или сторонние посты.

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

    Информация о закрепленных элементах хранится в json и выглядит примерно так.

    {
        "route_id": 1,
        "theme_id": 1,
    /* route_id - id пути в адресной строке и theme_id — id тем.
    Они необходимы, потому что к одной теме может быть привязано несколько наборов закрепленных элементов. */
    /* То есть например по пути / и по пути /tag/ тема одна и та же, но посты закреплены по-разному */
    /* Список закрепленных элементов */
        "items": [
            {
    /* Имя модели закрепленного элемента (тут может быть пост, форма подписки, рекламный блок или что угодно) */
                "fixed_model_name": "Post",
    /* ID айтема модели */
                "fixed_model_id": 1,
    /* ID линии. */
                "line_id": 1,
    /* Позиция в линии */
                "position": 1,
    /* Индикатор, повторяется ли это закрепление при повторных отображениях этой линии в  бесконечной ленте */
                "repeatable":0
            },
            ...
        ]
    }

    В визуальном редакторе линии можно легко передвигать вверх-вниз и таким образом создавать новую тему.

    Вот так это выглядит в админке на Angular:



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

    Преимущества нового бэкенда:

    • Новая админка позволяет допускать меньше редакционных ошибок, связанных с человеческим фактором, потому что расположение постов удобно проверять в визуальном редакторе.
    • Его быстрее дорабатывать и внедрять новые фичи, потому что мы хорошо знаем систему, которую сами и написали.
    • Новый бэкенд стабильнее работает, то есть мы больше не теряем пользователей на простоях.
    • Запросы теперь проще и работают быстрее, потому что идут к нашему серверу на Laravel и в специализированную БД, а не в универсальный WP. Скорость работы сайта для посетителей портала стала выше.

    Публичная часть


    Сделана на Angular и максимально переиспользует код из админки. На всех страницах с постами, кроме страниц типа «Команда», сделали бесконечную ленту, которая формируется за счёт повторения темы. Закреплённые посты показываются при прокрутке снова, если в админке для них задан параметр «repeatable».

    Если из ленты перейти на детальную страницу поста, то там тоже будет тема, которая настраивается так же, как и все остальные темы, и также бесконечная. Например, сейчас первую линию занимает сам пост, дальше блок три по 33,3% и снова статья. И при этом, в зависимости от того, какая статья из бесконечной ленты сейчас на экране, меняется url. Кроме того, в текст поста, который приходит с бэкенда в виде HTML, можно встроить Angular-компоненты, например, форму подписки на рассылку.

    Все темы на сайте The Bell свёрстаны на гридах.

    Релиз и результаты переезда


    За два месяца у нас, конечно, получилось то ещё чудовище Франкенштейна. Мы написали API для переезда на новый стек, но посты пока что создаются по-прежнему в админке на WP, синхронизируются с базой данных, и тогда уже в новой админке можно управлять их положением на странице.

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

    Даже такой монстрик позволил, во-первых, за короткий срок решить задачу бизнеса, а во-вторых, существенно снизить нагрузку как на БД, так и на CPU. Если до переезда сайт мог упасть из-за крайне медленных запросов в таблицы WP, где все метаданнные (например, категории, тэги, картинки и т.д.) находятся в одной и той же таблице, а также в одной таблице хранятся посты и десятки (!) ревизий этих постов. То после переезда проблем с базой не было ни разу.

    To be continued


    Новый дизайн мы выкатили примерно полгода назад и теперь в режиме небольших доработок постепенно переносим все инструменты на новый движок и дописываем админку. Как это обычно бывает, продуктовые фичи отнимают почти всё время и они на виду, а внутренние доработки не всегда видны со стороны заказчика, но нужны для дальнейшей миграции и развития. Поэтому мы стараемся разгребать техдолг. В ближайших планах внедрить ssr и фиды на нашем бэкенде (сейчас это все ещё на стороне WP) и перевезти редактирование постов на новый редактор. А также довести до продуктового использования заложенную механику вложенных тем.

    Послесловие


    Закончить статью хочу нетехническими выводами о пользе гибкого подхода, в которой мы еще раз убедились на примере этого проекта:

    • Если ваша самая оптимистичная оценка срока разработки в 3-5 больше, чем то, что нужно бизнесу, то это НЕ значит, что ничего не получится. Необходимо искать альтернативные варианты.
    • Большой переезд — это не обязательно два года работы. Можно реализовать самое необходимое в новых модулях (или сервисах) на новом стеке и постепенно переносить старое и допиливать фичи. Это, может быть, не самое удобное и простое решение для разработчиков, но оно рабочее, способствует гибкой разработке и не заставляет пользователя резко отказываться от привычных инструментов.
    • В условиях сжатых сроков большое значение имеет организация работы. Такие, казалось бы, очевидные моменты, как налаженная коммуникация, быстрое решение блокеров и слаженная работа кросс-функциональной команды могут быть решающими.
    • Мы пишем код не для себя, а для того чтобы он решал бизнес-задачи. Лучше потратить время и разобраться в нуждах пользователя (для нас это не только посетители сайта The Bell, но и редакция медиа), чем написать идеальный код, которые делает что-то не то.
    • Взять и сделать сразу всё идеально в реальном мире, к сожалению, невозможно. Вам всегда будет хотеться что-то переделать и улучшить. И это хорошо, потому что помогает не стоять на месте.

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

    Комментарии 23

      +6

      Жалко что о технических деталях реализации не сказано почти ни слова, а очень хотелось бы.


      Очень большой Time to Interactive — на телефоне, после показа шапки, очень долго ничего не проихсодит. Я вижу секунд 5-10 просто шапку с логотипом и просто чистый лист. По ощущению, идет компиляция страницы для первоначального отображения. Причем нагрузка на трафик не сильная, а вот нагрузка на проц просто чудовищная. Такая же проблема хорошо заметна и на десктопе, если немного опустить скорость работы процессора.


      Определенно стоит провести оптимизацию показа первого экрана. Мне кажется слишком много там сейчас выполняется фоновых действий, которые съедают ресурсы проца, откладывая первый показ.


      По возможности отложить загрузку модулей, которые не нужны для первого показа. Например на главной не обязательно знать как рендерить конкретную новость, а в новости не обязательно знать как рендерить главную. Здесь лучше всего использовать модель загрузки lazy load module


      Пред компиляции готовых HTML страниц нет — это конечно плохо.


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

        0
        Спасибо за уделенное время, работу над оптимизацией конечно же ведем, жаль что не такими темпами, как хотелось бы, но все будет и пререндер и снижение Time to Interactive до вменяемых значений.
        +1

        Почему не уговорили заказчика отказаться от бесконечной прокрутки?

          0
          Бесконечный скролл был одним из обязательных требований заказчика.
            +1

            Но этот вопрос обсуждался? Вы же сами говорите, что "… заказчики — классные профессионалы в медиа, но среди них нет ни одного технического специалиста". Вы пытались им объяcнить, что с точки зрения UX, бесконечный скролл — зло.
            К примеру, я прокрутил 5-6 страниц вниз, открыл новость, потом вернулся назад, и я опять на первой странице, мне снова надо прокручивать 5-6 страниц вниз.

          +3
          WordPress вам не мешал получить все эти возможности. Вообще не встречал ситуации, когда WordPress не справляется. Был опыт внедрения алгоритмической ленты, но и тут получилось удачно подружить python с php.
            +1
            Жаль, что сообщение об опечатках оторвали и не вернули. Постоянно приходилось им пользоваться.
              +1
              Эта задача есть у нас в backlog, мы обязательно вернем эту функциональность.
              +2
              Технических деталей почти нет. Больше всего не понятно зачем бежали с WordPress, если он на самом деле не ограничивал ничего что нужно было.

              • Новая админка — делается на WP.
              • Быстрее дорабатывать — нет, WP знает больше людей и он документирован, если вашего программиста придётся заменить по болезни, то будет медленнее вводить в курс дела человека со стороны.
              • Новый бэкенд стабильнее работает — ????
              • Запросы теперь проще и работают быстрее, потому что идут к нашему серверу на Laravel и в специализированную БД, а не в универсальный WP. — ???? Вы смогли сделать таблицу ещё проще, чем в WP? Или в чём магия? Там и так минимум полей, часть из которых не задействована в выборках.

              Такое ощущение что переделывали просто потому что не разобрались.
                +1
                Это как в Linux — работать надо с тем ПО, в котором разбираешься.
                  –2
                  Да, а я не разбираюсь ни в каком, поэтому Linux говно.
                  0
                  • Новая админка делается не на WP, т. к. заказчику необходим удобный пайплайн подготовки статьи к публикации.
                  • И все таки разрабатывать и дорабатывать SPA админку быстрее чем потрошить php страницы в WP перекраивая под наши нужды, но безусловно WP знает больше людей.
                  • Новый бэкенд стабильно работает — Мы с командой уже год спим по ночам. А не играем в красноглазиков.
                  • Все таки WP это универсальное решение с соответствующими плюсами и минусам, а универсальное всегда больше и сложнее кастомного и уж точно менее гибкое, поэтому мы для наших нужд сделали выбор в пользу кастомного решения.
                    –1

                    1) не разобрались с WP REST
                    2) потрошить и не надо, это делается через API
                    3) WP тем и хорош, что стабильно работает
                    4) Утверждать о том что что-то так просто потому что вы так говорите — логическая ошибка.

                  +2

                  А как вы выстраиваете очередность ленты, когда сначала 33-66% а потом 25-75%? Появляется новый пост — он должен дождаться брата по ширине экрана? Или поджимаем картинку предыдущего превью под формат?

                    0
                    Если правильно понял вопросы.
                    1. создаются линии с указаными размерностями карточек т. е. каждая линия несет в себе определенные варианты карточек например 3x33, 2x50
                    2. Нет никто никого не ждет, идет обычная ротация постов
                    3. На каждую обложку материала сгенерировано несколько вариантов размеров этого изображения и зная базис карточки мы выбираем подходящую обложку.
                    0

                    Самый плохой тип цензуры — самоцензура.


                    Для иллюстрации поместил в ленту статьи из нашего блога. The Bell пишут на острые социальные и политические темы, которые не хочется обсуждать в рамках данного поста.
                      +3

                      Не совсем понял насчет wp, php и повышенной нагрузки. Все же можно кэшировать на уровне веб сервера.
                      Контент менеджеры обычно в шоке от самодельных cms. Как бы они не казались разработчикам удобными и надежными до wp drupal им далеко

                        0
                        Как раз наоборот админка «тюнится» под конкретные задачи редакции, так чтобы редакции в итоге стало удобно, укладываться в сроки, не пропускать задачи для фоторедактора, корректора и пр.
                          0

                          Что то мне подсказывает что конкретные задачи редакции не являются полностью уникальными и неповторимыми. И по озвученной Вами теме с флоу редактирования в wp даже беглый и поверхность ный почту дал результаты в виде плагинов.
                          Вторая часть проблематики которую я не озвучил еще это жизненный цикл системы. То что на ура пишется нужно будет в конце концов кому то поддерживать. И тут у самописных продуктов все не так хорошо. Нет документации, не устоявшаяся структура приложения,

                        +2

                        Не проводили анализ того, что именно было боттлнеком на WP беке? Не рассматривали вариант headless WP с новым публичным фронтом? Тогда редакция могла бы продолжить пользоваться старой админкой.

                          0
                          Главная задача была сделать конструктор ленты со сложной логикой. По сути сейчас headless WP и есть. Но от старой админки в WP всё равно хотим отказаться, потому что там не получается сделать удобный пайплайн подготовки статьи, когда задействовано несколько лиц и на каждый этап назначена своя дата.
                          +1

                          А чего не на друпале? (типа, гибкий, мастшабируемый, одной ногой в симфони, композер, вот это фсё)

                            +1
                            В большинстве случаем, кастомное решение конечно быстрее замутить снуля, чем подгонять тот же WP под нужны клиента. Обратная сторона этого подхода — клиенту придется и дальше переписывать все снуля, если он вдруг решит уйти от вас, так как другой разработчик явно не заходет возиться с кастомным решением и скорее всего сделает свое. В защиту WP можно сказать, что практически все можно реализовать плагинами. В результате, как ни крути, это будет стандартизированное решение, под которое и найти народ легче, чем под свой велосипед. По крайней мере, если смотреть со стороны и на базе собственного опыта. Аворам конечно же виднее, так как они больше в теме :)

                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                            Самое читаемое