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 - вещи вполне совместимые -).

8 Responses to “CakePHP - проблема производительности requestAction”

  1. Hellboton 26 Apr 2007 at 7:32 pm

    И до полного ощущения счастья от requestAction
    http://www.soledadpenades.com/2006/11/13/beware-of-cakephps-requestaction/
    “Каждый requestAction тянет за собой вызов Sessions, если конечно им пользуются, что при способе хранения сессий database приводит к дополнительным запросам к базе.”

  2. djviruson 27 Apr 2007 at 9:18 am

    Сессии не причём, да и вообще, запросы к БД, много времени не занимают по сравнению с requestAction.
    Дабы опровергнуть твоё предположение, провёл небольшой бенчмарк. Засёк время генерации главного меню:
    ~175 ms - requestAction c php-сессиями
    ~183 ms - requestAction c database-сессиями
    как видишь, разница не большая.

  3. Hellboton 29 Apr 2007 at 7:13 pm

    Для меня старт сессий вход в полную инициализацию контроллера. Помимо того что она и так не очень быстрая, согласно твоему мнению, так по и сессии мы инициализируем дополнительно на каждый вызов requestAction. Помимо дополнительных накладных расходов на доступ к БД, файлам (session_invalidate, session_start) и дублированию header, чудо PHP, добавляет ко всем ссылкам переменную ? = , чем, зараза такая, портит мне жизнь.

    И если с потерей времени на инициализацию я готов еще смирится (стоимость целостности и удобства программирования), то на дополнительную инициализацию, казалось бы, глобальных обьектов - я обижен ужасно :)

  4. VolChon 04 Nov 2007 at 10:31 pm

    Вместо этого подготавливайте данный в AppController-е (constructClasses и beforeRender), ну а в шаблоне - пользуйте renderElement. Не так красиво, зато гарантированно без тормозов, хотя тормоза и CakePHP - вещи вполне совместимые -).

    Ну я использую requestAction в элементах. Готовить данные для элемента в контроллере, а, тем более, в апконтроллере, имхо, не есть гуд. если что-то менять надо будет, то кучу изменений вносить в коде надо будет, а если блок выводится не всегда, то в пустую для него данные готовиться будут

    Как вариант можно разбивать функциональность на компоненты (подготовка данных) и жлемены (их вывод)

  5. djviruson 05 Nov 2007 at 10:20 am

    requestAction - это просто супер-удобный механизм, просто возможно реализован кривовато.
    Есть подозрение, что это может быть даже только на винде проблема. То что у меня на машине генерится полторы секунды, на серваке выплювывается моментально!
    Осмелюсь предположить, что это либо вина самого пхп, либо кеш операционной системы у линукса работает эффективнее…

  6. Антон Чon 30 Dec 2007 at 4:43 am

    djvirus, php тут вряд ли при чем то =)
    а за заметку спасибо

  7. Johanon 24 Feb 2008 at 7:56 am

    Все правильно .. у меня из-за реквесткэшн .. иногда даже проект не запускался … настолько он вешал систему .. причём запускал я на продакшн .. хостер не давал выполняться так долго … все экшены требовали работы с бд .. и в результате .. у меня страница не отвечала … решение с Элементами на самом деле красивое … я его сейчас только и использую .. главное привыкнуть.

  8. Экстремалon 11 Sep 2008 at 2:03 pm

    тоже намучился с этой жестью

Trackback URI | Comments RSS

Leave a Reply