Ответ 1
Как и при любой проблеме с производительностью, профилировщик очень поможет в определении узких мест. (Да, вы знаете, что это фаза restore_view, но не там, где на этапе restore_view).
Тем не менее, фаза восстановления восстанавливает весь вид, а не только части, которые будут обрабатываться или визуализироваться. Цитирование Документация Richlaces taglib:
: Id ['s] (в формате вызова UIComponent.findComponent()) компонентов, обработанных на этапах 2-5 в случае AjaxRequest, вызванных этим компонентом. Может быть единым идентификатором, разделенным запятыми списком идентификаторов или выражением EL с помощью массива или коллекции
RESTORE_VIEW - это этап 1. Также:
reRender: Id ['s] (в формате вызова UIComponent.findComponent()) компонентов, отображаемых в случае AjaxRequest, вызванных этим компонентом. Может быть единым идентификатором, разделенным запятыми списком идентификаторов или выражением EL с помощью массива или коллекции
Кроме того, я не уверен, что UIComponent.findComponent() реализован с использованием более подходящей структуры данных, чем дерево компонентов. (Поиск чего-то в дереве компонентов сводится к линейному поиску...).
Я наблюдал подобные эффекты с JSF 2.0 (Mojarra). Мой вывод состоял в том, что мнения не должны содержать более нескольких десятков UIComponents, независимо от того, будут ли они визуализированы. (По-другому, AJAX непригоден для навигации по страницам.) Мы делаем вывод, что мелкие представления не включают в себя только компоненты, которые в настоящее время видны в представлении, и переключают представления, если необходимо отобразить много новых компонентов. То есть вместо одного представления с 10 вкладками с 30 компонентами каждый, у нас будет 10 видов, каждый из которых содержит только содержимое одной вкладки. Недостатком такого подхода является то, что компоненты переключаются при переключении вкладок, в результате чего теряется какое-либо состояние, не содержащееся в резервной копии beans.
Я не утверждаю, что это хорошее решение. Увы, это был лучший, который я нашел, когда смотрел на это пару недель назад. Я был бы счастлив, если бы мне показали лучшую.
Edit
Когда я говорю восстановление, я имею в виду ViewHandler.restoreView()
, который вызвал и для первоначального запроса на получение, и для обратной передачи. Неверно сказать, что restoreView
будет просто повторно использовать существующее представление как есть. Например, спецификация JSF 2.0 в разделе 7.6.2.7:]
Метод
restoreView()
должен выполнять следующие обязанности:Все реализации должны:
- Если идентификатор viewId не может быть идентифицирован, верните
null
.- Вызвать метод
restoreView()
связанногоStateManager
, передав экземплярFacesContext
для текущий запрос и рассчитанный viewId, и верните возвращенныйUIViewRoot
, который может бытьnull
.
и в разделе 7.7.2:
Реализации JSF поддерживают два основных механизма сохранения состояния на основе значения javax.faces.STATE_SAVING_METHOD параметр инициализации (см. раздел 11.1.3 "Конфигурация приложения Параметры" ). Возможные значения этого параметра дают общую индикацию используемого подхода, позволяя Реализации JSF для новаций по техническим деталям:
- клиент - [...]
- server - причина сохранения сохраненного состояния на сервере между запросами. Реализации, которые хотят включить их сохраненное состояние для отказа от другого экземпляра контейнера должно помнить об этом при реализации своего сервера стратегия сохранения состояния. Реализация по умолчанию Сериализует представление как в режиме клиента, так и на сервере. в сервер, это сериализованное представление сохраняется в сеансе, а уникальный ключ для извлечения представления отправляется вниз клиент. Сохраняя сериализованное представление в сеансе, переход на другой ресурс может произойти с использованием обычных механизмов, предоставляемых контейнер.
Иными словами, поддержка AJAX, добавленная в JSF (как добавленная RichFaces 3 к JSF 1.2, так и встроенная в JSF 2.0), направлена на снижение потребления полосы пропускания сети, а не на стороне сервера.