Как мне сжать HTML в laravel 5

В Laravel 4.0 я использую приведенный ниже код для сжатия выводимых ответов HTML laravel в браузер, однако в laravel 5 это не работает.

App::after(function($request, $response)
{
    if($response instanceof Illuminate\Http\Response)
    {
        $buffer = $response->getContent();
        if(strpos($buffer,'<pre>') !== false)
        {
            $replace = array(
                '/<!--[^\[](.*?)[^\]]-->/s' => '',
                "/<\?php/"                  => '<?php ',
                "/\r/"                      => '',
                "/>\n</"                    => '><',
                "/>\s+\n</"                 => '><',
                "/>\n\s+</"                 => '><',
            );
        }
        else
        {
            $replace = array(
                '/<!--[^\[](.*?)[^\]]-->/s' => '',
                "/<\?php/"                  => '<?php ',
                "/\n([\S])/"                => '$1',
                "/\r/"                      => '',
                "/\n/"                      => '',
                "/\t/"                      => '',
                "/ +/"                      => ' ',
            );
        }
        $buffer = preg_replace(array_keys($replace), array_values($replace), $buffer);
        $response->setContent($buffer);
    }
});

Пожалуйста, как мне сделать эту работу в Laravel 5.

ИЛИ ЖЕ

Пожалуйста, предоставьте лучший способ сжатия HTML в laravel 5, если таковой имеется. Заранее спасибо.

NB: я не хочу использовать какой-либо пакет laravel для сжатия html, просто нужен простой код, который работает без потери производительности.

10 ответов

Решение

Рекомендуемый способ сделать это в Larvel 5 - переписать вашу функцию в качестве промежуточного программного обеспечения. Как указано в документах:

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

<?php namespace App\Http\Middleware;

class AfterMiddleware implements Middleware {

    public function handle($request, Closure $next)
    {
        $response = $next($request);

        // Perform action

        return $response;
    }
}

Полный код такой (с включенным пользовательским GZip):

<?php

namespace App\Http\Middleware;

use Closure;

class OptimizeMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        $buffer = $response->getContent();
        if(strpos($buffer,'<pre>') !== false)
        {
            $replace = array(
                '/<!--[^\[](.*?)[^\]]-->/s' => '',
                "/<\?php/"                  => '<?php ',
                "/\r/"                      => '',
                "/>\n</"                    => '><',
                "/>\s+\n</"                 => '><',
                "/>\n\s+</"                 => '><',
            );
        }
        else
        {
            $replace = array(
                '/<!--[^\[](.*?)[^\]]-->/s' => '',
                "/<\?php/"                  => '<?php ',
                "/\n([\S])/"                => '$1',
                "/\r/"                      => '',
                "/\n/"                      => '',
                "/\t/"                      => '',
                "/ +/"                      => ' ',
            );
        }
        $buffer = preg_replace(array_keys($replace), array_values($replace), $buffer);
        $response->setContent($buffer);
        ini_set('zlib.output_compression', 'On'); // If you like to enable GZip, too!
        return $response;
    }
}

Пожалуйста, проверьте ваш браузер сетевой инспектор для Content-Length заголовок до / после реализации этого кода.

наслаждайся этим...:).. .

Это не очень хорошее решение для минимизации html в промежуточном программном обеспечении, так как вы можете тратить на него много процессорного времени, и оно запускается при каждом запросе.

Вместо этого лучше использовать пакет htmlmin ( https://github.com/HTMLMin/Laravel-HTMLMin):

composer require htmlmin/htmlmin
php artisan vendor:publish

Сокращение HTML на уровне шаблона лезвия и кэширование его в хранилище должно быть намного более эффективным.

Я создал плагин webpack для решения той же задачи.MinifyHtmlWebpackPlugin

Установите плагин с помощью npm:

$ npm install minify-html-webpack-plugin --save-dev

Для пользователей Laravel Mix

Вставьте приведенные ниже фрагменты в файл mix.js.

    const MinifyHtmlWebpackPlugin = require('minify-html-webpack-plugin');
    const mix = require('laravel-mix');

    mix.webpackConfig({
        plugins: [
            new MinifyHtmlWebpackPlugin({
                src: './storage/framework/views',
                ignoreFileNameRegex: /\.(gitignore)$/,
                rules: {
                    collapseWhitespace: true,
                    removeAttributeQuotes: true,
                    removeComments: true,
                    minifyJS: true,
                }
            })
        ]
    });

Он уменьшит все файлы просмотра во время сборки Webpack.

Это почти копия ответа Вахида, но она исправляет две проблемы.

1) Это проверка, если ответ BinaryFileResponse поскольку любая попытка изменить этот тип ответа вызовет исключение.

2) В нем сохранены символы новой строки, поскольку полное удаление новых строк приведет к плохому коду Javascript в строках с однострочным комментарием.

Например, код ниже

 var a; //This is a variable
 var b; //This will be commented out

Станет

 var a; //This is a variable var b; //This will be commented out

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

Вот модифицированная версия.

<?php

namespace App\Http\Middleware;

use Closure;

class OptimizeMiddleware {

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 * @return mixed
 */
public function handle($request, Closure $next)
{
    $response = $next($request);
    if ($response instanceof \Symfony\Component\HttpFoundation\BinaryFileResponse) {
        return $response;
    } else {
        $buffer = $response->getContent();
        if (strpos($buffer, '<pre>') !== false) {
            $replace = array(
                '/<!--[^\[](.*?)[^\]]-->/s' => '',
                "/<\?php/" => '<?php ',
                "/\r/" => '',
                "/>\n</" => '><',
                "/>\s+\n</" => '><',
                "/>\n\s+</" => '><',
            );
        } else {
            $replace = array(
                '/<!--[^\[](.*?)[^\]]-->/s' => '',
                "/<\?php/" => '<?php ',
                "/\n([\S])/" => '$1',
                "/\r/" => '',
                "/\n+/" => "\n",
                "/\t/" => '',
                "/ +/" => ' ',
            );
        }
        $buffer = preg_replace(array_keys($replace), array_values($replace), $buffer);
        $response->setContent($buffer);
        ini_set('zlib.output_compression', 'On'); //enable GZip, too!
        return $response;
    }
  }
}

На всякий случай, если вы визуализируете представление вручную:


echo view('example.site')->render(function($view, $content) { 
    return preg_replace(
            ['/\>[^\S ]+/s', '/[^\S ]+\</s', '/(\s)+/s'],
            ['>', '<', '\\1'],
            $content
    ); }
);

На мой взгляд, этот пакет намного лучше https://github.com/renatomarinho/laravel-page-speed

Я сделал это с помощью очень простого кода.Пример: welcome.blade.php

Добавьте следующий код в начало страницы

      <?php ob_start('compress_page');?>

Добавьте следующий код в конец страницы :

      <?php   
ob_end_flush();
function compress_page($buffer) {
    $search = array("/>[[:space:]]+/", "/[[:space:]]+</");
    $replace = array(">","<");
    return preg_replace($search, $replace, $buffer);
}?>

Пример кода полной страницы:

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

<?php

namespace App\Http\Middleware;

use Closure;

class OptimizeMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        $buffer = $response->getContent();
        if(strpos($buffer,'<pre>') !== false)
        {
            $replace = array(
                '/<!--[^\[](.*?)[^\]]-->/s' => '',
                "/<\?php/"                  => '<?php ',
                "/\r/"                      => '',
                "/>\n</"                    => '><',
                "/>\s+\n</"                 => '><',
                "/>\n\s+</"                 => '><',
            );
        }
        else
        {
            $replace = array(
                '/<!--[^\[](.*?)[^\]]-->/s' => '',
                "/<\?php/"                  => '<?php ',
                "/\n([\S])/"                => '$1',
                "/\r/"                      => '',
                "/\n/"                      => '',
                "/\t/"                      => '',
                "/ +/"                      => ' ',
            );
        }
        $buffer = preg_replace(array_keys($replace), array_values($replace), $buffer);
        $response->setContent($buffer);
        ini_set('zlib.output_compression', 'On'); // If you like to enable GZip, too!
        return $response;
    }
}

Для легкого сжатия я создаю свою собственную библиотеку, которая требует небольшого изменения конфигурации в app/Http/Kernel.php, В основном это будет использовать AfterMiddleware Концепция Laravel, где весь вывод готов к просмотру в браузере. Так это Middleware сработает прямо перед отправкой вывода html в браузер.

protected $middleware = [
    ...
    \Vrkansagara\Http\Middleware\AfterMiddleware::class,
    ...
];

Вы также можете настроить таргетинг на несколько сред одновременно .env файл.

Более подробную информацию о том, как установить и настроить, можно найти здесь

Другие вопросы по тегам