7 проверенных способов повысить скорость разработки и качество проекта

7 проверенных способов повысить скорость разработки и качество проекта

29 марта 2023 г.

Все эти пункты можно применить к разработке мобильных приложений, веб-интерфейсу и серверной части. Я собрал эти практики из разных команд и через проблемы, с которыми я столкнулся за последние 6 лет. Эти приемы могут быть особенно полезны, когда вы создаете проект с нуля. Какие-то из них могут подойти вам идеально, а какие-то нет. Если у вас есть свои подходы и разный опыт, буду рад, если вы поделитесь ими здесь. Кстати, если вы мидл- или джуниор-разработчик, ищущий повышения, внедрение этих практик в вашей команде может действительно помочь. Поехали!

1. Имитация ответов серверной части, пока они не будут готовы

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

Затем каждая команда приступает к планированию и декомпозиции задач. Но что, если бэкенд-команде требуется значительно больше времени для разработки своей части? Что, если они смогут доставлять конечные точки только раз в неделю?

<цитата>

Бэкенд становится узким местом.

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

Решение: договоритесь о контракте с серверной командой и имитируйте все запросы.

In the classic approach, we have a gap between tasks. In the "mock approach", all work is performed as a flow

1. Координируйте работу с серверной командой по конечным точкам и объектам.

2А. Реализуйте серверный API с ответами-заглушками. Библиотека Faker может помочь с созданием образцов данных.

2Б. Или реализовать заглушки на интерфейсе. Это может быть объект с данными прямо в коде. Например, в Node.js это можно эффективно реализовать с помощью динамического импорта и избежать увеличения размера пакета:

getUser() {
    return import('../../assets/mocks/users')
      .then(data => data.userById)
      .then(deserializeUser);
  };

Это также может быть фиктивный HTTP-сервис, который извлекает файлы JSON из ресурсов, а не делает настоящие запросы.

  1. Скрыть функцию за флагом функции.

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

2.Флажок функции

Теперь, как вы, наверное, заметили, в предыдущем разделе я упомянул флаги функций. В двух словах, флаги функций, также известные как переключатели функций, позволяют разработчикам включать или выключать функции в реальной среде. Есть также несколько случаев, когда они полезны: постепенное развертывание новых функций, проведение A/B-тестирования, включение бета-функций и внедрение исправлений.

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

В коде это выглядит довольно просто:

  1. В проекте мы получаем все флаги активных функций. Под капотом Gitlab основан на Unleash (сервис переключения функций), мы используем его официальный клиент.
  2. А затем просто добавьте if features.YOUR_FEATURE в код, который нужно скрыть.
  3. Вы можете расширить варианты использования, добавив другие значения в флаг функции. Например, добавив значение цвета или значение скидки.

3. Мониторинг ошибок для отслеживания проблем в производственной среде

Когда наш продукт перешел от стадии MVP к рабочему приложению, мы были обеспокоены тем, что пользователи будут получать ошибки, которые мы не могли воспроизвести и о которых могли даже не знать. Изучив инструменты отслеживания ошибок, мы остановились на Sentry. Опыт был положительным. А теперь давайте пройдемся по важным нюансам.

Бесполезные ошибки

Под капотом будет отслеживаться любое неперехваченное исключение. По мере роста приложения и числа пользователей количество ошибок может стать настолько огромным, что заметить что-то действительно важное становится практически невозможно. Sentry может превратиться в мусорный контейнер, если вы не будете отфильтровывать ненужные вещи. Например, такие события, как отмененные запросы, ошибки подключения и ошибки подключенных скриптов, совершенно бесполезны и будут только спамить вашу рабочую почту уведомлениями. В качестве решения можно добавить фильтры в конфигурацию. Для этого просто определите обратный вызов beforeSend и поместите его в свой sentryPackage.init. В этом обратном вызове вы можете проанализировать каждую пойманную ошибку, а затем отбросить ее (возвратив null), если она бесполезна. Вот пример фильтра, исключающего ненужные ошибки:

function beforeSend(event, hint) {
  const error = hint.originalException;

  const externalScripts = [
    'gtm.js', // Google Tag Manager
    'watch.js', // X Analytics
  ].join('|');

  const errorsToIgnore = [
    AxiosError.ERR_NETWORK, 
    AxiosError.ECONNABORTED, 
    AxiosError.ETIMEDOUT
  ];

  if (axios.isCancel(error) 
      || errorsToIgnore.includes(error.code) 
      || error.stack?.match(externalScripts)) {
    return null;
  }

  return event;
}

Включите больше данных для лучшей отладки

По умолчанию Sentry может не включать содержимое запроса и ответа в отчет об ошибке. Без этой информации правильная отладка невозможна. К счастью, мы можем включить эту информацию в обработчик beforeSend.

function beforeSend(event, hint) {
  const error = hint.originalException;
  if (error.isAxiosError) {
      const url = error.request?.responseURL;
      const response = error.response?.data;
      const request = error.config?.data;

      event.extra = { 
        ...(event.extra || {}), 
        url, 
        response, 
        request 
      };
   }

   return event;
}

Отфильтровать конфиденциальную информацию

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

Автономное решение

Если характер вашего бизнеса не позволяет хранить такие данные на другом сервере, Sentry предлагает возможность использовать их на ваших собственных серверах.

4.Трассировка

The path of trace ID

Представьте себе ситуацию, когда вы успешно фиксируете ошибку в Sentry, но информации в описании недостаточно. Вы обращаетесь к логам, но как определить конкретную ошибку среди тысяч запросов и тем более строк лога в секунду? Как отличить правильные, построить цепочку запросов и определить точную ошибку, особенно если в вашем бизнесе несколько команд и есть интеграция с другими сервисами? Здесь в игру вступает трассировка.

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

В нашей конкретной реализации мы использовали Jaeger, основанный на OpenTracing API.

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

5.Оптимизация производительности

Когда мы внедрили MVP финтех-приложения, у нас была довольно сложная форма. В то время я был еще молод и неопытен. И в конце концов мы поняли, что наш проект тормозит. Пришлось потратить дополнительные часы на выяснение причины. У нас было много ненужных повторных рендеров, потому что мы игнорировали основные правила, связанные с пропсами в React. Я хотел сделать все возможное, чтобы избежать подобных ситуаций в будущем.

Итак, я добавил в проект линтеры типа this и дополнительную стартовую конфигурацию в package.json для запуска < a href="https://github.com/welldone-software/why-did-you-render">почему-did-you-render. Короче говоря, этот плагин выдает предупреждение, если что-то перерисовывается без необходимости, и предлагает, как этого избежать. Кроме того, мы включили запуск Lighthouse в безголовом режиме. Некоторые люди говорят, что преждевременная оптимизация — это плохо, но для меня это принцип: ==сделай это правильно с самого начала==.

6.Определенный стиль кода для всех командных проектов

Вероятно, вы слышали о теории разбитых окон. Если в здании есть одно разбитое окно и никто не заменяет со временем в этом здании не останется ни одного целого окна.

Чем меньше в проекте правил и элементов управления, тем больше соблазн написать некачественный код или написать его совершенно в другом стиле. Непоследовательный код увеличивает время, необходимое для его понимания, в то время как понятный, знакомый и лаконичный код обеспечивает быстрое чтение. В одной из наших команд мы описали стиль кодирования в одном месте. В качестве отправной точки вы можете взять код Prettier или Airbnb. стиль.

7. Регрессионные тесты

О различных типах тестов, подходах и способах их правильного написания уже написано значительное количество литературы. Единственное, что здесь стоит упомянуть, это то, что ни одно производственное приложение не может выжить без регрессионного тестирования. Вот почему мы сосредоточили все наши усилия на создании комплексной сквозной среды тестирования и на ее основе написали тесты, связанные со сценариями BDD и пользовательскими историями. Мы использовали шаблон Page Object для организации нашего кода и фреймворк Playwright для взаимодействия с браузером. Для тестирования в различных браузерах, включая Safari, вы можете использовать решение под названием Moon. Его можно развернуть на одном из ваших серверов.

Заключение

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

Основное изображение для этой статьи было создано с помощью генератора AI-изображений через подсказку "скорость".


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE