Как сжать HTML в laravel 5
В Laravel 4.0 я использую приведенный ниже код, чтобы сжать выходные сообщения ответа ларавелла HTML в браузере, однако он не работает в 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, просто нужен простой код, который делает работу без потери производительности.
Ответы
Ответ 1
Рекомендуемый способ сделать это в Larvel 5 - это переписать вашу функцию как middleware. Как указано в документах:
.. это промежуточное программное обеспечение выполнило бы свою задачу после, запрос обрабатывается приложением:
<?php namespace App\Http\Middleware;
class AfterMiddleware implements Middleware {
public function handle($request, Closure $next)
{
$response = $next($request);
// Perform action
return $response;
}
}
Ответ 2
Полный код (с включенным пользовательским 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
до/после реализации этого кода.
наслаждайся этим... :)...
Ответ 3
Это не очень хорошее решение для минимизации html в промежуточном программном обеспечении, так как вы можете тратить на него много процессорного времени, и оно запускается при каждом запросе.
Вместо этого лучше использовать пакет htmlmin (https://github.com/HTMLMin/Laravel-HTMLMin):
composer require htmlmin/htmlmin
php artisan vendor:publish
Сокращение HTML на уровне шаблона лезвия и кэширование его в хранилище должно быть намного более эффективным.
Ответ 4
Edit
Сжатие вывода для каждого запроса с использованием промежуточного программного обеспечения действительно плохая идея, я рекомендую вам проверить это решение от Jokerius
Ответ
Это почти копия ответа Вахида, но она устраняет две проблемы.
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;
}
}
}
Ответ 5
Это лучший способ. Нам не нужно использовать пакетики laravel. Спасибо.
<?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;
}
}
Ответ 6
Для легкого сжатия я создаю свой собственный модуль laravel. Этот модуль будет сжимать весь окончательный вывод html перед отправкой клиенту (браузеру).
Вы также можете одновременно настроить таргетинг на несколько сред, используя файл .env
.
Подробнее о том, как установить и настроить, можно найти здесь .