Apr 11th, 2007
CakePHP - проблема производительности requestAction
requestAction - это метод базового класса Object в CakePHP, задумывался разработчиками с целью повышения гибкости, особенно в ajax-приложениях. С помощью requestAction можно инициировать GET-запрос аналогичный запросу через HTTP, получить и вывести результат. Самый простой пример использования requestAction - это блок последних новостей в главном шаблоне:
<?=$this->requestAction(’/news/latest/’)?>
При этом функциональность выборки последних записей инкапсулируется в контроллер news и шаблон блока лежит рядом шаблонами модуля новостей - очень удобно при интеграции и переноси модуля новостей в другие проекты.
Однако есть одна очень неприятная особенность которую разработчики CakePHP пока ещё не решили. requestAction заново инициирует полный цикл создания объектной модели (диспечера, обработки правил роутера, контроллера и т.д.). В результате на каждый requestAction уходит 150-200мс (это без учёта времени SQL-запросов). У меня в проекте получилоь: верхнее меню + нижнее меню + список категорий + архив календарь + 3 блока баннеров + последние новости. Итого время герерации простой страницы около 1.5 сек!!! (на простой машине, на двухядерном сервере немного быстрее).
Как так можно? Зачем разработчики CakePHP и в группах Google рекомендуют использовать requestAction. Почему в документации не описан такой важный момент?
Я практически полностью отказался от requestAction и не рекомендую использовать её в простых задачах, если не хотите, чтобы хостер забанил ваш сайт после того как по нему пройдётся Google-робот.
Вместо этого подготавливайте данный в AppController-е (constructClasses и beforeRender), ну а в шаблоне - пользуйте renderElement. Не так красиво, зато гарантированно без тормозов, хотя тормоза и CakePHP - вещи вполне совместимые -).
И до полного ощущения счастья от requestAction
http://www.soledadpenades.com/2006/11/13/beware-of-cakephps-requestaction/
“Каждый requestAction тянет за собой вызов Sessions, если конечно им пользуются, что при способе хранения сессий database приводит к дополнительным запросам к базе.”
Сессии не причём, да и вообще, запросы к БД, много времени не занимают по сравнению с requestAction.
Дабы опровергнуть твоё предположение, провёл небольшой бенчмарк. Засёк время генерации главного меню:
~175 ms - requestAction c php-сессиями
~183 ms - requestAction c database-сессиями
как видишь, разница не большая.
Для меня старт сессий вход в полную инициализацию контроллера. Помимо того что она и так не очень быстрая, согласно твоему мнению, так по и сессии мы инициализируем дополнительно на каждый вызов requestAction. Помимо дополнительных накладных расходов на доступ к БД, файлам (session_invalidate, session_start) и дублированию header, чудо PHP, добавляет ко всем ссылкам переменную ? = , чем, зараза такая, портит мне жизнь.
И если с потерей времени на инициализацию я готов еще смирится (стоимость целостности и удобства программирования), то на дополнительную инициализацию, казалось бы, глобальных обьектов - я обижен ужасно
Ну я использую requestAction в элементах. Готовить данные для элемента в контроллере, а, тем более, в апконтроллере, имхо, не есть гуд. если что-то менять надо будет, то кучу изменений вносить в коде надо будет, а если блок выводится не всегда, то в пустую для него данные готовиться будут
Как вариант можно разбивать функциональность на компоненты (подготовка данных) и жлемены (их вывод)
requestAction - это просто супер-удобный механизм, просто возможно реализован кривовато.
Есть подозрение, что это может быть даже только на винде проблема. То что у меня на машине генерится полторы секунды, на серваке выплювывается моментально!
Осмелюсь предположить, что это либо вина самого пхп, либо кеш операционной системы у линукса работает эффективнее…
djvirus, php тут вряд ли при чем то =)
а за заметку спасибо
Все правильно .. у меня из-за реквесткэшн .. иногда даже проект не запускался … настолько он вешал систему .. причём запускал я на продакшн .. хостер не давал выполняться так долго … все экшены требовали работы с бд .. и в результате .. у меня страница не отвечала … решение с Элементами на самом деле красивое … я его сейчас только и использую .. главное привыкнуть.
тоже намучился с этой жестью