Улучшите производительность сетевых API для ваших приложений

Улучшите производительность сетевых API для ваших приложений

7 ноября 2022 г.

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

Однако часто оптимизация времени отклика API не выходит за рамки сравнительного анализа конечных точек и оптимизации запросов SQL. Конечно, иметь быструю кодовую базу выгодно, но также важно понимать, что задержка, воспринимаемая пользователем, также зависит от того, как и в каких сетевых условиях используется API.

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

Здесь я открываю google.com в своем Wi-Fi. Следующий снимок сделан с сетевым подключением, ухудшенным до 3G (780/330 Кбит/с, задержка 100 мс) с использованием Network Link Conditioner из пакета Apple Additional Tools for Xcode.

Вдвое медленнее. И здесь мы добавляем 1% потери пакетов:

Как видите, жизнь быстро становится совсем невыносимой. И я даже пропустил здесь установление соединения и рукопожатие SSL. Вы обязательно должны попробовать это со своим приложением!

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

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

Клиенту с задержкой 100 мс в каждую сторону придется ждать 600 мс только для того, чтобы показать пользователю что-то значимое. Но что, если этот API может вернуть все необходимые данные за один ответ? Это на 400 мс быстрее!

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

Выполняя такого рода оптимизацию API путем объединения/пакетирования данных ответов, важно помнить, что сеть имеет свои ограничения и ограничения. Не забывайте про MTU и фрагментацию пакетов. Вы можете узнать больше об этом, например, здесь. Для API это означает, что существует ограничение на размер ответа, после которого он будет фрагментирован на несколько TCP-пакетов. Это все равно будет быстрее, чем выполнение отдельных HTTP-запросов из-за заголовков.

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

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

Теперь давайте поговорим о размере тела отклика. Первое, что стоит проверить — это сжатие ответа. Убедитесь, что он включен даже для динамического API. Вы проиграете с точки зрения обработки, но это уменьшит объем передаваемых данных, иногда значительно, и уменьшит задержку для клиентов.

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

И последнее, о чем я хочу упомянуть, — это формат сериализации данных. Большинство современных API построены на основе JSON. JSON — удобный и вездесущий формат; он удобочитаем и очень хорошо работает в браузерах. Проблема с ним в многословии. Вот пример:

Полный размер ответа здесь составляет 2512 байт. Из него только 1586 байт данных. Остальное — имена полей и синтаксис JSON:

Но даже это можно уменьшить, если убрать повторяющиеся данные, которые можно получить из контекста запроса. И это оставляет нам 626 байт.

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

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

Подводя итог:

  • Будьте в курсе сетевых условий ваших пользователей. Измерьте задержку, воспринимаемую клиентами.
  • Разработайте свой API так, чтобы он делал меньше запросов.
  • Разработайте свой API таким образом, чтобы отправлять меньше данных.
  • Проверьте, как ваше приложение взаимодействует с API в реальном мире.


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