简体   繁体   English

如何在 Laravel 5 中压缩 HTML

[英]How do I compress HTML in laravel 5

In Laravel 4.0, I use the code below to compress the HTML laravel response outputs to browser, however it doesn't work in 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);
    }
});

Please how do i make this work in Laravel 5.请问我如何在 Laravel 5 中完成这项工作。

OR或者

Please provide a better way of compressing HTML in laravel 5 if any.如果有的话,请提供一种在 laravel 5 中压缩 HTML 的更好方法。 Thanks in advance.提前致谢。

NB: I don't wish to use any laravel package for compressing html, just need a simple code that does the work without killing performance.注意:我不希望使用任何 laravel 包来压缩 html,只需要一个简单的代码来完成工作而不会降低性能。

Complete code is this (with custom GZip enabled) :完整代码是这样的(启用自定义 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;
    }
}

Please check your browser network inspector for Content-Length header before/after implement this code.请在实施此代码之前/之后检查您的浏览器网络检查器的Content-Length标头。

enjoy it ... :).. .好好享受 ... :).. 。

It is not very good solution to minify html in middleware as you can spend a lot of CPU time on it and it runs on every request.在中间件中缩小 html 不是一个很好的解决方案,因为您可能会在它上面花费大量 CPU 时间并且它在每个请求上运行。

Instead it is better to use htmlmin package ( https://github.com/HTMLMin/Laravel-HTMLMin ):相反,最好使用 htmlmin 包( https://github.com/HTMLMin/Laravel-HTMLMin ):

composer require htmlmin/htmlmin
php artisan vendor:publish

Minifying HTML on blade template level and caching it in storage should be much more effective.在刀片模板级别缩小 HTML 并将其缓存在存储中应该更有效。

The recommended way to do this in Larvel 5 is to rewrite your function as middleware .在 Larvel 5 中推荐的方法是将你的函数重写为中间件 As stated in the docs:如文档中所述:

..this middleware would perform its task after the request is handled by the application: ..这个中间件将在应用程序处理请求执行其任务:

<?php namespace App\Http\Middleware;

class AfterMiddleware implements Middleware {

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

        // Perform action

        return $response;
    }
}

I have created a webpack plugin to solve same purpose.我创建了一个 webpack 插件来解决相同的目的。 MinifyHtmlWebpackPlugin MinifyHtmlWebpackPlugin

Install the plugin with npm:使用 npm 安装插件:

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

For Laravel Mix Users对于 Laravel Mix 用户

Paste below snippets into mix.js file.将以下片段粘贴到 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,
                }
            })
        ]
    });

It will minify all view files during the Webpack build.它会在 Webpack 构建期间缩小所有视图文件。

This is almost a copy of Vahid's answer but it fixes two problems.这几乎是Vahid答案的副本,但它解决了两个问题。

1) It checks if a response is a BinaryFileResponse as any attempt to modify this type of response will throw an Exception. 1) 它检查响应是否为BinaryFileResponse因为任何修改此类响应的尝试都将引发异常。

2) It retained newline characters as the complete elimination of newlines will lead to bad Javascript code on lines with single-line comment. 2) 它保留了换行符,因为完全消除换行符将导致在带有单行注释的行上出现错误的 Javascript 代码。

For example, the code below例如,下面的代码

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

Will become会变成

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

Note: At the time of this answer I couldn't get my hands on a good regex to match single line comments without complications or rather, ignore newlines on only lines with a single-line comment, so I'm hoping for a better fix.注意:在回答这个问题时,我无法使用一个好的正则表达式来匹配单行注释而不会出现并发症,或者更确切地说,仅忽略带有单行注释的行上的换行符,所以我希望有更好的修复.

Here's the modified version.这是修改后的版本。

<?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;
    }
  }
}

Edit编辑

Compressing output for every request using the middleware truly is really a bad idea, I recommend you check out this solution by Jokerius使用中间件为每个请求压缩输出确实是一个坏主意,我建议您查看Jokerius 的这个解决方案

Just in case you are rendering the view manually:以防万一您手动渲染视图:


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

在我看来,这个包是更好的选择renatomarinho/laravel-page-speed

I did it with very simple code.我用非常简单的代码做到了。 Example: welcome.blade.php示例:welcome.blade.php

Add the following code to the beginning of the page将以下代码添加到页面的开头

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

Add the following code to the end of the page:在页面末尾添加以下代码:

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

Full page code example:整页代码示例:

 <?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; } .mb-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 mb-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); }?>

this is best way.. we don't need to use laravel packeges .Thanks..这是最好的方法..我们不需要使用laravel packeges.谢谢..

 <?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; } }

For easy compression, I build my own laravel module.为了便于压缩,我构建了自己的 Laravel 模块。 This module will compress all the final html output before sending to the client (browser).该模块将在发送到客户端(浏览器)之前压缩所有最终的 html 输出。

You can also target multiple environment at a time using .env file.您还可以使用.env文件一次定位多个环境。

More details on how to install and configure will be found here可以在此处找到有关如何安装和配置的更多详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM