Full-stack web developer, love Open Source
21,0
рейтинг
15 января в 19:54

Разработка → Cобрать лучшее из двух миров — фреймворков и CMS (часть 3)

Прошло уже много времени с выхода второй статьи (часть 1, часть 2), а тут как раз есть что рассказать, так как вышел первый релиз третьей версии системы.

Вкратце об изменениях


Третья версия понемногу двигается в направлении микроядерной архитектуры. Это значит что код ядра всё так же достаточно сильно связан (хотя немного меньше чем до этого), некоторые второстепенные фичи были попросту удалены и появилось больше точек соприкосновения, где разработчик может при необходимости вклиниться в работу системы если он того желает.

На стороне сервера был проведен масштабный рефакторинг нацеленный на простоту и качество кода, что за последние пол года вылилось в повышение оценки Scrutinizer с 5.4 или что-то около того до текущих 7.74/10, что уже совсем неплохо.
На стороне клиента произошла революция, Polymer 0.5.x был обновлен до Polymer 1.x и все компоненты были соответственно переписаны, ещё был полностью выпилен UI фреймворк и некоторые другие изменения.

Polymer


Пожалуй, стоит начать с Polymer. На Google I/O 2015 была анонсирована первая стабильная версия Polymer 1.0, которая весьма существенно, хоть и не радикально отличается от версии 0.5, используемой в CleverStyle CMS на тот момент.
К сожалению, первая версия была достаточно кривой с большим количеством неудобств, и даже версия 1.1 не сильно это исправила.

CleverStyle CMS 3 поставляется с Polymer 1.2 и рядом патчей поверх, которые исправляют многие неровности в работе библиотеки, а так же вносят некоторые удобства. Многие из ранних патчей уже приняты в кодовую базу Polymer, но не все.
Так же для более быстрой загрузки сборка Polymer поставляемая с системой являет собой минифиицированную JS версию вместо набора официальных неминифицированных HTML файлов.
Таким образом Polymer в составе системы является гораздо лучшей средой для разработки чем ванильная версия.
Патчи поверх Polymer протестированные и обратно совместимые, так что проблем при использовании собственных или сторонних компонентов не будет (на момент написания статьи я вхожу в топ-10 разработчиков Polymer по вкладу в кодовую базу, так что я знаю о чём говорю).

К примеру:

// Before
Polymer({
    is         : 'my-element',
    properties : {
        username   : {
            type  : String,
            value : 'Guest'
        },
        registered : {
            type  : Boolean,
            value : false
        }
    }
});
// After
Polymer({
    is         : 'my-element',
    properties : {
        username   : 'Guest',
        registered : false
    }
});

То есть имея значение по умолчанию нет никакой проблемы вывести тип свойства, но разработчики никак не примут соответствующий PR, хотя это у них P1.

Или пример касающийся стилей:

// Before
:host ::content div {}
// After
::content div {}

Мелочь, но приятно что этот костыль больше не нужен (это проблема в Polymer, по спецификации :host там не нужен), PR тоже ожидает своего часа.

Последнее что стоит упомянуть — так это то, что Polymer 1.x на момент написания статьи не поддерживает расширение пользовательских элементов, но хак с переопределением элементов всё же был портирован и позволяет разработчику полностью или частично переопределять внешний вид и устройство встроенных системных и любых других пользовательских элементов. Подробнее с примерами в документации.

TinyMCE и Shadow DOM



Полноценные WYSIWYG редакторы это большие и сложные приложения и ни одно из популярных решений не поддерживает работу внутри Shadow DOM по причине сложности реализации и поддержки (на момент написания статьи, хотя судя по инициативности разработчиков это ещё долгое время будет актуально).

Проведя несколько дней в дебрях мегабайтов JavaScript кода и пошаговом отладчике браузера мне удалось получить обратно совместимую версию TinyMCE, которая полноценно работает внутри теневого дерева.
На сколько мне известно — это первая в мире реализация полнофункционального WYSIWYG редактора с поддержкой Shadow DOM, а CleverStyle CMS первый продукт, где вы можете его использовать что называется из коробки.

Для того чтобы подключить редактор нужно установить плагин TinyMCE и обернуть <textarea> следующим образом:

<cs-editor>
    <textarea></textarea>
</cs-editor>

Под капотом элемент-обертка применит Shadow DOM-совместимую версию TinyMCE к <textarea>, а так же подключит CSS стили к редактору в дополнение к используемым по умолчанию глобальным, чтобы элементы интерфейса корректно отображались даже внутри Shadow DOM.
А ещё элемент-обертка понимает когда он перемещается в DOM, фокусируется и так далее, обновляя соответствующим образом связь с текстовым полем.

Есть так же вариация с inline режимом, применяемым для редактируемого <div>:

<cs-editor-inline>
    <div></div>
</cs-editor-inline>

Интересно, что при отсутствии плагина TinyMCE элемент-обертка просто не будет обновлен до веб-компонента и пользователь увидит обычное текстовое поле, такое вот прогрессивное улучшение:)

Так что теперь впервые в истории человечества можно использовать WYSIWYG редактор в любом месте документа на любом уровне вложенности теневого дерева.

Подробнее в документации.

UI фреймворк


Исторически система поставлялась с каким-то UI фреймворком. Давным давно это был jQuery UI, который впоследствии был заменен на UIkit.
Последний служил весьма неплохо до того момента как в системе начали использоваться веб-компоненты, после чего несколько критических недостатков UIkit послужили причиной его полного выпиливания.
Во-первых та же поддержка Shadow DOM. UIkit понятия не имеет (так же как и Bootstrap, Foundation и другие приятели) что такое теневое дерево. И ладно если бы это касалось только стилей — были проблемы с обработкой событий и прочими нюансами.
В течении многих месяцев система поставлялась с растущим количеством патчей поверх ванильной версии для обеспечения поддержки Shadow DOM, но разработчики не спешили принимать патчи, к сожалению.
Вторая существенная проблема — это избыточная верстка и отсутствие поддержки data-binding из Polymer. В результате подключение компонентов UIkit превращалось в месиво как на стороне разметки, так и в JavaScript, причиняя боль и страдания при каждой попытке использования.

Решение было нелегким. На поиски альтернативы ушло дня три, ещё пару дней на обдумывание реализации и в результате появился пока ещё подпроект CleverStyle Widgets (есть планы выделить в отдельный самостоятельный проект).

CleverStyle Widgets



Как следует из названия, это не фреймворк, хотя он и заменил на 99% UIkit.
Виджеты — это набор веб-компонентов.
Все веб-компоненты отлично работают с Shadow DOM по определению, так как используют Polymer и поддерживают его data-binding систему (в отличии от UIkit, Bootstrap, Foundation и других приятелей).
Они имеют радикально простой API для пользователя, чаще всего это один тэг, который делает всё что нужно — никаких пятиэтажных вложенностей безликих <div>.
Но что ещё более важно — элементы сами по себе не имеют визуального стиля — он определяется извне с помощью CSS mixin-ов (в отличии от фиксированного внешнего вида Paper Elements с Material Design и Strand, который вообще идет в едином визуальном исполнении). Таким образом вы можете сделать внешний вид таким, каким он нужен именно вам.

В набор виджетов входят кнопки, переключатели, всплывающие подсказки, модальные окна и подобные нужные вещи.

Несколько примеров использования:

<button is="cs-button" type="button" icon="home" primary>Primary button with home icon</button>
<label is="cs-label-switcher">
    <input checked type="radio" value="0">
    Zero
</label>
<label is="cs-label-switcher">
    <input checked type="radio" value="1">
    One
</label>
<nav is="cs-nav-pagination" page="3" pages="10"></nav>
<cs-notify success left>Hello</cs-notify>
<button is="cs-button" type="button">Button will open modal</button>
<section is="cs-section-modal">One Two Three</section>

Упор сделан на максимальное сходство с нативными элементами, максимальное использование встроенного функционала браузера.

Больше примеров и описание свойств каждого элемента в документации.

Фронтенд без стилей по умолчанию


Используя UI фреймворк вы получаете огромную кучу стилей примененных ко всему документу, что периодически вынуждает бороться с этими стилями, порой даже прибегая к использованию !important.
Что хорошего в CleverStyle CMS 3 так это то, что НИКАКИЕ СТИЛИ НЕ ПРИМЕНЕНЫ К ДОКУМЕНТУ ПО УМОЛЧАНИЮ!
На практике это значит что даже normalize.css по умолчанию не используется. Разработчик имеет полную свободу по настройке внешнего вида и при желании может воспользоваться встроенными shared styles. Это так же значит что вы можете без конфликтов портировать любой готовый HTML шаблон в качестве темы оформления, можете при желании воспользоваться тем же Bootstrap, UIkit или чем-то ещё без проблем с наложением стилей.

Ещё больше фронтенда


Система никогда не использовала шаблонизатор и никогда не будет. Для генерации разметки используется BananaHTML, которая тоже была обновлена с частичной потерей обратной совместимости и сейчас гораздо более удобная и прямолинейная чем раньше.

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

Качество кода



Рефакторинг на сервер не только упростил понимание кода, но и в целом повысил его качество по ряду объективных метрик. При этом Scrutinizer имеет доступ к ещё большему количеству кода, так как API системы использует маршрутизацию основанную на контроллере, а Scrutinizer с ООП дружит лучше.

Прочие интересные изменения


На фронтенде был переработан объект cs.Event, теперь события основываются на Promise.

Это последняя стабильная ветка с поддержкой IE10 (и, возможно, IE11), поэтому полифилы для IE/Edge теперь вынесены в отдельную папку и подключаются для этих отставших браузеров, остальные браузеры не тратят на это трафик.

К минификации CSS и объединению CSS/JS/HTML добавилась минификация JS. Реализация весьма простая, как и минификация CSS, но очень быстраяя и весьма эффективная.
А CSS минификатор перестал встраивать картинки и прочие ресурсы размером больше 4 КиБ, вместо этого он просто корректирует относительные пути, на практике это означает гораздо более начальную быструю загрузку страницы.

Plupload модуль объявлен устаревшим, вместо него теперь появился модуль Uploader, который имеет независимую реализацию всего нужного для загрузки файлов (в том числе Drag'n'Drop, множественная загрузка файлов), но при этом в неминифицированном виде имеет в 15 раз меньший размер JavaScript кода чем минифицированный Plupload.

Улучшены интерфейсы работы с многоязычностью как на клиенте, так и на сервере, добавлен ряд событий, на которые разработчик может подписаться, проведено множество оптимизаций, сторонние компоненты обновлены до актуальны версий и многое другое (полный список изменений).

Небольшой тест производительности


Имея достаточно много функциональности из коробки в ядре, CleverStyle CMS остается чрезвычайно быстрой системой.

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

Забавы ради была взята последняя git версия CleverStyle CMS на момент написания статьи (3.146.4+build-1793) и абсолютно пустая Symfony Standard Edition 3.0.1.

Нужно заметить, что CleverStyle CMS не работает без БД, поскольку она заводит сессию на каждого посетителя в БД (в данном случае без поддержки cookie это значит что сессия создавалась при каждом запросе) + использовался файловый движок кэша. Symfony Standard Edition устанавливалась через Composer и к БД при запросах не подключалась.

Состояние обоих систем «из коробки», в CleverStyle CMS загружалась пустая главная страница, в Symfony загружалась стандартная страница с надписью «Welcome to Symfony 3.0.1».

Прочее ПО: Apache 2.4.17, PHP 7.0.2, MariaDB 10.1, Ubuntu 16.04 x64
Запускается на ноутбуке: Core i7 4900MQ, SSD

Результаты:
CleverStyle CMS
nazar-pc@nazar-pc ~> ab -c256 -n10000 cscms.loc
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, www.zeustech.net
Licensed to The Apache Software Foundation, www.apache.org

Benchmarking cscms.loc (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests

Server Software: Apache/2.4.17
Server Hostname: cscms.loc
Server Port: 80

Document Path: /
Document Length: 2132 bytes

Concurrency Level: 256
Time taken for tests: 7.813 seconds
Complete requests: 10000
Failed requests: 8468
(Connect: 0, Receive: 0, Length: 8468, Exceptions: 0)
Total transferred: 25217819 bytes
HTML transferred: 21327819 bytes
Requests per second: 1279.86 [#/sec] (mean)
Time per request: 200.022 [ms] (mean)
Time per request: 0.781 [ms] (mean, across all concurrent requests)
Transfer rate: 3151.89 [Kbytes/sec] received

Connection Times (ms)
min mean[±sd] median max
Connect: 0 4 58.3 0 1003
Processing: 5 171 670.6 96 6888
Waiting: 4 171 670.7 96 6888
Total: 9 175 673.2 96 6892

Percentage of the requests served within a certain time (ms)
50% 96
66% 103
75% 108
80% 112
90% 126
95% 148
98% 221
99% 3507
100% 6892 (longest request)

UPD: CleverStyle CMS 3.156.3+build-1823
nazar-pc@nazar-pc ~> ab -c256 -n10000 test.com
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, www.zeustech.net
Licensed to The Apache Software Foundation, www.apache.org

Benchmarking test.com (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests

Server Software: Apache/2.4.18
Server Hostname: test.com
Server Port: 80

Document Path: /
Document Length: 2191 bytes

Concurrency Level: 256
Time taken for tests: 3.733 seconds
Complete requests: 10000
Failed requests: 940
(Connect: 0, Receive: 0, Length: 940, Exceptions: 0)
Total transferred: 24388762 bytes
HTML transferred: 21908762 bytes
Requests per second: 2678.93 [#/sec] (mean)
Time per request: 95.561 [ms] (mean)
Time per request: 0.373 [ms] (mean, across all concurrent requests)
Transfer rate: 6380.45 [Kbytes/sec] received

Connection Times (ms)
min mean[±sd] median max
Connect: 0 10 100.7 0 1003
Processing: 4 84 29.6 79 359
Waiting: 4 81 26.5 78 359
Total: 9 94 104.5 80 1136

Percentage of the requests served within a certain time (ms)
50% 80
66% 88
75% 95
80% 100
90% 118
95% 137
98% 199
99% 1038
100% 1136 (longest request)

Symfony Standard Edition
nazar-pc@nazar-pc ~> ab -c256 -n10000 symfony.loc/web
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, www.zeustech.net
Licensed to The Apache Software Foundation, www.apache.org

Benchmarking symfony.loc (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests

Server Software: Apache/2.4.17
Server Hostname: symfony.loc
Server Port: 80

Document Path: /web/
Document Length: 4580 bytes

Concurrency Level: 256
Time taken for tests: 8.290 seconds
Complete requests: 10000
Failed requests: 0
Total transferred: 48440000 bytes
HTML transferred: 45800000 bytes
Requests per second: 1206.22 [#/sec] (mean)
Time per request: 212.233 [ms] (mean)
Time per request: 0.829 [ms] (mean, across all concurrent requests)
Transfer rate: 5706.01 [Kbytes/sec] received

Connection Times (ms)
min mean[±sd] median max
Connect: 0 14 119.0 0 3003
Processing: 6 197 43.7 194 594
Waiting: 6 194 40.3 192 594
Total: 15 211 127.4 194 3226

Percentage of the requests served within a certain time (ms)
50% 194
66% 203
75% 210
80% 216
90% 242
95% 283
98% 387
99% 1182
100% 3226 (longest request)

Выводы каждый сделает для себя сам.

На этом всё, жду комментариев.
Желающие пообщаться чатике могут сделать это в Gitter.
Код на GitHub, документация там же в разделе wiki.
Запустить пощупать можно одной строчкой с помощью Docker:

docker run --rm -p 8888:8888 nazarpc/cleverstyle-cms
Назар Мокринский @nazarpc
карма
31,0
рейтинг 21,0
Full-stack web developer, love Open Source
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (35)

  • 0
    Обратите внимание на:

    Проекту явно не хватает автозагрузки с единым стандартом для Namespace\\Class, развертывания из композера и слежение за версиями им же и много чего прочего, что можно изучить по ссылкам выше.
    • +1
      Composer полноценно поддерживается, у самого движка немного другой (более простой и специфический) механизм автозагрузки.
      Если кратко — все \ меняете на /, префикс \cs\modules соответствует директории components/modules, с плагинами аналогично.

      Просто Composer не обязателен для установки и работы системы, но опционально можете использовать, автозагрузчик классов из vendor будет подхвачен автоматически.
    • 0
      На счёт двух других ссылок — знаем, в курсе, сознательно некоторые из советов не применяю. Как результат — движок, рендерящий страницу с запросом в БД работает существенно быстрее фреймворка, который никаких запросов не делает и рендерит примитивнейшую фиксированную страницу. В реальных условиях разброс будет ещё больше.
      Отдельно стоит упомянуть размер стека вызовов при ошибке — в CleverStyle CMS он будет существенно меньше чем у Symfony, более осмысленный и простой для понимания, всё это результат осознанного выбора при принятии архитектурных решений.
      • +1
        То есть, вы сознательно игнорируете стандарты стиля и качества написания кода и это по вашему дает вашему проекту больший performance?
        Как результат — движок, рендерящий страницу с запросом в БД работает существенно быстрее фреймворка, который никаких запросов не делает и рендерит примитивнейшую фиксированную страницу. В реальных условиях разброс будет ещё больше.

        Я скажу вам больше, процедурный код, реализующий те-же функциональные особенности забитый в 1 файл будет делать это еще быстрей, однако вы же не пошли по этому пути. Вы стараетесь, хотя-бы отчасти, сделать ваш проект доступным для работы и доработки другими людьми, расширяемым, однако это едва-ли возможно если вы не следуете общепринятым принципам (т.к. вследствие этого другому человеку нужно будет потратить время на изучение именно вашего стиля расширения).
        Отдельно стоит упомянуть размер стека вызовов при ошибке — в CleverStyle CMS он будет существенно меньше чем у Symfony, более осмысленный и простой для понимания, всё это результат осознанного выбора при принятии архитектурных решений.

        А будет ли он таким же гибким и понятным как в symfony?
        П.с. — все проблемы, связанные с расходом ресурсов и временем генерации страниц уже давно решаются при помощи nginx/php-fpm+opcache и прочих шалостей, даже для таких монстров как bitrix(господь упаси).
        • +2
          То есть, вы сознательно игнорируете стандарты стиля и качества написания кода и это по вашему дает вашему проекту больший performance?
          Я скажу вам больше, процедурный код, реализующий те-же функциональные особенности забитый в 1 файл будет делать это еще быстрей, однако вы же не пошли по этому пути.

          Будет быстрее, это факт. Поэтому приходится искать золотую средину. Symfony исповедует более академический стиль программирования, напрочь забывая что в PHP нет zero cost abstractions, то есть каждая прослойка это потеря производительности, порой существенная. Так почему бы не выстроить архитектуру, которая и расширяемая, и абстракций имеет только необходимый минимум?
          Вы стараетесь, хотя-бы отчасти, сделать ваш проект доступным для работы и доработки другими людьми, расширяемым, однако это едва-ли возможно если вы не следуете общепринятым принципам (т.к. вследствие этого другому человеку нужно будет потратить время на изучение именно вашего стиля расширения).

          Конечно стараюсь. Но теперь давайте по сути, а не абстрактно и в вакуме. Возьмем достаточно большой файл, что в стиле кодирования такого, что делает код едва ли доступным и расширяемым? Буду очень благодарен комментариям по существу, а не «не такой как все — вон из профессии».
          А будет ли он таким же гибким и понятным как в symfony?

          Вы пробовали, к примеру отлаживать Composer, который использует немало компонентов Symfony? Я пробовал, блуждание по пустым прокси-вызовам убивает желание вникать в проект напрочь. Как раз из-за меньшего количества «пустых» вызовов стек меньше и гораздо понятнее.
          П.с. — все проблемы, связанные с расходом ресурсов и временем генерации страниц уже давно решаются при помощи nginx/php-fpm+opcache и прочих шалостей, даже для таких монстров как bitrix(господь упаси).

          К вашему сведению opcache включен начиная с PHP 5.5 по-умолчанию, тесты с PHP-FPM показывают аналогичный результат. Ещё объективные возражения по поводу условий тестирования?
          • 0
            Будет быстрее, это факт

            Я так понимаю за счёт меньшего стека вызова, я прав?
            Но как влияет хоть один из PSR на величину стека вызова?
            • 0
              Не только и не столько из-за количества вызовов, как из-за количества объектов, которые создаются в процессе. Возьмите любой пример и сравните — в большинстве случаев будет меньше вызовов и меньше сущностей.
              PSR никак не влияют на величину стека вызовов напрямую)
              • +1
                так всё же почему Вы выбрали такой стиль кодирования?
                когда речь идёт о закрытых проектах — да, там может быть всё, что угодно, как принято в команде.

                Но всё же Ваш проект в опен сорсе, его видят большое количество, которые привыкли к определённым стандартам в опен сорс проектах, привыкли контрибьютить по этим стандартам.

                Это ведь сильно снижает читаемость кода, или нет?
          • 0
            Стандарты кодирования, нужны что бы легко писать код, и не задумываться о стиле.
            Поясню, у вас все названия переменных через _, методов тоже, и вероятно ещё куча мелочей. И есть стандарт, которому все популярные библиотеки следуют, и большинство проектов в целом так же приходят к нему, все го знают. Я как рядовой разработчик тоже его знаю, и привык писать именно так, т.е. без задней мысли буду называть метод так: «someMethod», в IDE так же есть правила автоформата для стандарта, и эти часто пользуются люди, что бы не пропускать мелочи в стиле кодирования.
            И теперь когда я, захочу помочь в развитии вашего проекта, мне нужно будет переучиваться, перенастраивать окружение, переучиваться писать всё по стандарту. Это пустая трата времени, это ведь не несёт в себе ценности для меня, не даёт новых знаний, новых навыков. И многие тупо не будут помогать проекту если им нужно будет таким заниматься. И пойдут люди помогать другим проектам.

            Вот в кратце суть стандартов кодирования, зачем они и чем полезны.
            • +1
              Если вас остановит написание some_method вместо someMethod — то это, конечно, очень печально. У меня правило на этот счёт простое — в любом стороннем проекте где я принимаю участие (а, как видно по моему GitHub профилю, таких много), я всегда без дополнительных вопросов принимаю локальный стиль кодирования и подходы, какими бы они не были.
          • +1
            К вашему сведению opcache включен начиная с PHP 5.5 по-умолчанию, тесты с PHP-FPM показывают аналогичный результат. Ещё объективные возражения по поводу условий тестирования?

            Насколько я помню, начиная с версии php 5.5 входит в состав сборки бинарника php, однако он НЕ включен по умолчанию:
             ;opcache.enable=0
            

            Конечно стараюсь. Но теперь давайте по сути, а не абстрактно и в вакуме. Возьмем достаточно большой файл, что в стиле кодирования такого, что делает код едва ли доступным и расширяемым? Буду очень благодарен комментариям по существу, а не «не такой как все — вон из профессии».

            Во 1х вы наступили на те же грабли, на которые я наступил полтора года назад — у вас очень много (а возможно и все) классов наследуют паттерн singleton, который сам по себе является «мертвым» как для расширения так и для тестирования. Очень многие модели реализации в вашей CMS куда лучше будут выглядеть и работать в виде тех же factory, DI — ведь именно в умении выбрать правильный паттерн для конкретной реализации и заключается одна из составляющих работы программиста.
            Вы пробовали, к примеру отлаживать Composer, который использует немало компонентов Symfony? Я пробовал, блуждание по пустым прокси-вызовам убивает желание вникать в проект напрочь. Как раз из-за меньшего количества «пустых» вызовов стек меньше и гораздо понятнее.

            Верно, но это лишь их огрех из-за больших прослоек прокси или абстракций, уже не помню где, но есть рекомендации по количеству «прослоек» от крайней к основной модели реализации.
            • 0
              Насколько я помню, начиная с версии php 5.5 входит в состав сборки бинарника php, однако он НЕ включен по умолчанию

              Вот уж не знаю что сказать, по-моему используется всё-таки (в php.ini такой же комментарий как у вас).



              Во 1х вы наступили на те же грабли, на которые я наступил полтора года назад — у вас очень много (а возможно и все) классов наследуют паттерн singleton, который сам по себе является «мертвым» как для расширения так и для тестирования.

              Это не до конца верно. Во-первый название отражает способ использования, но не то, как он устроен внутри (внутри оно ближе к Factory). На самом деле компоненты могут расширять и модифицировать базовые системные классы, при чём даже делать множественное наследование, подробнее в соответствующем разделе документации. Но в целом да, это немного менее гибко чем DI, зато проще в использовании.
            • 0
              Недавно система перестала заводить сессию на каждого посетителя без надобности, добавил обновленный тестовый результат, получился двухкратный рост по сравнению с более старой версией системы: с 1279.86 rps до 2678.93 rps, тут Symfony уже никак конкурировать не может со своими 1206.22 rps.
              На HHVM получилось 2878.00 rps:

              HHVM
              nazar-pc@nazar-pc ~> ab -c256 -n10000 test.com:8000/
              This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
              Copyright 1996 Adam Twiss, Zeus Technology Ltd, www.zeustech.net
              Licensed to The Apache Software Foundation, www.apache.org

              Benchmarking test.com (be patient)
              Completed 1000 requests
              Completed 2000 requests
              Completed 3000 requests
              Completed 4000 requests
              Completed 5000 requests
              Completed 6000 requests
              Completed 7000 requests
              Completed 8000 requests
              Completed 9000 requests
              Completed 10000 requests
              Finished 10000 requests

              Server Software: nginx/1.9.10
              Server Hostname: test.com
              Server Port: 8000

              Document Path: /
              Document Length: 2195 bytes

              Concurrency Level: 256
              Time taken for tests: 3.475 seconds
              Complete requests: 10000
              Failed requests: 808
              (Connect: 0, Receive: 0, Length: 808, Exceptions: 0)
              Total transferred: 24578997 bytes
              HTML transferred: 21948997 bytes
              Requests per second: 2878.00 [#/sec] (mean)
              Time per request: 88.951 [ms] (mean)
              Time per request: 0.347 [ms] (mean, across all concurrent requests)
              Transfer rate: 6908.05 [Kbytes/sec] received

              Connection Times (ms)
              min mean[±sd] median max
              Connect: 0 0 0.7 0 5
              Processing: 17 88 13.5 86 187
              Waiting: 17 87 13.5 86 187
              Total: 21 88 13.3 86 187

              Percentage of the requests served within a certain time (ms)
              50% 86
              66% 91
              75% 95
              80% 97
              90% 105
              95% 110
              98% 118
              99% 121
              100% 187 (longest request)

              Увеличение конкурентности приводит к росту скорости но по окончанию теста что-то упирается и сильно конкурентность поднять не получается — сразу падает, то ли конфигурация сетевого стека то ли Nginx. В любом случае производительность очень ОК я считаю.
              При этом я не вдаюсь в крайности вроде процедурного кода в одном файле — запускается полноценный фреймворк.
    • +2
      Вот из-за такого хода дискуссий приходится уходить в англоязычный сектор опенсорса. Без обид.

      nazarpc инфраструктурно развивает сообщество (CMS, polymer, для Php Inspections (EA Extended) были баг-репорты) и критиковать решения не стоит.

      Не нравится решения автолоадинга, докера, архитектуры — делайте пулл реквесты, или создавайте тикеты.
      • 0
        Так не кто субъективно не обсуждает личность разработчика и его вклад в opensource, обсуждается именно программный код и принципы, на которые опирался автор, когда его писал.
  • +1
    А что означает Failed requests: 8468 в тесте CleverStyle CMS?
    • 0
      Failed requests: 8468
      (Connect: 0, Receive: 0, Length: 8468, Exceptions: 0)

      Это значит что у ответов отличается тело запроса по длинне. Поскольку в теле страницы указывается потребляемая оперативная память и время рендеринга страницы то тело ответа на несколько байт может отличаться, сами же запросы прошли без ошибок.
  • 0
    Не знал про Scrutinizer, спасибо за наводку. Проверил несколько своих решений, 10/10 ) Где мой пирожок?
    • +1
      Хорошая штука, там даже автопатчи есть на code-style и мелкие баги :)
      П.с. — покажите проект с 10/10 ( я до 8ки вылизывал достаточно долго).
      • 0
        чет он мне дает 9.69 бала, но не показывает проблемный код. Странно.
      • 0
        scrutinizer-ci.com/g/Bashka/bricks_frameworks_base
        дал 8.6 балла за то, что не смог найти в проекте объявленный выше класс ))) крутая штука, вне всяких сомнений
        • 0
          Ну… для 3 классов с парой методов это просто. А вот вам пример yii2, код которой далеко не самый плохой: scrutinizer-ci.com/g/yiisoft/yii2
          • 0
            Да при чем здесь размер проекта, scrutinizer нашел ошибку, которой в проекте нет )
            • 0
              Scrutinizer штука хорошая, но в последнее время статистику (там где график) не обновляет и вообще периодически разные глюки выдает.
          • +2
            Код в Yii2, достаточно плохой, так что оценка в 6 балов полностью оправдана.
  • 0
    del
  • 0
    Dockerfile странный, во-первых, описывает установку MariaDB и nginx, во-вторых, нет привязки к версии, билдится только мастер, в-третьих, все это лежит в коде проекта. По этим причинам не рекомендуется использовать в продакшене или сам проект для этого не пригоден?
    • 0
      Только поэтому, Dockerfile ориентирован только на одну цель — запустить работоспособную git версию системы чтобы пощупать что оно такое. Там кроме указанных вами вещей есть ещё некоторые недочёты из-за которых в продакшн этот контейнер совать нельзя.
      Тем не менее у меня есть другая разработка: github.com/nazar-pc/docker-webserver
      Вот с её помощью успешно работает несколько сайтов как на базе CleverStyle CMS, так и, например, ownCloud и один проект на Yii 1.
      По идее нужно сделать специальный production-ready образ, и даже есть issue по этому поводу, просто руки не доходят чтобы сделать толково.
  • 0
    Complete requests: 10000
    Failed requests: 8468
    

    мне кажется или тут что-то не так?
    • 0
      Кажется, уже спрашивали выше: habrahabr.ru/post/275139/#comment_8740645
      • 0
        извините, еще не проснулся )
        хотел спросить, много ли изменилось с моего комментария ко второй части публикации
        • 0
          Да:
          — все найденные вами недочеты и многие другие были исправлены
          — UI в целом стал более дружелюбным, но есть ещё идеи над улучшением сообщений о недостающих зависимостях компонентов или конфликтах в админке и некоторые другие
          — тему оформления создавать стало гораздо проще (по сути скачиваете любой шаблон, убеждаетесь что CSS/JS/HTML от веб-компонентов в папках css/js/html, удаляете явное подключение этих файлов из шаблона и вставляете подстановочные фразы вроде <!--head--> и <!--content--> чтобы движок знал куда контент вставлять; больше ничего не нужно менять, благодаря выпиленному UIkit конфликтов стилей не будет, раньше всё было немного сложнее)
          — поскольку практически всё ядро подверглось рефакторингу — читать и понимать код теперь проще и стиль гораздо более однородный, с но с компонентами ещё много работы
          — поработал над документацией, особенно по фронтенду — больше информации и примеров

          Если соизволите посмотреть на прогресс и оставить комментарий — буду премного благодарен, вы тогда очень помогли.
  • +3
    Может быть уже говорили, но меня как-то смущают такие вещи в коде.
    namespace cs;
    use
    	h;
    
    • –1
      Выравнивание такое потому что в случае нескольких классов они все подключаются одним use:
      namespace cs\modules\HybridAuth;
      use
          Exception,
          h,
          Hybrid_Endpoint,
          cs\Config,
          cs\Event,
          cs\ExitException,
          cs\Key,
          cs\Language,
          cs\Mail,
          cs\Page,
          cs\Route,
          cs\Session,
          cs\User;
      

      По сравнению с рекомендуемым PSR одним классом на use гораздо меньше визуального шума.
      • +1
        Дело даже не в выравнивании…

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.