суббота, 28 мая 2016 г.

Настройка производительности ADF приложений (ADF performance tuning)

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

Основные рекомендации по настройке

Перед сборкой, настройкой  и деплоем приложения, для достижения оптимальной производительности рекомендуется  выполнить следующее :
  • Конфигурация и профилирование ADF
  • Повышение производительности ADF
  • Настройка атрибутов ADF компонентов
  • Повышение производительности компонентов Table and Tree Components
  • Повышение производительности для  autoSuggest(автозаполнение)
  • Доставка данных( Lazy или Immediate)


Конфигурация и профилирование ADF

 Конфигурация ADF происходит в файле web.xml. По умолчанию большинство компонентов  настроены для наилучшей производительности. Вот описание части из них


Свойство
Необходимое значение
Debug ресурсов
org.apache.myfaces.trinidad.resource.DEBUG
Eсли параметр имеет значение true, тогда будет возможна отладка ресурсов. Для увеличения производительности, этот компонент должен иметь значение false
Проверка изменения JSP и CSS файлов
oracle.adf.view.rich.CHECK_FILE_ MODIFICATION
false
Сжатие состояния страницы
org.apache.myfaces.trinidad.COMPRESS_ VIEW_STATE
false
Уровень логирования на клиентской стороне
oracle.adf.view.rich.LOGGER_LEVEL
off
(Если вы хотите включить JavaScript логирование, можно использовать следующие уровни: SEVERE,WARNING, INFO, CONFIG, FINE, FINER, FINEST, and ALL)
Отладка JavaScript
org.apache.myfaces.trinidad.DEBUG_JAVASCRIPT
false
Утверждения
oracle.adf.view.rich.ASSERT_ENABLED
false
Отключение сжатия данных
DISABLE_CONTENT_COMPRESSION
false
Отключение автоматического тестирования
oracle.adf.view.rich.automation.ENABLED
false

Повышение производительности ADF


Основные рекомендации:

  • Избегайте встроенный JavaScript на странице ( встроенный JavaScript может увеличить размер ответа полезной нагрузки, никогда не будет кэшироваться в браузере и может блокировать рендеринг страницы. Вместо этого выносите скрипты в отдельные js файлы)
  • Удалите unkown rowCount (таблицы у которых неизвестно количество строк, могут влиять производительность.  Потому что получение последнего набора строк занимает у пользователя много времени. Что бы избежать это, установите в VO DeferEstimatedRowCountProperty="false")
  • Используйте Partial Page Navigation
  • Используйте шаблоны страниц( шаблоны позволяют переиспользовать код)
  • Используйте компоненты управляющие геометрий пространства( идет речь о таких компонентах  как PanelAccordion, PanelStretchLayout, PanelTabbed, BreadCrumbs NavigationPane, PanelSplitter, Toolbar, Toolbox, Table и Train.  По возможности старайтесь, что бы у этих компонентов было меньше родительских компонент)
  • Используйте функцию переполнения ADF компонентов( эта функция позволяет перенести дочерние компоненты в невидимую область, когда они не вместились на страницу. Компоненты, которые имеют встроенную  поддержку переполнения являются: PanelTabbed, BreadCrumbs, NavigationPane, PanelAccordion, Toolbar, и Train )
  • Используйте Partial Page Rendering
  • Кэшируйте ресурсы
  • Уменьшите размер token-ов для состояния кэша( этой свойство находится в web.xml и называется org.apache.myfaces.trinidad.CLIENT_ STATE_MAX_TOKENS и в нем устанавливается сколько token-ов может быть установлено в один момент времени. Значение по умолчанию: 15.  Но будьте осторожны, при установке значения 1, у вас не будет работать даже кнопка "Назад" из за того, что не будет сохранено предыдущее состояние)
  • Кастомные стили необходимо прописывать в верху страницы (если стиль определить не в начале страницы, то браузеру придется перечитывать страницу, а это может повлиять на производительность)
  • Отключите режим debug output( элемент debug-output находится в trinidad-config.xml и определяет необходим ли обширный уровень вывода данных  для помощи при отладке)
  • Отключите автоматическое тестирование( при включение автоматического тестирования, на клиенте создаются копии всех компонентов, что отрицательно влияет на производительность)
  • Отключите  анимацию, в ненужных местах  (для этого в trinidad-config.xml используется элемент animation-enabled)
  • Отключите JavaScript профилирование ( при включенном профилировании, для сбора статистики страница обрабатывается 2 раза. Для отключения пропишите в web.xml  oracle.adf.view.rich.profiler.ENABLED = false)


Настройка атрибутов ADF компонентов


  • Используйте атрибут "immediate" ( у ADF компонентов есть атрибут immediate. Если этот атрибут имеет значение true, то валидация, конверсия и события связанные с компонентом выполняются на фазе applyRequestValues. Это может увеличить производительность в таких случаях как если значение  input  компонента нужно проверить  перед другими значениями. В случае ошибки он будет обнаружен ранее в цикле и дополнительную обработку можно избежать)
  • Внимательно обращайтесь с атрибутами  "visible" и "rendered"( все ADF компоненты которые могут быть отображены, имеют 2 свойства : visible и rendered. Visible указывает должен быть отображен компонент или спрятан, а rendered указывает должен ли компонент рендериться. Для улучшения производительности, если вам не нужно что бы компонент отображался, используйте свойство rendered)
  • Используйте  client-side события ( если есть возможность обработать относительно простую задачу на стороне клиента, делайте это. Так как это уменьшит количество обращений к серверу, а значит и увеличит производительность)
  • Следите за длинной  атрибута "id" ( его длина не должна превышать 7 символов)
  • Установите  значение deferred в атрибут  childCreation для компонента af:popup, что бы увеличить производительность на стороне сервера( этот подход нельзя использовать, если внутри popup-а есть следующие тэги: f:attribute, af:setPropertyListener, af:clientListener, af:serverListener. Так же этот подход нельзя использовать, если вам необходимо обратиться любому компоненту из popup перед его отображением. Установка childCreation = "deferred " отложит создание дочерних компонентов всплывающего окна, и вы не сможете обратиться к ним до тех пор,  пока popup не отобразится)



Повышение производительности компонентов Table and Tree Components

Table, Tree и  TreeTable  являются одними из самых сложных, и часто используемых компонентов. Так как эти компоненты могут включать в себя большие наборы данных, они могут быть источником проблем производительности.  Вот некоторые рекомендации по работе с ними:


  • Используйте  режим editingMode="clickToEdit" в редактируемых таблицах (при использовании  этого режима уменьшается  количество передаваемых данных и потенциально улучшается  взаимодействие с пользователем)
  • Уменьшите, там  где это возможно fetchSize( если в таблице большой размер выборки, то и больше данных должны быть обработаны, получены с сервера и отобразиться на клиенте )
  • Отключите растягивание колонок( колонки в table и treeTable могут растягиваться на неиспользуемом пространстве. Будьте осторожны с этим свойством, оно влияет на производительность при отображении страницы)
  • Используйте  заголовки строк и замороженные столбцы только при необходимости( эти свойства  могут повлиять на производительность на стороне клиента. Для того, чтобы получить максимальную производительность для компонентов таблицы, используйте  эти опции только тогда, когда они необходимы)


Повышение производительности для  autoSuggest(автозаполнение)

autoSuggest  это функция которую можно использовать для следующих компонентов: inputText, inputListOfValues, и inputComboboxListOfValues. Когда пользователь вводит символы в поле, компонент отображает возможный список для выбора.  Функция выполняет запрос к таблице базы данных для фильтрации результатов. Для того, чтобы ускорить обработку  данных, нужно создать  индекс  на колонке, для которой  включено автозаполнение. Это улучшает время отклика компонента, особенно, когда таблица  имеет большое количество строк.

Доставка данных( Lazy или Immediate).

Данные для Table, Tree и других  компонентов могут быть доставлены немедленно(immediate) или позже(lazy). По умолчанию используется режим  доставки lazy. Это означает, что данные не будут доставлены в первоначальном ответе от сервера. После того, как начальная страница отобразится, клиент запросит  данные у сервера  и получит их в ответ на второй запрос.В режиме  доставки immediate, данные могут быть  получены сразу .
При выборе между этими двумя вариантами, необходимо учитывать следующее:

Режим Lazy:
Этот  режим должен  использоваться для компонентов  у которых известно, что время выборки большое . Так же этот режим  можно использовать на страницах, где не сразу видно содержимое, и пользователь выполняет прокрутку вниз к нему. В этом случае время, чтобы доставить видимый контекст клиенту будет короче, а пользователь ощутит лучшую производительность.

Режим Immediate:
Этот режим следует использовать, если получение  данных выполняется  быстро  или если возвращается небольшой набор данных. В этих случаях время отклика быстрее, чем при использовании режима lazy.
Еще одним преимуществом этого режима, является  меньше использование ресурсов сервера, по сравнению с lazy. В immediate отправляется только один запрос на сервер, что приводит к снижению загрузки процессора и памяти на сервере.

Дополнительные рекомендации по настройке

Настройка Session Timeout ( будьте осторожны при настройке таймаута сессии. При большом времени таймаута  и большом количестве пользователей, сервер может не справиться с нагрузкой из за нехватки памяти.  Время таймаута можно установить в web.xml)

Настройка View Object-ов:

  •    Используйте read-only View Object-ы если не нужно обновлять или вставлять новые данные
  •    Для  View Object-ов которые используются только для  вставки данных, вы можете предотвратить ненужные запросы на выборку. Для этого установите параметр No Rows в Retrieve from the Database  на вкладке Overview)
  •    По возможности используйте динамическую генерацию SQL


Выполнение этих пунктов недостаточно, что бы всё "летало" :) . Но это те основы, за которыми нужно следить при разработке. Так же оптимизация должна выполняться на всех уровнях. Oracle по этому поводу написал целых 220 страниц :  https://docs.oracle.com/middleware/1213/core/ASPER.pdf

Вот еще ссылка с советами по performance от flexagon:https://flexagon.com/2015/07/tuning-best-practices-for-adf-applications/