Разница в производительности между res.json() и res.end()

Я хочу отправить ответ JSON с помощью Node и Express. Я пытаюсь сравнить производительность res.end и res.json для этой цели.

Версия 1: res.json

res.json(anObject);

Версия 2: res.end

res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(anObject));

Запуск некоторых тестов Я вижу, что вторая версия почти на 15% быстрее первой. Есть ли особая причина, по которой я должен использовать res.json, если я хочу отправить ответ JSON?

Ответ 1

Да, очень желательно использовать json, несмотря на накладные расходы.

setHeader и end исходят из родного http-модуля. Используя их, вы эффективно обходите много добавленных функций Express, и, следовательно, умеренный скачок скорости в тесте.

Однако, тесты в изоляции не рассказывают всю историю. json на самом деле просто метод удобства, который устанавливает Content-Type, а затем вызывает send. send - чрезвычайно полезная функция, потому что она:

  • Поддержка HEAD просит
  • Устанавливает соответствующий заголовок Content-Length, чтобы гарантировать, что ответ не использует Transfer-Encoding: chunked, который отнимает полосу пропускания.
  • Самое главное, обеспечивает поддержку ETag автоматически, разрешая условные GET s.

Последний момент - самое большое преимущество json и, вероятно, большая часть 15% -ной разницы. Express вычисляет контрольную сумму CRC32 строки JSON и добавляет ее как заголовок ETag. Это позволяет браузеру делать последующие запросы для того же ресурса, чтобы выдать условный GET (заголовок If-None-Match), и ваш сервер ответит 304 Not Modified, если строка JSON будет одинаковой, что означает, что фактический JSON не нужно отправлять по сети снова.

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


Наконец, есть проблема с ошибками. В вашем примере "версия 2" есть ошибка.

JSON стробируется как UTF-8, а Chrome (вопреки спецификации) не выполняет обработку ответов application/json как UTF-8; вам нужно указать charset. Это означает, что символы, отличные от ASCII, будут искажены в Chrome. Эта проблема уже была обнаружена пользователями Express и Express устанавливает правильный заголовок для вас.

Это одна из многих причин заботиться о преждевременной/микро-оптимизации. Вы рискуете внедрить ошибки.