ПРИЛОЖЕНИЯ ПРОСТО ТЯЖЕЛЕЕ И ВСЕГДА БУДУТ ТАКОВЫМИ

В эти дни довольно много говорят об одностраничных приложениях (SPA) и потрясающем опыте пользователей, который они предоставляют. 

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

Первая существенная сложность: дополнительный логический уровень

Во всех, кроме самых простых приложений, если вы создадите SPA, вам понадобятся три уровня логики вместо двух. Я определяю логический уровень как физический уровень, который содержит «бизнес-логику», специфичную для функций вашего приложения. В традиционном веб-приложении, независимо от платформы вашего веб-сервера, среды MVC и т. п. Если вы хотите добавить редактор (например,) для вашего приложения, вам нужно добавить несколько таблиц базы данных (уровень данных) и некоторый код, который создает HTML и обрабатывает формы, когда пользователи вносят изменения (уровень веб-сервера). В SPA вы, очевидно, все еще будете иметь уровень данных, у вас будет уровень веб-сервера, который предоставляет данные через веб-службы JSON или XML, и, наконец, у вас будет уровень браузера с кодом на основе JavaScript, который представляет данные для пользователей и обрабатывает обновления.

Рассмотрим код для простого дисплея только для чтения, который показывает клиента и некоторые заказы.

ТРАДИЦИОННОЕ ВЕБ-ПРИЛОЖЕНИЕ

На веб-сервере:

var customer = retrieveCustomerFromDatabase();
addCustomerToHtml( customer );

var orders = retrieveOrdersFromDatabase( customer );
addOrdersToHtml( orders );

ЭКВИВАЛЕНТ SPA

На веб-сервере:

var customer = retrieveCustomerFromDatabase();
addCustomerToJson( customer );

var orders = retrieveOrdersFromDatabase( customer );
addOrdersToJson( orders );

И в браузере:

var customerAndOrders = retrieveCustomerAndOrdersFromWebService();
addCustomerToHtml( customerAndOrders.Customer );
addOrdersToHtml( customerAndOrders.Orders );

Благодаря архитектуре SPA вы, по сути, должны иметь дело с заказчиком и заказами дважды. Дело не в том, что вам приходится выполнять любые механические задачи дважды: вы по-прежнему только извлекаете данные один раз и создаете представление HTML один раз. Но теперь вы должны публично представлять своих клиентов и заказы как на уровне веб-сервера, так и на уровне браузера. Если вы добавите новый тип данных на дисплей своего клиента, например список адресов доставки, вам нужно добавить адреса в JSON и HTML. Если вам необходимо ограничить доступ к полю (например, номер социального страхования), чтобы его могли видеть только определенные пользователи, вам требуется проверка авторизации дважды, один раз при написании JSON и снова при построении HTML. В традиционном веб-приложении вы можете перейти прямо из данных в конечное представление HTML с помощью одного блока кода на веб-сервере. Вот диаграмма, которая суммирует разницу:

SpaLogicComparison.png

В простых случаях вам может не понадобиться писать какую-либо логику для уровня веб-сервера, предпочитая вместо этого использовать что-то вроде OData или «бэкэнд как услугу», например, Windows Azure Mobile Services. Но как только редактор вашего клиента впервые свяжется с пользователями и начнет делать запросы, и вы начнете приукрашивать экраны различными битами информации из других таблиц базы данных или источников данных, вам понадобятся ваши собственные веб-сервисы, чтобы связать вещи и избегать очень частых разговоров между веб-браузером и сервером. В этом вопросе не будет решения с серебряной пулей, поскольку латентность сети не исчезнет в ближайшее время.

Вторая существенная сложность: Синхронизация данных

ООПТ обычно хранят больший объем данных в уровне браузера в любой момент времени; это то, как они позволяют пользователям без промедления переходить от задачи к задаче. Данные в браузере всегда могут быть устаревшими из-за внешних изменений, и чем больше у вас есть, тем сложнее определить во время синхронизации, является ли оно или не является устаревшим. И когда это происходитустаревайте, чем больше данных у вас есть, тем сложнее вам (или вашим пользователям) согласовать его. Вернемся к примеру редактора клиентов: что произойдет, если пользователь отредактирует клиента, начнет навигацию и начнет редактирование второго клиента, прежде чем вы обнаружите, что обе записи были модифицированы на несколько секунд ранее фоновым процессом, который очищает почтовые адреса клиентов? Возможно, вы сможете обеспечить хорошее поведение, чтобы справиться с этим, но это непросто, и это будет связано с логикой, характерной для ситуации. И такие проблемы усугубляются, если вы решите поддерживать автономное редактирование. Чем больше времени вы позволяете между синхронизацией данных, тем больше проблем у вас будет.

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

SpaDataComparison.png

Мысли об этом

Никто не может утверждать, что SPA-центры обеспечивают более непрерывный, легкий пользовательский опыт. Но если вы создаете приложение, которое, честно говоря, будет обслуживать только 10 человек, или 100 -- или 1000 -- вы действительно хотите нести более высокие затраты на разработку и обслуживание только ради того, чтобы нажимать конверт пользовательского опыта ?