QR code

SPAs Are a Performance Dead End

  • Translated by to

Похоже, что популярно разрабатывать веб-сайты как Одностраничные приложения (SPA). Вместо того, чтобы показывать новую HTML-страницу при каждом клике, SPA отправляет легкую оболочку с помощью JavaScript. JS делает HTTP-запросы, получает JSON и внедряет данные в DOM. При каждом действии пользователя страница не перезагружается — меняется только DOM. Такая архитектура, когда-то ответ на медленные браузеры и ненадежные сети, теперь является узким местом. Страница строится из фрагментов, каждый из которых требует собственного HTTP-запроса. Независимо от того, насколько быстрым является каждый запрос, умножение уменьшает все усилия по оптимизации.

В 2000 году Рой Филдинг, автор REST и соавтор HTTP, описал Веб в своей диссертации:

Просто говоря, каждое действие приводит к перезагрузке HTML-страницы.

В 1999 году Microsoft представила XMLHttpRequest для Outlook Web Access, обеспечивая фоновые HTTP-запросы. В 2005 году Джесси Джеймс Гарретт придумал термин AJAX в своем эссе “Ajax: A New Approach to Web Applications.” Это пригодилось, когда полные перезагрузки страниц перестали хорошо работать:

  • Сети были ненадежными.

  • Полная перезагрузка страницы казалась неэффективной.

  • Пользователи ожидали интерактивности, подобной настольным приложениям

AJAX прокладывает путь для SPA: вместо HTML сервер отправляет JSON, и браузер воссоздает страницу локально. Затем появились фреймворки: Angular, React, Vue. Каждый формализует ту же идею: браузер хостит приложение, сервер доставляет данные.

Представьте себе простой онлайн-калькулятор, где пользователь вводит “2+3”, нажимает “Отправить” и видит результат прямо рядом с полем ввода. Никакого перезагрузки страницы. DOM остается тем же. JS внутри браузера изменяет только результат вычисления в одном <div/>.

Основным обоснованием для такой архитектуры является производительность. Если сервера медленные, отрисовка полной HTML-страницы занимает больше времени, чем просто JSON с результатом вычисления. Если сеть ненадежна, повторная доставка всей HTML занимает больше времени, чем небольшой JSON-документ. Также, если браузеры медленные, сделать маленькое изменение в DOM работает быстрее, чем полная перезагрузка страницы.

Это верно для тривиального примера. Однако, когда SPA становится крупнее, фронтенд должен совершать десятки обращений к бэкенду. Посмотрите, что делают Facebook и LinkedIn при отображении вашей домашней страницы. Довольно простой пользовательский интерфейс с просто списком последних постов заполняется несколькими частями, каждая из которых приводит к своему собственному HTTP-запросу, иногда занимающему более нескольких секунд для завершения отображения страницы. Их UX ужасен, если спросите меня.

Их архитекторы глупы? Нет.

Сама идея SPA недостаточно хороша. Архитекторы Facebook и LinkedIn являются заложниками этой идеи. Они не могут ускорить работу своих веб-сайтов, потому что они, по своей сути, состоят из фрагментов, получаемых с бэкенда. Они должны совершать множественные HTTP-запросы.

Штраф производительности у SPA структурный, а не случайный. Даже если HTTP/2 мультиплексирует запросы, интерфейс все равно ждет прибытия JSON в определенном порядке - классическая блокировка по линии заголовка на уровне приложения. Более того, один запрос часто раскрывает разрешения, флаги функций или идентификаторы сущностей, необходимые для следующего запроса, превращая параллельные вызовы в водопад. Кэширование также не помогает: десятки конечных точек, каждая со своим TTL, редко приводят к полному попаданию в кеш, а частичные попадания все равно заставляют браузер собирать и согласовывать страницу во время выполнения. Тем временем, браузер должен управлять стабилизацией макета, индикаторами загрузки и частичными сбоями - все это до того, как появится значимое содержимое.

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

Большинство веб-архитекторов просто не могут сделать свои веб-сайты такими быстрыми, как Stack Overflow, который не является SPA. Он доставляет целую HTML-страницу, отрендеренную на сервере с использованием Razor за один <50мс запрос. Он использует клиентские компоненты на стороне клиента выборочно, но они изолированы и не отменяют центральную роль серверного HTML для начального опыта. Их UX один из лучших на современном вебе, если спросите меня.

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

Буквально каждый крупный, содержательный, ориентированный на потребителя SPA, о котором я могу подумать, ужасен с точки зрения UX. Даже Gmail - не исключение. Их UX был бы заметно лучше, если бы они следовали принципам Роя Филдинга и перезагружали страницу каждый раз, когда открывается электронное письмо. Я не шучу.

Translated by ChatGPT gpt-3.5-turbo/42 on 2026-01-25 at 15:19

sixnines availability badge  GitHub stars