Подключаем сжатые min версии css и js с автоматическим слежением и обновлением

Не секрет, что для высоких показателей PageSpeed полезно минифицировать css и js код на сайте. А минифицированный css код вообще желательно выводить сразу в html, чтобы тот при загрузке не блокировал первичный рендеринг страниц.

Однако, недостаток подключения сжатых копий js или css всегда заключался в том, что непосредственно сжатый код править неудобно и непонятно, куда удобней править стандартные файлы. Но тогда, после каждого редактирования своих css или js файлов, после каждой мелкой правки в них, надо было вручную перегонять оригиналы в сжатые min версии, перезаливать их на сайт, следить за актуальностью — соответствием версий сжатых и не сжатых файлов друг другу, путаться потом в этой актуальности… Какой-то геморрой, согласны?

Так было раньше, но после установки php библиотеки https://www.minifier.org/ всё будет иначе.

В шаблоне мы продолжим указывать обычные css, js файлы. Но особым способом. И редактировать тоже будем только обычные файлы, как и всегда это делали. А сжатые min копии больше не наша забота, управлять ими будет только скрипт.

Например:

<style type="text/css">
<?=minify('/tpl/css/template.css');?>
</style>
<!-- на выходе получаем сжатый css код -->

Или так:

<script src="<?=minify('/tpl/js/script1.js');?>"></script>
<script src="<?=minify('/tpl/js/script2.js');?>"></script>
<script src="<?=minify('/tpl/js/script3.js');?>"></script>
<!-- в src этих скриптов на выходе всегда будет путь к сжатым и актуальным min js копиям соответствующих файлов с timestamp меткой времени изменения. -->

То есть, указываете в шаблоне обычные свои js, css файлы с относительным путем от корня сайта. И правки, когда надо, вносите как обычно в них. А создавать их сжатые версии, следить за соответствием оригиналам и актуальностью, автоматом обновлять эти сжатые копии(если был отредактирован оригинальный файл), будет специальная библиотека ( https://www.minifier.org/ ) и функция minify().

Принцип следующий: например есть файл tpl/css/styles.css , если надо напрямую в html вывести его сжатый css код, то вы просто подключаете в шаблоне его так:

<style type="text/css"><?=minify('/tpl/css/styles.css');?></style>

На выходе в браузере получится:

<style type="text/css">сжатый css код этого файла</style>

Если же нужно вывести не сжатый css код, а просто подключить на странице сжатый css файл тегом <link rel=»stylesheet» href=»…»>, тогда надо добавить параметр url вот так:

<link href="<?=minify('/tpl/css/styles.css', 'url');?>" rel="stylesheet">

На выходе в браузере получится путь с min копией соответствующего файла:

<link href="/tpl/css/styles.min.css?TIMESTAMP" rel="stylesheet">

При этом автоматически будет создан соответствующий файл /tpl/css/styles.min.css и функция сама будет отслеживать его соответствие оригиналу. Если вы внесли правки в оригинал — функция minify() автоматически обновит и соответствующий ему сжатый файл. То есть, создает, обновляет и управляет min версиями только скрипт. Достаточно подключить в шаблоне таким способом обычные файлы js и css, а про их сжатые версии забыть и не париться, будто их нет. Правки вносятся в обычные версии файлов, а скрипт подхватит, создаст и если надо обновит сжатые копии. При изменении файла изменится и timestamp метка, чтобы подхватывалось кешем юзеров.

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

Но это поведение можно менять, передав второй параметр. Например, если нужен не путь к сжатому файлу, а сжатый js код файла, то:

<script><?=minify('/tpl/js/example.js', 'code');?></script>

На выходе будет:

<script>сжатый js код</script>

А если из src нужно подключить min js, тогда:

<script src="<?=minify('/tpl/js/example.js');?>"></script>
<!-- или равнозначно вот так -->
<script src="<?=minify('/tpl/js/example.js', 'url');?>"></script>

На выходе будет путь с его актуальной min версией:

<script src="/tpl/js/example.min.js?TIMESTAMP"></script>

Внедряется на сайт всё просто:

composer require matthiasmullie/minify

Да, на папочки с файлами css или js права на запись должны иметься 755 По месту использования включаем такой скрипт:

require_once 'minify.php';
<?php
require $_SERVER['DOCUMENT_ROOT'] . '/vendor/autoload.php';
    use MatthiasMullie\Minify;
    /*
    $filepath = относительный путь к не сжатому css или js файлу
    $appearance = при вызове может иметь 2 значения или не указываться: 
                'code' = вывести сжатый код
                'url' = вывести url к сжатому файлу
                если значение $appearance не указывается, то для css выводится сжатый код, а для js выводится путь к сжатому файлу
    */
 function minify($filepath, $appearance = false) {
    $filepath = $_SERVER['DOCUMENT_ROOT'] . $filepath;
    $ext = substr($filepath, -3) == 'css' ? 'css' : 'js';
    $minifiedPath = ($ext == 'css') ? preg_replace('#\.css$#', '.min.css', $filepath) : preg_replace('#\.js$#', '.min.js', $filepath);
    $v = filemtime($filepath);
    if (!file_exists($minifiedPath) || $v != filemtime($minifiedPath)) {
        $minifier = ($ext == 'css') ? new Minify\CSS($filepath) : new Minify\JS($filepath);
        $minifier->minify($minifiedPath);
        touch($filepath);
    }
    switch ($appearance) {
        case 'code':
            echo file_get_contents($minifiedPath);
            break;
        case 'url':
            echo mb_substr($minifiedPath, mb_strlen($_SERVER['DOCUMENT_ROOT'])) . '?' .$v;
            break;
        default:
            echo ($ext == 'css') ? file_get_contents($minifiedPath) : mb_substr($minifiedPath, mb_strlen($_SERVER['DOCUMENT_ROOT'])) . '?' .$v;
            break;
    }
}

А если composer не используется, то:

<?php

require_once __DIR__ . '/minify/src/Minify.php';
require_once __DIR__ . '/minify/src/CSS.php';
require_once __DIR__ . '/minify/src/JS.php';
require_once __DIR__ . '/minify/src/Exception.php';
require_once __DIR__ . '/minify/src/Exceptions/BasicException.php';
require_once __DIR__ . '/minify/src/Exceptions/FileImportException.php';
require_once __DIR__ . '/minify/src/Exceptions/IOException.php';
require_once __DIR__ . '/path-converter/src/ConverterInterface.php';
require_once __DIR__ . '/path-converter/src/Converter.php';

use MatthiasMullie\Minify;
/*
$filepath = относительный путь к не сжатому css или js файлу
$appearance = при вызове может иметь 2 значения или не указываться: 
            'code' = вывести сжатый код
            'url' = вывести url к сжатому файлу
            если значение $appearance не указывается, то для css выводится сжатый код, а для js выводится путь к сжатому файлу
*/
function minify($filepath, $appearance = false) {
    $filepath = $_SERVER['DOCUMENT_ROOT'] . $filepath;
    $ext = substr($filepath, -3) == 'css' ? 'css' : 'js';
    $minifiedPath = ($ext == 'css') ? preg_replace('#\.css$#', '.min.css', $filepath) : preg_replace('#\.js$#', '.min.js', $filepath);
    $v = filemtime($filepath);
    if (!file_exists($minifiedPath) || $v != filemtime($minifiedPath)) {
        $minifier = ($ext == 'css') ? new Minify\CSS($filepath) : new Minify\JS($filepath);
        $minifier->minify($minifiedPath);
        touch($filepath);
    }
    switch ($appearance) {
        case 'code':
            echo file_get_contents($minifiedPath);
            break;
        case 'url':
            echo mb_substr($minifiedPath, mb_strlen($_SERVER['DOCUMENT_ROOT'])) . '?' .$v;
            break;
        default:
            echo ($ext == 'css') ? file_get_contents($minifiedPath) : mb_substr($minifiedPath, mb_strlen($_SERVER['DOCUMENT_ROOT'])) . '?' .$v;
            break;
    }
}

 

Оставить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *