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
    
    Поделиться публикацией
    Похожие публикации
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 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
                                    Дело даже не в выравнивании…

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