在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中完成这项工作。
或
如果有,请提供一种更好的方法来压缩laravel 5中的HTML。提前谢谢。
注意:我不想使用任何laravel包来压缩html,只需要一个简单的代码来完成这项工作而不会影响性能。
完整的代码是这样的(启用自定义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不是一个很好的解决方案,因为你可能会在它上花费大量的CPU时间,而且它会在每个请求上运行。
相反,最好使用htmlmin包(https://github.com/HTMLMin/Laravel-HTMLMin):
composer require htmlmin/htmlmin
php artisan vendor:publish
在刀片模板级别上最小化HTML并将其缓存在存储中应该更有效。
Larvel 5中推荐的方法是将函数重写为中间件。如文件所述:
该中间件将在应用程序处理请求后执行其任务:
<?php namespace App'Http'Middleware;
class AfterMiddleware implements Middleware {
public function handle($request, Closure $next)
{
$response = $next($request);
// Perform action
return $response;
}
}
我创建了一个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生成期间缩小所有视图文件。
这几乎是Vahid答案的副本,但它解决了两个问题。
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;
}
}
}
编辑
使用中间件压缩每个请求的输出确实是个坏主意,我建议您查看Jokerius 的此解决方案
以防手动渲染视图:
echo view('example.site')->render(function($view, $content) {
return preg_replace(
['/'>[^'S ]+/s', '/[^'S ]+'</s', '/('s)+/s'],
['>', '<', '''1'],
$content
); }
);
在我看来,这个包是renatomarnho/laravel页面速度的更好选择
我用非常简单的代码完成了这项工作。示例: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 ob_start('compress_page');?>
<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">
<!-- Styles -->
<style>
html, body {
background-color: #fff;
color: #636b6f;
font-family: 'Raleway', sans-serif;
font-weight: 100;
height: 100vh;
margin: 0;
}
.full-height {
height: 100vh;
}
.flex-center {
align-items: center;
display: flex;
justify-content: center;
}
.position-ref {
position: relative;
}
.top-right {
position: absolute;
right: 10px;
top: 18px;
}
.content {
text-align: center;
}
.title {
font-size: 84px;
}
.links > a {
color: #636b6f;
padding: 0 25px;
font-size: 12px;
font-weight: 600;
letter-spacing: .1rem;
text-decoration: none;
text-transform: uppercase;
}
.m-b-md {
margin-bottom: 30px;
}
</style>
</head>
<body>
<div class="flex-center position-ref full-height">
@if (Route::has('login'))
<div class="top-right links">
@auth
<a href="{{ url('/home') }}">Home</a>
@else
<a href="{{ route('login') }}">Login</a>
<a href="{{ route('register') }}">Register</a>
@endauth
</div>
@endif
<div class="content">
<div class="title m-b-md">
Laravel
</div>
<div class="links">
<a href="https://laravel.com/docs">Documentation</a>
<a href="https://laracasts.com">Laracasts</a>
<a href="https://laravel-news.com">News</a>
<a href="https://forge.laravel.com">Forge</a>
<a href="https://github.com/laravel/laravel">GitHub</a>
</div>
</div>
</div>
</body>
</html>
<?php
ob_end_flush();
function compress_page($buffer) {
$search = array("/>[[:space:]]+/", "/[[:space:]]+</");
$replace = array(">","<");
return preg_replace($search, $replace, $buffer);
}?>
这是最好的方法。。我们不需要使用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;
}
}
为了便于压缩,我构建了自己的laravel模块。该模块将在发送到客户端(浏览器)之前压缩所有最终的html输出。
您还可以使用.env
文件一次针对多个环境。
有关如何安装和配置的更多详细信息,请访问