Заголовок может заставить вас подумать, что этот пост - еще один пост с разглагольствованием о недостатках «одностраничного приложения». Это больше касается того, чтобы пролить свет на перспективу производительности , о которой следует помнить при проектировании SPA. Особенно, если ваш SPA использует API из разных доменных служб.

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

Большинство SPA включают в себя «микросервисы». Они используют разные конечные точки служб, обслуживаемых разными доменами в SPA. Это повышает отказоустойчивость, отказоустойчивость и повышает удобство использования нашего продукта. Несколько доменных запросов станут неизбежными до тех пор, пока мы не будем строго придерживаться одного и того же доменного приложения API Gateway - Microservices Pattern для нашего SPA.

Представьте, что у нас есть GET API /users/report/:id, обслуживаемый из домена api.example.com. Наш СПА обслуживается с spa.example.com. :id означает, что это значение, которое может изменяться для каждого запроса.

Можете ли вы угадать проблему с вышеуказанным дизайном API в отношении CORS (Cross-Origin Resource Sharing) и ее влияние на производительность нашего SPA?

Вот краткое введение в CORS от MDN:

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

Это связано с тем, что нам нужно отправить заголовок, отличный от CORS-safelisted-request-header. Пример заголовка - Authorization, x-corelation-id. Часто значение нашего заголовка Content-Type равно application/json. Это недопустимое значение для заголовка Content-Type для cors-safelisted-request-header.

Если наш api.example.com сервер принимает content-type из application/json, наш домен SPA spa.example.com сначала отправит HTTP-запрос методом OPTIONS. Он отправляется ресурсу /users/report/12345 в другом домене api.example.com. Чтобы определить, безопасен ли фактический запрос для отправки, опция отправляется предварительно. Межсайтовые запросы всегда предварительно обрабатываются таким образом, поскольку они могут иметь последствия для пользовательских данных.

Задача api.example.com сервера - сообщить другому домену spa.example.com о безопасности отправки данных. Возможно, вы сделали что-то подобное для CORS внутри своего приложения.

После того, как api.example.com сервер отправит правильный ответ от метода «OPTIONS» другому домену spa.example.com, будут обработаны только фактические данные с запросом, который вы пытались сделать.

Итак, для доступа к ресурсу api.example.com/users/report/12345 было выполнено два фактических запроса.

Вы могли бы сказать да. Мы можем использовать Access-Control-Max-Age header для кеширования результатов предполетного запроса. В следующий раз, когда мы обратимся к ресурсу api.example.com/users/report/12345 из spa.example.com, предварительный запрос не будет.

Да, это правда, но запомните заголовок - Ужасная стоимость запросов CORS в одностраничном приложении (SPA). Это происходит от API, который мы используем, и от того, как он был разработан. В нашем примере мы разработали наш API /users/report/:id, где :id означает его значение, которое может изменяться.

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

Таким образом, в нашем случае для доступа к ресурсам api.example.com/users/report/12345 и api.example.com/users/report/123987 он инициирует в общей сложности четыре запроса от нашего SPA.

Если у вас медленная сеть, это может стать серьезной неудачей. Особенно, когда на запрос OPTIONS требуется 2 секунды для ответа и еще 2 секунды для данных.

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

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

Не существует решения или технологии, которые были бы полностью хорошими или плохими. Важно знать его недостатки и то, что нужно, чтобы заставить его работать. Это то, что отличает ваше приложение от других.

Узнал что-то? Хлопайте 👏, чтобы помочь другим найти эту статью.