Flector

Как автоматически «сжимать» html, css и js скрипты сайта?

Пример сжатого html-кода страницы

В данном случае речь идет не о физическом сжатии (с помощью gzip или чего-то подобного), а о минимизации кода страницы, когда из него удаляются все не значимые для отображения страницы в браузере символы (переводы строк, пробелы, комментарии и т.д.). Обычно для решения подобной задачи используют сторонние плагины для движка, хотя можно обойтись всего одной (хоть и объемной) функцией, которую вам необходимо добавить в файл functions.php вашей темы:

//сжатие html, js и css start
class Compress_HTML {
    protected $compress_css = true; //сжатие css (true - включено)
    protected $compress_js = true; //сжатие js-скриптов (true - включено)
    protected $info_comment = true; //вывод информации о сжатии (было - стало)
    protected $remove_comments = true; //комментарии в коде
 
    protected $html;
    public function __construct($html)
    {if (!empty($html)){$this->parseHTML($html);}}
    public function __toString()
    {return $this->html;}
    protected function bottomComment($raw, $compressed){
        $raw = strlen($raw);
        $compressed = strlen($compressed);
        $savings = ($raw-$compressed) / $raw * 100;
        $savings = round($savings, 2);
        return '<!--HTML compressed, size saved '.$savings.'%. From '.$raw.' bytes, now '.$compressed.' bytes-->';}
    protected function minifyHTML($html){
        $pattern = '/<(?<script>script).*?<\/script\s*>|<(?<style>style).*?<\/style\s*>|<!(?<comment>--).*?-->|<(?<tag>[\/\w.:-]*)(?:".*?"|\'.*?\'|[^\'">]+)*>|(?<text>((<[^!\/\w.:-])?[^<]*)+)|/si';
        preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);
        $overriding = false;
        $raw_tag = false;
        $html = '';
        foreach ($matches as $token) {
            $tag = (isset($token['tag'])) ? strtolower($token['tag']) : null;
            $content = $token[0];
            if (is_null($tag)){
                if ( !empty($token['script']) ){$strip = $this->compress_js;				}
                else if ( !empty($token['style']) )
                {$strip = $this->compress_css;				}
                else if ($content == '<!--wp-html-compression no compression-->')
                {$overriding = !$overriding; continue;}
                else if ($this->remove_comments)
                {if (!$overriding && $raw_tag != 'textarea'){
                    $content = preg_replace('/<!--(?!\s*(?:\[if [^\]]+]|<!|>))(?:(?!-->).)*-->/s', '', $content);}}
            } else{
                if ($tag == 'pre' || $tag == 'textarea'){$raw_tag = $tag;}
                else if ($tag == '/pre' || $tag == '/textarea')
                {$raw_tag = false;}
                else{if ($raw_tag || $overriding){$strip = false;}else{$strip = true;
                    $content = preg_replace('/(\s+)(\w++(?<!\baction|\balt|\bcontent|\bsrc)="")/', '$1', $content);
                    $content = str_replace(' />', '/>', $content);}}}
            if ($strip){$content = $this->removeWhiteSpace($content);}
            $html .= $content;}
        return $html;}
    public function parseHTML($html) {
        $this->html = $this->minifyHTML($html);
        if ($this->info_comment){$this->html .= "\n" . $this->bottomComment($html, $this->html);}}
    protected function removeWhiteSpace($str) {
        $str = str_replace("\t", ' ', $str);
        $str = str_replace("\n",  '', $str);
        $str = str_replace("\r",  '', $str);
        while (stristr($str, '  ')){$str = str_replace('  ', ' ', $str);}
        return $str;}
}
function wp_html_compression_finish($html){return new Compress_HTML($html);}
function wp_html_compression_start(){ob_start('wp_html_compression_finish');}
add_action('get_header', 'wp_html_compression_start');
//сжатие html, js и css end

В случае проблем с js-скриптами отключите их сжатие в настройках функции. И еще раз отмечу - минимизация кода страницы никак не отменяет необходимости включения серверного сжатия с помощью gzip.


Комментарии (8 комментариев)
  1. Функция работает, почти ничего не изменилось по показателям сайта, вот только в developers.google было выполнено условие по сокращению HTML на странице. У вас стоит данная функция на сайте? Как о ней еще можно сказать более развернуто, какая польза данной функции?

    • Flector:

      у меня включено gzip-сжатие на сервере, а при включенном gzip гугл считает, что страница и так сокращена.

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

      • Спасибо за разъяснения! Я у себя вставил, пусть будет, так как на сервере не подключал данную функцию.
        При проверке на один процент все улучшилось - это немного, но улучшение не в ущерб чему-то.
        У Вас отличный сайт, хорошо сделанный шаблон, информация полезная и актуальная. Выгодно выделяется из числа вашей тематики. По крайне мере, некоторые полезные статьи я не встречал на просторе интернета. :)

  2. Валодя:

    Чет не работает - 502 ошибка но админка работает

    • Flector:

      отключите сжатие js-скриптов. или лучше загляните в логи ошибок сервера - вероятно у вас или не та версия php или не хватает какого-то модуля для него.

  3. Класс вырезан из плагина WP-HTML-Compression
    Для удобства можно прогнать через PHPformatter.com

    • Flector:

      не, сначала был код - потом из него плагин сварганили.

Написать комментарий

Для вставки кода воспользуйтесь кнопкой "Код". Используйте предпросмотр!