А разве Drupal при каждой загрузке страницы инклюдит главные файлы всех активных модулей?

Главные вкладки

Аватар пользователя Murz Murz 29 августа 2007 в 16:41

При разработке модулей заметил что если сделаю ошибку в php в файле *.module какого-то модуля, то перестают работать и страницы других модулей, которые данной странице впринципе даже и не требуются.

Если логически помыслить, то получается что Drupal при загрузке каждой страницы инклюдит кучу лишних файлов? Как-то нецелесообразно это по-моему. А если модулей куча и у половины огромные исходники, то вообще тормоза страшные наступят!

По-моему правильнее инклюдить файлы только тех модулей, у которых есть функции hook_init() и другие, которые при загрузке странице должны подгружаться.

Также в Drupal 6 фукнция hook_menu() по-моему при вызове функции menu_rebuild кешируется в базе и каждый раз подгружать её исходники тоже не нужно. А тут получается что Drupal ещё и её тоже парсит.

Drupal итак уже "небыстрый", в результате на все эти излишки как-то неприятно смотреть Sad

У кого какие мысли по этому поводу?

Комментарии

Аватар пользователя ultraboy@drupal.org ultraboy@drupal.org 29 августа 2007 в 17:06

Это Вам на форум ДО с такими измышлениями))) Или, еще лучше, на IRC. Там все растолкуют)

На самом деле, думаю что без этого сложно обойтись... Или же можно, но очень сложно реализовать, раз еще не сделали. Например, ХУК_МЕНЮ бывает и динамическим, это уже не прокешируешь.

Скорее всего тебе ответят: "Ты давай сделай патч, ну а мы уж его посмотрим..." Smile

Аватар пользователя edhel edhel 29 августа 2007 в 19:33

Кроме хуков menu и init еще куча хуков! Если сделать так как Вы говорите, потеряется ~80% функциональности.

1) Например, модуль taxonomy при отображении нод подгружает термины. Если taxonomy не подгрузить, то ссылки на термины пропадут.

2) В любом модуле может быть объявлен блок (block), причем его содержимое может зависеть от текущей страницы. Если перестать грузить "лишние" модули, то все блоки пропадут.

3) Я, к примеру, использую модуль, которые удаляет ссылки на категории у определенных типов публикаций. Если его не грузить, то что из этого выйдет??

Чтобы пхп меньше нагружать - можно производить оптимизацию на уровне самого модуля. Например, основа модуля cck (файл content.module) весит 35 кб, а дополнительный код для администрирования 55 кб и он лежит в отдельном файле content_admin.inc и инклюдится только когда нужен.

ЗЫ: Без php-опмтимизаторов Drupal тормоз имхо. Особенно по мере обрастания модулями и контентом.

Аватар пользователя Murz Murz 30 августа 2007 в 8:52

edhel says: Кроме хуков menu и init еще куча хуков! Если сделать так как Вы говорите, потеряется ~80% функциональности.
Если просто перестать инклюдить файлы, то конешно потеряется Smile По-правильному-то надо сначала посмотреть, что стоит инклюдить а что нет (например в момент установки), а потом уже инклюдить только то что надо. Ведь многие модули не использует никаких хуков и блоков, а работу друпала тормозят.

edhel says: Чтобы пхп меньше нагружать - можно производить оптимизацию на уровне самого модуля.
Как я заметил такую подставу - сразу же лишний код из своих модулей вынес в inc-файлы Wink Ещё задумался вот куда вынести довольно-таки объемный код меню, который используется только при обновлении кеша меню, но пока не нашёл куда Wink Но посмотрел на остальные модули - не все так основательно подходят к оптимизации кода. Моих-то модулей 1-2-10 на сайте, а остальных - значительно больше, поэтому тормоза по большей части происходят к сожалению не из-за меня Wink

edhel says: ЗЫ: Без php-опмтимизаторов Drupal тормоз имхо. Особенно по мере обрастания модулями и контентом.
Оптимизаторы конешно рулят, но к сожалению не на всех хостингах они установлены. Да и оптимизаторы впринципе-то не устраняю проблемы, а просто снижают её значимость Wink Для ускорения подгрузки файлов можно докупить на сервер оперативной памяти, закешировать все файлы в ней и всё будет работать быстро и шустро. Но на сервере обычно не один сайт, а целый вагон, на каждый сайт ресурсами не запасёшься. Поэтому имхо более правильный путь - оптимизация самой CMS, а не прикручивание всяких оптимизаторов.

Аватар пользователя axel axel 29 августа 2007 в 21:48

Да, при полной загрузке (в той фазе где подгружается module.inc) подключаются главные файлы всех модулей, чтобы выяснить какие обработчики они предлагают. Если установлен php-акселератор, то это не критично - инклюды кешируются им и их загрузка является очень быстрой.

Возможная альтернатива загрузке файлов: модуль при регистрации публикует список предлагаемых им обработчиков и затем этот список сохраняется в базе и берётся оттуда, обновляясь только при подключении/отключении модулей (примерно как это сделано уже с обработчиками меню). Насколько это быстрей загрузки файлов (учитывая кешироание php-акселератором) - это надо тестить, я бы не стал делать умозрительных заключений сходу. Теоретически препятствий в друпаловской архитектуре такой реализации нет, но очевидно код модулей в таком случае придётся конкретно переписывать. С точки зрения PHP и экономии памяти удобней делать главный файл состоящий из одних объявлений функций, в которых реализация подключается из отдельных файлов, но в друпале сейчас ничего не препятствует написанию всего кода (кроме вынесенных отдельно процедур инсталляции) в одном файле.

Аватар пользователя Murz Murz 30 августа 2007 в 7:58

axel says: Возможная альтернатива загрузке файлов: модуль при регистрации публикует список предлагаемых им обработчиков и затем этот список сохраняется в базе и берётся оттуда, обновляясь только при подключении/отключении модулей (примерно как это сделано уже с обработчиками меню). Насколько это быстрей загрузки файлов (учитывая кешироание php-акселератором) - это надо тестить, я бы не стал делать умозрительных заключений сходу.
Ну так в базе уже прописан список активных модулей и при загрузке страницы он выбирается. Просто добавить в эту таблицу поле, где поставить галочки нужно ли подгружать этот файл каждый раз (по наличию в нем хуков, инитов и других функций для вызова при каждой загрузке) или нет. Правда для этого придется парсить весь код модуля и смотреть что там есть а чего нет, но это ведь только 1 раз при установке, а зато какой прирост в производительности!

Аватар пользователя edhel edhel 29 августа 2007 в 22:00

Это скорее проблема ПХП, чем Друпал... Вот бы интересно было бы погонять что нить типа JDrupal (на яве)

Аватар пользователя Murz Murz 30 августа 2007 в 8:07

edhel says: Это скорее проблема ПХП, чем Друпал... Вот бы интересно было бы погонять что нить типа JDrupal (на яве)
Да, ява штука интересная. Насколько я понял - там всё подгружается сразу и ждёт пока пользователь запросит страницу, а потом не выгружается а висит в памяти и ждёт следующего запроса. А остальное всё подгружается по мере надобности. Очень по-моему правильное решение. Правда бросать php и переходить на жаву как-то жалко и боязно.

axel says: Хочу PyDrupal Smile
А разьве в Python дела обстоят по-другому? По-моему это тоже интерпретатор, который работат таким же образом как и php.

Аватар пользователя axel axel 5 сентября 2007 в 15:30

Интерпретатор интерпретатору рознь ) В Python возможности построения разных моделей работы шире. Например легко сделать демона, который будет слушать запросы пришедшие от вебсервера и разруливать их по своим процессам (отдельно например используя пул persistent connections к бд) - при этом код будет постоянно подгружен в памяти, как в упомянутом здесь примере на Java. Нет проблем с namespaces (точнее это в PHP их нет, потому как нет пространств имен вообще, обещались в PHP6 реализовать) - в питоне не надо изобретать хитрые имена modulename_functionname, а можно импортировать модуль modulename в собственное или общее пространство имён и использовать его функции. Программы как в яве предкомпилируются в байт-код, что ускоряет повторную загрузку (то что в PHP делаетс отдельным акселератором). Широкие возможности ООП (ок, в PHP5 ситуацию улучшили), есть элементы функционального программирования (в php тож есть lambda-функции, но в весьма ограниченной реализации). Поддержка юникода в питоне во всех функциях (внутри интерпретатора вообще UTF-16, для вывода преобразуется в UTF-8 или другие кодировки), а не только в части функций предоставляемых отдельным расширением как в PHP. Список можно продолжать...

Аватар пользователя Murz Murz 5 сентября 2007 в 16:51

axel says:
Интерпретатор интерпретатору рознь ) В Python возможности построения разных моделей работы шире.

Эх, как прочитал прям сразу захотелось изменить PHP с Питоном Wink Только вот странно, почему он так мало распространен раз в нём всё так прекрасно? И синтаксис у него вроде бы немного странноватый, чем-то мне вижуалвасик напоминает Wink Тяжело с PHP будет переучиваться.... и гибкости нету в написании ;(

Аватар пользователя axel axel 5 сентября 2007 в 18:23

Мало распространён? Smile Вебскриптов на PHP несомненно больше всего, но остальные языки сбрасывать со счетов не стоит. Тем более питон это язык общего назначения, не завязанный так сильно на веб, как php. Вот несколько примеров проектов на питоне:

  • zope - сервер приложений
  • plone - cmf/cms
  • bzr - система управления версиями
  • mailman - сервер почтовых рассылок
  • скриптовая поддержка во многих программах и средах, например в OpenOffice, KDE, Gnumeric, Gimp, Vim...
  • вообще см. список на http://ru.wikipedia.org/wiki/Python

Вообще в юниксе питона гораздо больше, чем в виндовс. К примеру в линуксе он весьма активно используется в разных сервисных скриптах. Например в Gentoo Linux на питоне работает portage - система управления установкой программ. Поскольку это я/п общего назначения, к нему есть библиотеки для построения GUI или работы с графикой: PyQt, PyGTK, PyOpenGL, PyGame и т.д., математические пакеты для инженерных вычислений и т.п. При этом язык удобен для веба - через fastcgi питоновские скрипты могут работать быстро, под апач есть ещё mod_python (действующий по аналогии с mod_php).

Почему же тогда PHP более распространён? Вероятно потому же, почему Windows - лидер на десктопах. Просто так исторически сложилось Wink

Новичков обычно отпугивает странный синтаксис. Особенно жёсткая необходимость отступов. Т.е. от глубины отступов зависит вложенность операторов Lol Странно, но во-первых программы приятней читать (всё в строку не напишешь), во-вторых экономит на написании лишних операторов и открывающих/закрывающих скобок Smile Во времена бумажных листингов распечатка питоновской программы вероятно могла быть проблемой, но сейчас это неактуально - поддержка работы с питоном есть в программерских редакторах, поэтому неудобств с набором не возникает.

До кучи отмечу, что питон поддерживается на многих платформах (тут он может поспорить с Java) - от мобилок на симбиане и КПК до мейнфремов.

Аватар пользователя edhel edhel 30 августа 2007 в 8:54

Ну так в базе уже прописан список активных модулей и при загрузке страницы он выбирается. Просто добавить в эту таблицу поле, где поставить галочки нужно ли подгружать этот файл каждый раз (по наличию в нем хуков, инитов и других функций для вызова при каждой загрузке) или нет. Правда для этого придется парсить весь код модуля и смотреть что там есть а чего нет, но это ведь только 1 раз при установке, а зато какой прирост в производительности!

Всё у Вас так просто!) Если есть хук nodeapi в модуле и он что то делает, к примеру, со story. В каком случае грузить такой модуль? При просмотре страницы типа page грузить вроде и не надо? Но для этого надо анализировать код nodeapi! Это нереально. Вывод: если есть хук nodeapi, то при любой работе с нодой - надо его грузить.

А если есть хук menu или block? Они могут динамически создавать пункты меню и блоки (в зависимости от текущей страницы, роли, времени, погоды). Когда их грузить? Чтобы все работало - всегда придется грузить!

Короче имхо: очень мало случаев, когда не надо грузить модули. Например, если в модуле только 1 хук form_alter и на странице нету форм - тогда можно и не грузить... Если есть форма поиска - то уже на каждой странице придется грузить и такой модуль.

PS: Ява всё держит в памяти, как и обычная программа (не веб). При первом использовании библиотеки (класса) - загружает и уже не выгружает ее. Парсится всё на этапе "компиляции". На этапе выполнения еще может и компилироваться. Вообще java/jsp просто летает... и можно не бояться ставить всё новые и новые библиотеки, на производительность не влияют, только на память.

Аватар пользователя Murz Murz 30 августа 2007 в 13:41

PS: Ява всё держит в памяти, как и обычная программа (не веб). При первом использовании библиотеки (класса) - загружает и уже не выгружает ее. Парсится всё на этапе "компиляции". На этапе выполнения еще может и компилироваться. Вообще java/jsp просто летает... и можно не бояться ставить всё новые и новые библиотеки, на производительность не влияют, только на память.
Эх, прикольно сделано! Нагрузка на сервер при таком подходе в разы меньше должна получаться. Я вот всё думал как бы это с помощью php сделать, чтобы каждый раз не подгружалось и генерилось всё с нуля, но кроме увеличения параметров кеширования больше ничего не придумалось ;(

Аватар пользователя edhel edhel 30 августа 2007 в 8:59

ведь многие модули не использует никаких хуков и блоков, а работу друпала тормозят.

Ниасилил... Что за модули без хуков???

Поэтому имхо более правильный путь - оптимизация самой CMS, а не прикручивание всяких оптимизаторов.

По мере роста функциональности и, соответственно, кода, архитектура PHP даёт о себе знать... Имхо без предкомпиляции оптимизаторами тут не обойтись.

лишний код из своих модулей вынес в inc-файлы

Дробить файл из 20 кб на 10 по 2 кб - только в убыток может оказаться. То бишь перебарщивать не надо.

Аватар пользователя Murz Murz 30 августа 2007 в 13:57

Ниасилил... Что за модули без хуков???
Мой, например, модуль Wink У него только хук меню висит, а в остальном он сам ковыряется в собственных таблицах и файлах. Некоторые другие специализированные модули, я думаю, тоже так работают. Некоторым конешно не обойтись без хуков, но не всем они в работе требуются.

Всё у Вас так просто!) Если есть хук nodeapi в модуле и он что то делает, к примеру, со story. В каком случае грузить такой модуль? При просмотре страницы типа page грузить вроде и не надо? Но для этого надо анализировать код nodeapi! Это нереально. Вывод: если есть хук nodeapi, то при любой работе с нодой - надо его грузить.
Можно тогда дать администратору выбор - ставить галки какие модули подгружать а какие нет. Например модуль форума uieforum у меня на сайте используется только когда в него заходишь, никаких блоков на остальных страницах не выведено. Основные заходы идут не на форум а на контент сайта, на форум заходят очень редко, но всё же заходят, поэтому его не уберешь совсем. И в итоге получается что модуль форума (размер uieforum.module - 91 килобайт) подгружается и парсится практически впустую.

Дробить файл из 20 кб на 10 по 2 кб - только в убыток может оказаться. То бишь перебарщивать не надо.
Ну это-то понятно, во всех делах главное не переусердствовать Wink
Я из главного модуля вынес все функции, которые работают только внутри модуля, в отдельные файлы и указываю файл, в котором находится функция, прямо в меню - получается очень ресурсоэкономично Smile

Аватар пользователя edhel edhel 30 августа 2007 в 14:37

Если uieforum.module не подгружать, то и uieforum форум работать не будет.. Т.е. надо задавать правила - на каких страницах какие модули грузятся, на каких не грузятся, нужно разбираться во всех модулях и их адресах... Чем больше сайт и больше модулей - тем сложнее эти правила поддерживать будет.

Проще раз модуль нормально написать с нормальными include-ами... А в идеале всё-таки пхп-оптимизатор)

Аватар пользователя dimanjy dimanjy 5 сентября 2007 в 13:23

Вот, кстати, идейка про Java-like PHP. На грани маразма, но все-таки:
Есть PHP-демон, который все время загружен и слушает HTTP-запросы на каком-нибудь 8181-порту. Веб-сервер проксирует на него все запросы. А сам демон - ни что иное как адаптированный движок Drupal, который все, что требуется, подгружает сразу в память и больше не выгружает, т.к. он - демон.
Как мысль? Завалится такая конструкция или жить будет?

Аватар пользователя leshov leshov 5 сентября 2007 в 18:50

Для анонимных пользователей есть галочка "агрессивное кэширование" -- отключает загрузку модулей

-----
if (variable_get('cache', CACHE_DISABLED) == CACHE_AGGRESSIVE) {
drupal_page_cache_header($cache);
exit();
}

-----

Для питона список можно дополнить еще одним популярным фреймворком -- django.