Prestashop 1.5.3, впечатления
Категория: / DEV Блог
/ PHP (LAMP)
- печальная скорость работы
Под 200 запросов на рендер главной страницы - это многовато.
Например выборка брендов и товаров для них занимает порядочное количество времени, если
делать это с помощью средств встроенной ORM.
Пример времени выполнения главной страницы
с включенным файловым кэшем, отключенными сайдбарами и практически без модулей
Впринципе сойдет, до очередного обновления кэша.
- нет полноценного автолоада
Обращение к class_exists('неизвестный_class') вызывает переиндексацию дерева классов (встроенным автолоадером),
которая занимает 0.4 секунды за вызов. Отключить вызов автолоада можно передав второй параметр class_exists('', false)
- невозможно добавить дополнительное поле "изображение/файл" к объекту
Без применения напильника. Весь код заточен только под одну картинку,
как то отображение в форме, удаление.
- картинки конвертятся в jpg/png, совсем преобразование отключить нельзя.
Невозможно без костылей получить урл картинки. Нет метода getImageUrl или подобного.
каждый раз урл нужно получать складывая _PS_IMG_ . блабла . $object->id . 'default_small' . $imageType
Очень удобно.
Авторы престы почему то побрезговали сохранять метаданные о загруженных файлах в базу данных,
все что мы знаем о файле - это его размещение на диске.
- корявая реализация локализации
Кто придумал генерацию перевода через админку? Причем для ее работы должен предварительно
настраиваться сервер, т.к. каждое поле перевода отправляется элементом формы и запросто
срабатывает ограничение post.max_vars. Не проще ли править обычный (xml, ini, yml) файл в текстовом редакторе,
как в других фреймворках.
- нет возможности создать блок с custom html
Стандартная возможность любой cms в престашопе - продается! (wtf?40$)
По этому поводу я написал свою поделку
- печально с докуменацией и комментариями к коду
Минимум документации для разработчиков. Рассмотрены только самые базовые вещи.
В самом коде на комментарии тоже поскупились.
- нет развитого коммьюнити
На официальном форуме ответа не дождешься или он будет не совсем точным,
или вы уже все сделаете сами, перелопатив код десятка классов.
- работа файлового кэша неочевидна
Поддиректории для ключей автоматически не создаются, преста сохраняет ключи в поддиректории (первый символ идентификатора).
По-умолчанию созданы подпапки 0-9a-f, если вы желеаете сохранить объект в кэш с ключем, например, "super-cached-object",
вы удивитесь, но попытка закончится фейлом, так как поддиректории "s" не существует, и автоматически она не создастся,
и ошибки/исключения преста не выбросит, просто проглотит ошибку и продолжит делать свои грязные дела.
Плохая идея хранить все ключи в одном файле (/cache/cachefs/_/__keys__),
вместо того чтобы взять имя файла за идентификатор. Если вы не выставите права на запись для папок с кэшем,
и при этом включите файловый кэш, преста будет рендерить страницы по 8 секунд без единого сообщения о том,
что каждая попытка записи в файл закончена неудачей. При этом попыток сохранить данные будет около 200 за первый проход,
и в догонку после КАЖДОГО сохранения данных в кэш будет вызываться функция сохранения ключей (дополнительная запись в файл,
что не быстро).
Пример:
отлично видно - 4 вызова сохранения кэша создадут 200 мс накладных расходов
на сохранение ключей, которые можно было сохранять например в деструкторе.
- неудобное управление хуками и модулями
Обязательное добавление модуля в хук "хедера" чтобы он подтянул свои ассеты?
Про интерфейс управления хуками в админке лучше не вспоминать.
Пример скорости выполения хуков смотрите в приложении.
- хук вызванный через смарти {hook h="DisplayThisShit"} не подтянет нужные стили и скрипты,
если модули не добавлены в хеадер-хук
- невозможно вызвать модуль из шаблона
Почему нет аналога {hook}, например {module m="ShowText" id="TextForHome"}?
- неповоротливая система шаблонов.
Нет использования наследования шаблонов, попрежнему юзается старый добрый smarty capture.
Навигационная цепочка генерится в php коде, если вы хотите сверстать ее например при помощи списка ul-li,
извиняйте - здесь в шаблон передается уже полуготовая хтмл поделка
Жесткое навязывание сетки из трех колонок.
Дефолтный шаблон сущий ад для адаптации его под что-то другое.
Такие штуки какбы устарели :)
{if $hide_left_column}hide-left-column{/if}
{if $hide_right_column}hide-right-column{/if}
{if $content_only} content_only {/if}
Лейауты. В контроллере есть метод getLayout(), но нет setLayout(). Забавно правда?
- сортировка чего-либо кнопочками верх-вниз в админке - это АД!
Есть сотня плагинов jquery для удобной сортировки перетаскиванием.
Но нет же. Чтобы поднять объект на пять позиций вверх, нам нужно будет кликнуть пять раз кнопку "вверх",
каждый раз дожидаясь обновления страницы (а она порой не быстра) и вуаля - объект передвинут.
- еще про оптимизацию
Добавление в корзину одного и того же товара с разными атрибутами на странице оформления добавляет ~50 запросов к базе на один товар
Пример: в корзине 5 одинаковых товаров - запросов SQL: 350 --0.03337мс (Время скрипта: 0.3154мс), пустая корзина - запросов SQL: 63 --0.00660мс.
Пробуем включить файловый кэш. с товарами - SQL: 221 --0.06322мс (Время скрипта: 0.5174мс), пустая корзина SQL: 57 --0.04210мс
Оценили эффективность файлового кэширования?
Пробуем APC: SQL: 349 --0.03510мс (Время скрипта: 0.5712мс), вызывает стойкое ощущение, что APC не используется.
Пример выполнения страницы товара с дефолтным шаблоном (вызывыемые хуки-модули):
Под 200 запросов на рендер главной страницы - это многовато.
Например выборка брендов и товаров для них занимает порядочное количество времени, если
делать это с помощью средств встроенной ORM.
Пример времени выполнения главной страницы
с включенным файловым кэшем, отключенными сайдбарами и практически без модулей
[0.0000] Start
[0.0925] DispatcherCore::dispatch : IndexController
[0.1333] FrontControllerCore::initContent
[0.2011] INDEX IndexController::initContent
[0.2063] HomeSlider::hookDisplayHome
[0.2735] PSwidget text cached -- 0.00029 ttl 300
[0.2740] PSwidget index/brands cached -- 0.00032 ttl 300
[0.2750] Smarty: /themes/mytheme/layout-index.tpl -- 0.00666
[0.2751] Done
[0.2752] SQL 92 x 0.02554
Впринципе сойдет, до очередного обновления кэша.
- нет полноценного автолоада
Обращение к class_exists('неизвестный_class') вызывает переиндексацию дерева классов (встроенным автолоадером),
которая занимает 0.4 секунды за вызов. Отключить вызов автолоада можно передав второй параметр class_exists('', false)
- невозможно добавить дополнительное поле "изображение/файл" к объекту
Без применения напильника. Весь код заточен только под одну картинку,
как то отображение в форме, удаление.
- картинки конвертятся в jpg/png, совсем преобразование отключить нельзя.
Невозможно без костылей получить урл картинки. Нет метода getImageUrl или подобного.
каждый раз урл нужно получать складывая _PS_IMG_ . блабла . $object->id . 'default_small' . $imageType
Очень удобно.
Авторы престы почему то побрезговали сохранять метаданные о загруженных файлах в базу данных,
все что мы знаем о файле - это его размещение на диске.
- корявая реализация локализации
Кто придумал генерацию перевода через админку? Причем для ее работы должен предварительно
настраиваться сервер, т.к. каждое поле перевода отправляется элементом формы и запросто
срабатывает ограничение post.max_vars. Не проще ли править обычный (xml, ini, yml) файл в текстовом редакторе,
как в других фреймворках.
- нет возможности создать блок с custom html
Стандартная возможность любой cms в престашопе - продается! (wtf?40$)
По этому поводу я написал свою поделку
- печально с докуменацией и комментариями к коду
Минимум документации для разработчиков. Рассмотрены только самые базовые вещи.
В самом коде на комментарии тоже поскупились.
- нет развитого коммьюнити
На официальном форуме ответа не дождешься или он будет не совсем точным,
или вы уже все сделаете сами, перелопатив код десятка классов.
- работа файлового кэша неочевидна
Поддиректории для ключей автоматически не создаются, преста сохраняет ключи в поддиректории (первый символ идентификатора).
По-умолчанию созданы подпапки 0-9a-f, если вы желеаете сохранить объект в кэш с ключем, например, "super-cached-object",
вы удивитесь, но попытка закончится фейлом, так как поддиректории "s" не существует, и автоматически она не создастся,
и ошибки/исключения преста не выбросит, просто проглотит ошибку и продолжит делать свои грязные дела.
Плохая идея хранить все ключи в одном файле (/cache/cachefs/_/__keys__),
вместо того чтобы взять имя файла за идентификатор. Если вы не выставите права на запись для папок с кэшем,
и при этом включите файловый кэш, преста будет рендерить страницы по 8 секунд без единого сообщения о том,
что каждая попытка записи в файл закончена неудачей. При этом попыток сохранить данные будет около 200 за первый проход,
и в догонку после КАЖДОГО сохранения данных в кэш будет вызываться функция сохранения ключей (дополнительная запись в файл,
что не быстро).
Пример:
$cacher = Cache::getInstance();
$cacher->set('cache-test', '1', 10);
$cacher->set('cache-test', '1', 10);
$cacher->set('cache-test', '1', 10);
$cacher->set('cache-test', '1', 10);
[0.5096] CacheFS::_set - save KEYS : 0.05055
[0.5636] CacheFS::_set - save KEYS : 0.05147
[0.6177] CacheFS::_set - save KEYS : 0.05152
[0.6845] CacheFS::_set - save KEYS : 0.05108
отлично видно - 4 вызова сохранения кэша создадут 200 мс накладных расходов
на сохранение ключей, которые можно было сохранять например в деструкторе.
- неудобное управление хуками и модулями
Обязательное добавление модуля в хук "хедера" чтобы он подтянул свои ассеты?
Про интерфейс управления хуками в админке лучше не вспоминать.
Пример скорости выполения хуков смотрите в приложении.
- хук вызванный через смарти {hook h="DisplayThisShit"} не подтянет нужные стили и скрипты,
если модули не добавлены в хеадер-хук
- невозможно вызвать модуль из шаблона
Почему нет аналога {hook}, например {module m="ShowText" id="TextForHome"}?
- неповоротливая система шаблонов.
Нет использования наследования шаблонов, попрежнему юзается старый добрый smarty capture.
Навигационная цепочка генерится в php коде, если вы хотите сверстать ее например при помощи списка ul-li,
извиняйте - здесь в шаблон передается уже полуготовая хтмл поделка
Жесткое навязывание сетки из трех колонок.
Дефолтный шаблон сущий ад для адаптации его под что-то другое.
Такие штуки какбы устарели :)
{if $hide_left_column}hide-left-column{/if}
{if $hide_right_column}hide-right-column{/if}
{if $content_only} content_only {/if}
Лейауты. В контроллере есть метод getLayout(), но нет setLayout(). Забавно правда?
- сортировка чего-либо кнопочками верх-вниз в админке - это АД!
Есть сотня плагинов jquery для удобной сортировки перетаскиванием.
Но нет же. Чтобы поднять объект на пять позиций вверх, нам нужно будет кликнуть пять раз кнопку "вверх",
каждый раз дожидаясь обновления страницы (а она порой не быстра) и вуаля - объект передвинут.
- еще про оптимизацию
Добавление в корзину одного и того же товара с разными атрибутами на странице оформления добавляет ~50 запросов к базе на один товар
Пример: в корзине 5 одинаковых товаров - запросов SQL: 350 --0.03337мс (Время скрипта: 0.3154мс), пустая корзина - запросов SQL: 63 --0.00660мс.
Пробуем включить файловый кэш. с товарами - SQL: 221 --0.06322мс (Время скрипта: 0.5174мс), пустая корзина SQL: 57 --0.04210мс
Оценили эффективность файлового кэширования?
Пробуем APC: SQL: 349 --0.03510мс (Время скрипта: 0.5712мс), вызывает стойкое ощущение, что APC не используется.
Пример выполнения страницы товара с дефолтным шаблоном (вызывыемые хуки-модули):
[0.3400] DispatcherCore::dispatch : ProductController
[0.4859] HOOK HookCore::exec - displayHeader -- 0.06084
[0.4860] .. BlockBestSellers::hookdisplayHeader - 0.00021
[0.4861] .. BlockPaymentLogo::hookdisplayHeader - 0.00011
[0.4862] .. BlockPermanentLinks::hookdisplayHeader - 0.00017
[0.4863] .. BlockViewed::hookdisplayHeader - 0.00015
[0.4864] .. BlockCart::hookdisplayHeader - 0.00033
[0.4865] .. Blockcontact::hookdisplayHeader - 0.00015
[0.4866] .. blocksocial::hookdisplayHeader - 0.00010
[0.4867] .. BlockMyAccount::hookdisplayHeader - 0.00010
[0.4869] .. Blockcustomerprivacy::hookdisplayHeader - 0.00012
[0.4869] .. BlockCategories::hookdisplayHeader - 0.00029
[0.4871] .. BlockSpecials::hookdisplayHeader - 0.00017
[0.4872] .. BlockCurrencies::hookdisplayHeader - 0.00016
[0.4873] .. Blockmyaccountfooter::hookdisplayHeader - 0.00016
[0.4874] .. BlockNewProducts::hookdisplayHeader - 0.00015
[0.4875] .. BlockUserInfo::hookdisplayHeader - 0.00017
[0.4876] .. BlockLanguages::hookdisplayHeader - 0.00016
[0.4877] .. BlockManufacturer::hookdisplayHeader - 0.00013
[0.4878] .. BlockCms::hookdisplayHeader - 0.00011
[0.4879] .. BlockTags::hookdisplayHeader - 0.00017
[0.4880] .. BlockStore::hookdisplayHeader - 0.00010
[0.4881] .. BlockSearch::hookdisplayHeader - 0.00142
[0.4882] .. Blockcontactinfos::hookdisplayHeader - 0.00010
[0.4883] .. FavoriteProducts::hookdisplayHeader - 0.00209
[0.4884] .. HomeFeatured::hookdisplayHeader - 0.00016
[0.4885] .. Blocknewsletter::hookdisplayHeader - 0.00017
[0.4886] .. BlockSupplier::hookdisplayHeader - 0.00010
[0.4887] .. Feeder::hookdisplayHeader - 0.00259
[0.5141] HOOK HookCore::exec - displayTop -- 0.02522
[0.5142] .. BlockLanguages::hookdisplayTop - 0.00203
[0.5144] .. BlockCurrencies::hookdisplayTop - 0.00146
[0.5145] .. BlockPermanentLinks::hookdisplayTop - 0.00141
[0.5146] .. BlockSearch::hookdisplayTop - 0.00250
[0.5148] .. BlockUserInfo::hookdisplayTop - 0.00156
[0.5149] .. Blocktopmenu::hookdisplayTop - 0.00190
[0.5150] .. SEKeywords::hookdisplayTop - 0.00000
[0.5152] .. BlockCart::hookdisplayTop - 0.00461
[0.5153] .. Pagesnotfound::hookdisplayTop - 0.00002
[0.5437] HOOK HookCore::exec - displayLeftColumn -- 0.02831
[0.5439] .. BlockTags::hookdisplayLeftColumn - 0.00212
[0.5440] .. BlockCategories::hookdisplayLeftColumn - 0.00150
[0.5441] .. BlockViewed::hookdisplayLeftColumn - 0.00428
[0.5443] .. BlockManufacturer::hookdisplayLeftColumn - 0.00361
[0.5444] .. BlockSupplier::hookdisplayLeftColumn - 0.00381
[0.5445] .. BlockCms::hookdisplayLeftColumn - 0.00821
[0.5446] .. BlockAdvertising::hookdisplayLeftColumn - 0.00104
[0.5448] .. BlockPaymentLogo::hookdisplayLeftColumn - 0.00001
[0.5449] .. Blocknewsletter::hookdisplayLeftColumn - 0.00135
[0.5754] HOOK HookCore::exec - displayRightColumn -- 0.03035
[0.5755] .. BlockBestSellers::hookdisplayRightColumn - 0.00168
[0.5757] .. BlockNewProducts::hookdisplayRightColumn - 0.01812
[0.5758] .. BlockSpecials::hookdisplayRightColumn - 0.00696
[0.5760] .. BlockCms::hookdisplayRightColumn - 0.00032
[0.5761] .. BlockStore::hookdisplayRightColumn - 0.00154
[0.5762] .. Blockcontact::hookdisplayRightColumn - 0.00140
[0.5896] HOOK HookCore::exec - displayLeftColumnProduct -- 0.00664
[0.5898] .. blocksharefb::hookdisplayLeftColumnProduct - 0.00256
[0.5899] .. FavoriteProducts::hookdisplayLeftColumnProduct - 0.00228
[0.5980] HOOK HookCore::exec - displayMyAccountBlock -- 0.00181
[0.5981] .. FavoriteProducts::hookdisplayMyAccountBlock - 0.00162
[0.6116] HOOK HookCore::exec - displayFooter -- 0.02142
[0.6118] .. Blockreinsurance::hookdisplayFooter - 0.00156
[0.6119] .. BlockCategories::hookdisplayFooter - 0.00149
[0.6121] .. Blockmyaccountfooter::hookdisplayFooter - 0.00395
[0.6122] .. BlockCms::hookdisplayFooter - 0.00140
[0.6124] .. blocksocial::hookdisplayFooter - 0.00142
[0.6125] .. Blockcontactinfos::hookdisplayFooter - 0.00226
[0.6126] .. StatsData::hookdisplayFooter - 0.00453
[0.6245] Smarty: /themes/mytheme/product.tpl -- 0.00876
[0.6276] Smarty: /themes/mytheme/layout.tpl -- 0.00293
[0.6278] Done
По многим пунктам все предельно ясно: Разработчики зарабатывают на допиливании базовых функуций. + продажа шаблонов, +обучение (дорогое пипец... около 700€ за 8 часовую обучаловку)
Комьюнити примерно такое же, никто не хочет работать бесплатно. (сам такой)
Это не полноценный опен сорс, просто часть того что реализована в паблике, отсальное дорого и долго, нормальных спецов мало, по причине кривости самой престы, там много АДа потому хорошие разрабы не любят работать с престой.
Но пока что нет другого аналога по количеству реализованных (хоть и криво) фичь которых представлены в престе.
Большинство из бесплатных модулей кривые, созданы целенаправлено авторами что бы обращались к ним за допиливанием.
Громадный плюс в том что с нуля за несколько часов у вас готовый магазин для продажи чего угодно... от цифровых продуктов до просто красивого каталога вместо магазина.