Минимизация и объединение CSS и JS файлов

#
Минимизация и объединение CSS и JS файлов
Предлагаю на суд следующее решение:

Немного позаимствовал методов у Core_Page, создал свой класс Core_Compress, который минимизирует стили и скрипты сохраняет в файл и подключает файлы в шаблоне.

Core_Compress вместо Core_Page

<?php
Core_Compress::instance()
   // jQuery
   ->prependJs('/hostcmsfiles/jquery/jquery.js')
   //Vegas slider
   ->js('/bootstrap/vegas/vegas.js')
   ->showJs();
   ?>


На выходе имеем минимизированный и объединенный скрипт

<script type="text/javascript" src="/hostcmsfiles/minified.js"></script>


Теперь непосредственно реализация:

Сам скрипт минимизации и склейки я взял от сюда



поставил через composer и подключил в файле bootstrap.php

require_once(dirname(__FILE__) . '/vendor/autoload.php');


далее создаем свой класс, я назвал его compress, в папке Modules/Core/compress.php

<?php
defined('HOSTCMS') || exit('HostCMS: access denied.');
use MatthiasMullie\Minify;
/**
* Created by PhpStorm.
* User: xelax
* Date: 03.07.2017
* Time: 19:13
*/
class Core_Compress extends Core_Page
{
    protected $_checkSumPathCss = CMS_FOLDER.'hostcmsfiles/checksumcss.md5';
    protected $_miniPathCss = 'hostcmsfiles/minified.css';
    protected $_checkSumPathJs = CMS_FOLDER.'hostcmsfiles/checksumjs.md5';
    protected $_miniPathJs = 'hostcmsfiles/minified.js';
    /**
     * Constructor.
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * The singleton instances.
     * @var mixed
     */
    static public $instance = NULL;

    /**
     * Register an existing instance as a singleton.
     * @return object
     */
    static public function instance()
    {
        if (is_null(self::$instance))
        {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Linking css
     * @var array
     */
    public $css = array();

    /**
     * Get block of linked compressed css
     * @return string
     */
    protected function _getCssCompressed()
    {
        try
        {
            $sReturn = '';

            $minifier = new Minify\CSS();

            foreach ($this->css as $css)
            {
                $minifier->add(CMS_FOLDER.$css);
            }

            $minifiedPath = CMS_FOLDER . $this->_miniPathCss;

            if( !file_exists($minifiedPath) ){
                $this->setMd5($minifier->minify());
                $minifier->minify($minifiedPath);
            }else{
                $this->getMd5() != md5($minifier->minify()) ? $minifier->minify($minifiedPath) : false;
            }

            $sReturn .= '<link rel="stylesheet" type="text/css" href="/' . $this->_miniPathCss . '" />' . "\n";
        }
        catch (Exception $e)
        {
            $sReturn = $this->_getCss();
        }

        return $sReturn;
    }

    protected function getMd5($script='css'){
        return file_exists(strtolower($script) == 'js' ? $this->_checkSumPathJs : $this->_checkSumPathCss) ? file_get_contents(strtolower($script) == 'js' ? $this->_checkSumPathJs : $this->_checkSumPathCss) : false;
    }

    protected function setMd5($string='',$script='css'){
        if ( $result = file_put_contents(strtolower($script) == 'js' ? $this->_checkSumPathJs : $this->_checkSumPathCss,md5($string)) === false ){
            throw new Exception('The file "'.strtolower($script) == 'js' ? $this->_checkSumPathJs : $this->_checkSumPathCss.'" could not be written to. Check your disk space and file permissions.');
        }
        return $result;
    }
    /**
     * Get block of linked css and clear added CSS list
     * @param boolean $bExternal add as link
     * @return string
     * @hostcms-event Core_Page.onBeforeGetCss
     */
    public function getCss($bExternal = TRUE)
    {
        Core_Event::notify(get_class($this) . '.onBeforeGetCss', $this);

        $return = $this->_getCssCompressed();

        $this->css = array();

        return $return;
    }

    /**
     * Linking js
     * @var array
     */
    public $js = array();

    /**
     * Get block of linked compressed js
     * @param boolean $async Run asynchronously, default FALSE
     * @return string
     */
    protected function _getJsCompressed($async = FALSE)
    {
        try
        {
            $sReturn = '';

            $minifier = new Minify\JS();

            foreach ($this->js as $aJs)
            {
                $minifier->add(CMS_FOLDER.$aJs[0]);
            }

            $minifiedPath = CMS_FOLDER . $this->_miniPathJs;

            if( !file_exists($minifiedPath) ){
                $this->setMd5($minifier->minify(),'js');
                $minifier->minify($minifiedPath);
            }else{
                $this->getMd5('js') != md5($minifier->minify()) ? $minifier->minify($minifiedPath) : false;
            }

            $sAsync = $async ? ' async="async"' : '';

            $sReturn .= '<script type="text/javascript"' . $sAsync . ' src="/' . $this->_miniPathJs . '"></script>' . "\n";
        }
        catch (Exception $e)
        {
            $sReturn = $this->_getJs();
        }

        return $sReturn;
    }

    /**
     * Get block of linked JS and clear added JS list
     * @param boolean $async Run asynchronously, default FALSE
     * @return string
     * @hostcms-event Core_Page.onBeforeGetJs
     */
    public function getJs($async = FALSE)
    {
        Core_Event::notify(get_class($this) . '.onBeforeGetJs', $this);

        $return = $this->_getJsCompressed($async);

        $this->js = array();

        return $return;
    }
}


Пути к сжатым файлам меняйте сами

protected $_checkSumPathCss = CMS_FOLDER.'hostcmsfiles/checksumcss.md5';
protected $_miniPathCss = 'hostcmsfiles/minified.css';
protected $_checkSumPathJs = CMS_FOLDER.'hostcmsfiles/checksumjs.md5';
protected $_miniPathJs = 'hostcmsfiles/minified.js';


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

Вроде работает!
Жду разбор полетов! Хотелось бы понять, вообще проверка и сжатие на лету это нормально?

#
Re: Минимизация и объединение CSS и JS файлов
Опытным путем выяснил что большое кол-во JS файлов склеиваются плохо, а вот CSS нормально.
#
Re: Минимизация и объединение CSS и JS файлов
xelaxela13,
проверка на лету большого количества файлов не нормально
HostDev.pw - модули для HostCMS, Telegram: @hostdev
#
Re: Минимизация и объединение CSS и JS файлов
По сути склейка и минимизация происходит один раз, ну или при внесении изменений, а так просто проверяется контрольная сумма
Авторизация