Wie minimiere ich die HTML-Ausgabe der PHP-Seite?


143

Ich suche nach einem PHP-Skript oder einer PHP-Klasse, die meine HTML-Ausgabe auf PHP-Seiten wie die Geschwindigkeit von Google-Seiten minimieren kann.

Wie kann ich das machen?


14
Einzeiler basierend auf @ RakeshS Antwort:ob_start(function($b){return preg_replace(['/\>[^\S ]+/s','/[^\S ]+\</s','/(\s)+/s'],['>','<','\\1'],$b);});
Francisco Presencia

5
@FranciscoPresencia Das ist eine wirklich schlechte Sache. Sie brechen Skript-Tags, Pre-Tags usw.
Brad

Das stimmt, wie in seinen Antwortkommentaren erwähnt, funktioniert es nicht mit <pre>oder <code>Tags, da sie das Leerzeichen für die richtige Struktur benötigen. Das <script>sollte jedoch normalerweise extern oder inline sein, aber ;streng verwendet werden, damit es auch funktioniert. Welche anderen Tags könnten @Brad kaputt machen? Ich konnte nicht an andere denken. Ich hätte jedoch schnell und schmutzig vor meinem vorherigen Kommentar hinzufügen sollen .
Francisco Presencia

Antworten:


212

CSS und Javascript

Betrachten Sie den folgenden Link, um Javascript / CSS-Dateien zu minimieren: https://github.com/mrclay/minify

HTML

Weisen Sie Apache an, HTML mit GZip bereitzustellen. Dadurch wird die Antwortgröße im Allgemeinen um etwa 70% reduziert. (Wenn Sie Apache verwenden, hängt das Modul, das gzip konfiguriert, von Ihrer Version ab: Apache 1.3 verwendet mod_gzip, während Apache 2.x mod_deflate verwendet.)

Accept-Encoding: gzip, entleeren

Inhaltskodierung: gzip

Verwenden Sie das folgende Snippet , um Leerzeichen mit dem Puffer der Hilfe ob_start aus dem HTML-Code zu entfernen:

<?php

function sanitize_output($buffer) {

    $search = array(
        '/\>[^\S ]+/s',     // strip whitespaces after tags, except space
        '/[^\S ]+\</s',     // strip whitespaces before tags, except space
        '/(\s)+/s',         // shorten multiple whitespace sequences
        '/<!--(.|\s)*?-->/' // Remove HTML comments
    );

    $replace = array(
        '>',
        '<',
        '\\1',
        ''
    );

    $buffer = preg_replace($search, $replace, $buffer);

    return $buffer;
}

ob_start("sanitize_output");

?>

54
Dies ist eine gute Funktion, aber seien Sie vorsichtig, wenn Sie PRE- Tags verwenden. Manchmal werden dort Zeilenumbrüche entfernt.
Fedmich

2
Wo sollte dieser Code oben in Ihrem Skript oder unten sein?
Jdepypere

8
Sie können auch die Minify_HTML-Klasse aus dieser Minify-Bibliothek verwenden ( $content = \Minify_HTML::minify($content);Sie können js / css-Minifizierern sogar Rückrufe für Inline-Code hinzufügen). Siehe github.com/mrclay/minify/blob/master/min/lib/Minify/HTML.php
Barryvdh

21
Dies bricht auch Inline-JavaScript (dh in <script>Tags), das nicht ;am Ende jeder Anweisung steht oder Kommentare enthält//
Konstantin Pereiaslov

8
Dadurch werden Leerzeichen aus dem Textbereich, Pre, Input und Img entfernt. Außerdem werden Inline-Javascripts unterbrochen. Wenn jemand nicht glücklich ist, sperrige Klasse mit DOM zu verwenden, funktioniert das Parsen dieser auf Regexp basierenden Lösung großartig
Peter

28

Aktivieren Sie gzip, wenn Sie es richtig machen möchten. Sie können auch einfach so etwas tun:

$this->output = preg_replace(
    array(
        '/ {2,}/',
        '/<!--.*?-->|\t|(?:\r?\n[ \t]*)+/s'
    ),
    array(
        ' ',
        ''
    ),
    $this->output
);

Dadurch werden etwa 30% der Seitengröße entfernt, indem Ihr HTML-Code in eine Zeile umgewandelt wird, keine Registerkarten, keine neuen Zeilen, keine Kommentare. Der Kilometerstand kann variieren


1
Wenn Sie beides tun, wird die Anzahl der benötigten Bytes noch weiter reduziert.
Wander Nauta

1
Beides zu tun ist dasselbe wie gzip. Auf einer 700-KB-Seite reduziert gzip es auf ungefähr 400 KB und preg_replace () auf ungefähr 450 KB (alle abhängig vom Inhalt). Beide sind wie 399 KB, da gzip die Leerzeichen gleich entfernt und dann komprimiert es
dogmatisch69

18
Dies könnte möglicherweise gefährlich sein, da dadurch auch IE-Bedingungen entfernt werden ... - Sie müssten es in /<!--(?![if).*?-->/
Katai

3
Funktioniert nicht, zu viel entfernen, den Code durcheinander bringen. Vorher war W3C gültig und danach nicht mehr.
Codebeat

3
Leider bricht es auch Javascript-Code, etwa um komplexere Implementierungen von Google Maps zu generieren - genau dafür würde ich eine solche Funktion benötigen.
Richey

19

Alle preg_replace()oben genannten Lösungen weisen Probleme mit einzeiligen Kommentaren, bedingten Kommentaren und anderen Fallstricken auf. Ich würde empfehlen, das bewährte Minify-Projekt zu nutzen, anstatt Ihren eigenen regulären Ausdruck von Grund auf neu zu erstellen.

In meinem Fall platziere ich den folgenden Code oben auf einer PHP-Seite, um ihn zu minimieren:

function sanitize_output($buffer) {
    require_once('min/lib/Minify/HTML.php');
    require_once('min/lib/Minify/CSS.php');
    require_once('min/lib/JSMin.php');
    $buffer = Minify_HTML::minify($buffer, array(
        'cssMinifier' => array('Minify_CSS', 'minify'),
        'jsMinifier' => array('JSMin', 'minify')
    ));
    return $buffer;
}
ob_start('sanitize_output');

1
Ihr Code setzt das HTML nicht in eine Zeile
Karadayi

Lesen Sie die erste Frage in den häufig gestellten Fragen zum Minify-Projekt . TL; DR: Ignoriere sie.
Andrew

Ich habe es versucht, es funktioniert nicht. Ich habe auf meiner PHP-Datei CSS zwischen <style> -Tags und Javascript eingebettet mit PHP zwischen <script> -Tags
João Pimentel Ferreira

Wo platzieren Sie diesen Code? zuletzt in der Fußzeile oder Kopfzeile?
Francesco

@francesco Dies sollte der allererste Code auf Ihrer Seite sein.
Andrew

19

Ich habe mehrere Minifikatoren ausprobiert, die entweder zu wenig oder zu viel entfernen.

Dieser Code entfernt redundante Leerzeichen und optionale HTML-Tags (Ending-Tags). Außerdem geht es auf Nummer sicher und entfernt nichts, was möglicherweise HTML, JS oder CSS beschädigen könnte.

Der Code zeigt auch, wie das in Zend Framework geht:

class Application_Plugin_Minify extends Zend_Controller_Plugin_Abstract {

  public function dispatchLoopShutdown() {
    $response = $this->getResponse();
    $body = $response->getBody(); //actually returns both HEAD and BODY

    //remove redundant (white-space) characters
    $replace = array(
        //remove tabs before and after HTML tags
        '/\>[^\S ]+/s'   => '>',
        '/[^\S ]+\</s'   => '<',
        //shorten multiple whitespace sequences; keep new-line characters because they matter in JS!!!
        '/([\t ])+/s'  => ' ',
        //remove leading and trailing spaces
        '/^([\t ])+/m' => '',
        '/([\t ])+$/m' => '',
        // remove JS line comments (simple only); do NOT remove lines containing URL (e.g. 'src="http://server.com/"')!!!
        '~//[a-zA-Z0-9 ]+$~m' => '',
        //remove empty lines (sequence of line-end and white-space characters)
        '/[\r\n]+([\t ]?[\r\n]+)+/s'  => "\n",
        //remove empty lines (between HTML tags); cannot remove just any line-end characters because in inline JS they can matter!
        '/\>[\r\n\t ]+\</s'    => '><',
        //remove "empty" lines containing only JS's block end character; join with next line (e.g. "}\n}\n</script>" --> "}}</script>"
        '/}[\r\n\t ]+/s'  => '}',
        '/}[\r\n\t ]+,[\r\n\t ]+/s'  => '},',
        //remove new-line after JS's function or condition start; join with next line
        '/\)[\r\n\t ]?{[\r\n\t ]+/s'  => '){',
        '/,[\r\n\t ]?{[\r\n\t ]+/s'  => ',{',
        //remove new-line after JS's line end (only most obvious and safe cases)
        '/\),[\r\n\t ]+/s'  => '),',
        //remove quotes from HTML attributes that does not contain spaces; keep quotes around URLs!
        '~([\r\n\t ])?([a-zA-Z0-9]+)="([a-zA-Z0-9_/\\-]+)"([\r\n\t ])?~s' => '$1$2=$3$4', //$1 and $4 insert first white-space character found before/after attribute
    );
    $body = preg_replace(array_keys($replace), array_values($replace), $body);

    //remove optional ending tags (see http://www.w3.org/TR/html5/syntax.html#syntax-tag-omission )
    $remove = array(
        '</option>', '</li>', '</dt>', '</dd>', '</tr>', '</th>', '</td>'
    );
    $body = str_ireplace($remove, '', $body);

    $response->setBody($body);
  }
}

Beachten Sie jedoch, dass bei Verwendung der gZip-Komprimierung Ihr Code viel stärker komprimiert wird, als dies bei jeder Minifizierung möglich ist. Die Kombination von Minifizierung und gZip ist sinnlos, da durch das Herunterladen eingesparte Zeit durch die Minimierung verloren geht und außerdem nur ein Minimum gespart wird.

Hier sind meine Ergebnisse (Download über 3G-Netzwerk):

 Original HTML:        150kB       180ms download
 gZipped HTML:          24kB        40ms
 minified HTML:        120kB       150ms download + 150ms minification
 min+gzip HTML:         22kB        30ms download + 150ms minification

4
Ja, ich stimme zu, dass es scheinbar sinnlos ist, aber es kann Ihnen ein oder zwei wertvolle Punkte in der Seitengeschwindigkeit für Google einbringen, was für Ihr Google-Ranking relevant ist. Ihr Code ist perfekt, um nicht benötigte Leerzeichen zu entfernen. Danke :-)
Tschallacka

1
Das funktioniert großartig, hatte Probleme mit = "/", also habe ich das / aus '~ ([\ r \ n \ t]) genommen? ([a-zA-Z0-9] +) = "([a-zA -Z0-9 _ / \\ -] +) "([\ r \ n \ t])? ~ S '=>' $ 1 $ 2 = $ 3 $ 4 ', // $ 1 und $ 4 fügen das erste vor / gefundene Leerzeichen ein nach Attribut
fragte_io

Nun, es geht nicht darum, Leerzeichen zu entfernen, nur um die Dinge zu beschleunigen, sondern weil HTML so sein sollte , damit die Dinge nicht völlig durcheinander geraten, wie Inline-Blockelemente, aber ich suche auch nach einem fähigen Dinge zu ignorieren, die ein Leerzeichen davor oder danach haben müssen (z. B. fette Elemente in einem Textblock).
Deji

Ich habe ein Problem mit bestimmten Jquery / Foundation-Inhalten gefunden ... es sei denn, ich habe die folgenden Zeilen auskommentiert: // "leere" Zeilen entfernen, die nur das Blockende-Zeichen von JS enthalten; mit der nächsten Zeile verbinden (zB "} \ n} \ n </ script>" -> "}} </ script>" // '/} [\ r \ n \ t] + / s' => '} ', //' /} [\ r \ n \ t] +, [\ r \ n \ t] + / s '=>'}, ',
Ian

1
Wenn Sie serverseitiges Caching verwenden (für mich Smarty V3), ist min + gzip eine gute Lösung, außer beim ersten Aufruf. Wenn es also nach dem 15. Aufruf interessant für die Serverzeit ist. Regel = 40x15 = (30x15 + 150) Aber für den zweiten Anruf ist es für Besucher bereits schneller.
Meloman

6

Diese Arbeit für mich.

function Minify_Html($Html)
{
   $Search = array(
    '/(\n|^)(\x20+|\t)/',
    '/(\n|^)\/\/(.*?)(\n|$)/',
    '/\n/',
    '/\<\!--.*?-->/',
    '/(\x20+|\t)/', # Delete multispace (Without \n)
    '/\>\s+\</', # strip whitespaces between tags
    '/(\"|\')\s+\>/', # strip whitespaces between quotation ("') and end tags
    '/=\s+(\"|\')/'); # strip whitespaces between = "'

   $Replace = array(
    "\n",
    "\n",
    " ",
    "",
    " ",
    "><",
    "$1>",
    "=$1");

$Html = preg_replace($Search,$Replace,$Html);
return $Html;
}

5

Erstellen Sie eine PHP-Datei außerhalb Ihres Dokumentstamms. Wenn Ihr Dokumentenstamm ist

/var/www/html/

Erstellen Sie eine Datei mit dem Namen minify.php eine Ebene darüber

/var/www/minify.php

Kopieren Sie den folgenden PHP-Code und fügen Sie ihn ein

<?php
function minify_output($buffer){
    $search = array('/\>[^\S ]+/s','/[^\S ]+\</s','/(\s)+/s');
    $replace = array('>','<','\\1');
    if (preg_match("/\<html/i",$buffer) == 1 && preg_match("/\<\/html\>/i",$buffer) == 1) {
        $buffer = preg_replace($search, $replace, $buffer);
    }
    return $buffer;
}
ob_start("minify_output");?>

Speichern Sie die Datei minify.php und öffnen Sie die Datei php.ini. Wenn es sich um einen dedizierten Server / VPS handelt, suchen Sie nach der folgenden Option, und fügen Sie sie beim Shared Hosting mit der benutzerdefinierten php.ini hinzu.

auto_prepend_file = /var/www/minify.php

Referenz: http://websistent.com/how-to-use-php-to-minify-html-output/



2

Sie können in HTML TIDY - http://uk.php.net/tidy schauen

Es kann als PHP-Modul installiert werden und entfernt (korrekt, sicher) Leerzeichen und alle anderen Unannehmlichkeiten, während weiterhin ein perfekt gültiges HTML / XHTML-Markup ausgegeben wird. Es wird auch Ihren Code bereinigen, was eine großartige oder eine schreckliche Sache sein kann, je nachdem, wie gut Sie überhaupt in der Lage sind, gültigen Code zu schreiben ;-)

Darüber hinaus können Sie die Ausgabe mit dem folgenden Code am Anfang Ihrer Datei gzipen:

ob_start('ob_gzhandler');

Das Problem ist, dass die Site auf Shared gehostet wird und ich keinen Zugriff auf die Installation solcher Module habe.
m3tsys

Wahrscheinlich wird es bereits installiert. Überprüfen Sie phpinfo()... Zumindest zlibsollte installiert sein, damit Sie die verwenden können ob_gzhandler.
Rudi Visser

Ich benutze schon, if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) ob_start("ob_gzhandler"); else ob_start();ist es nicht dasselbe?
m3tsys

2
Ja, Sie benötigen weder das else ob_start()Teil noch die gzip-Prüfung ... ob_gzhandlererkennt, ob der Browser intern eine Komprimierungsmethode unterstützt. Einfach zu haben ob_start('ob_gzhandler');wird ausreichen.
Rudi Visser

Gibt es eine Möglichkeit, dass TIDY aufgrund des zusätzlichen Analyseaufwands langsamer ist als die anderen Antworten hier? Könnte gut für die Entwicklung sein - dann können Sie diese HTML-Fehler im eigentlichen Quellcode korrigieren - aber ich frage mich, ob dies die beste Wahl für die Produktion ist.
Matt Browne

2

Zuallererst kann gzip Ihnen mehr als nur einen HTML-Minifier helfen

  1. Mit Nginx :

    gzip on;
    gzip_disable "msie6";
    
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
  2. Mit Apache können Sie mod_gzip verwenden

Zweitens: Mit gzip + Html Minification können Sie die Dateigröße drastisch reduzieren !!!

Ich habe diesen HtmlMinifier für PHP erstellt .

Sie können es über Composer abrufen : composer require arjanschouten/htmlminifier dev-master.

Es gibt einen Laravel-Dienstleister. Wenn Sie Laravel nicht verwenden, können Sie es über PHP verwenden.

// create a minify context which will be used through the minification process
$context = new MinifyContext(new PlaceholderContainer());
// save the html contents in the context
$context->setContents('<html>My html...</html>');
$minify = new Minify();
// start the process and give the context with it as parameter
$context = $minify->run($context);

// $context now contains the minified version
$minifiedContents = $context->getContents();

Wie Sie sehen können, können Sie hier viele Dinge erweitern und verschiedene Optionen übergeben. Überprüfen Sie die Readme-Datei , um alle verfügbaren Optionen anzuzeigen.

Dieser HtmlMinifier ist vollständig und sicher. Der Minifizierungsprozess dauert 3 Schritte:

  1. Ersetzen Sie kritische Inhalte vorübergehend durch einen Platzhalter.
  2. Führen Sie die Minimierungsstrategien aus.
  3. Stellen Sie den ursprünglichen Inhalt wieder her.

Ich würde vorschlagen, dass Sie die Ausgabe Ihrer Ansichten zwischenspeichern. Der Minifizierungsprozess sollte ein einmaliger Prozess sein. Oder machen Sie es zum Beispiel intervallbasiert.

Es werden derzeit keine eindeutigen Benchmarks erstellt. Der Minifier kann jedoch die Seitengröße basierend auf Ihrem Markup um 5-25% reduzieren!

Wenn Sie Ihre eigenen Strategien hinzufügen möchten, können Sie die addPlaceholderund die addMinifierMethoden verwenden.


Danke für die Bibliothek. Die Anweisungen sagen nicht, welche PHP-Dateien ich einschließen muss. Ich werde es irgendwann herausfinden, aber das sollten Sie wahrscheinlich auf Ihrer Website hinzufügen.
Rosenwasser

Es sieht so aus, als ob Illuminate \ Support \ Collection weiterhin erforderlich ist. Es ist keine eigenständige PHP-Lösung.
Rosenwasser

Danke für die Rückmeldung! Es ist ein Komponistenpaket . Ich habe die Readme-require __DIR__ . '/vendor/autoload.php'; Datei mit der folgenden Regel aktualisiert : Sie müssen nur diese Datei einschließen. Dies wird vom Komponisten generiert!
ArjanSchouten

2

Ich habe ein GitHub- Gist, das PHP-Funktionen zum Minimieren von HTML-, CSS- und JS-Dateien enthält → https://gist.github.com/taufik-nurrohman/d7b310dea3b33e4732c0

So minimieren Sie die HTML-Ausgabe im laufenden Betrieb mit dem Ausgabepuffer:

<?php

include 'path/to/php-html-css-js-minifier.php';

ob_start('minify_html');

?>

<!-- HTML code goes here ... -->

<?php echo ob_get_clean(); ?>

Der Hauptlink führt zu einer 404-Seite
1111161171159459134

2
Der Link wurde aktualisiert.
Taufik Nurrohman

1

Wenn Sie alle neuen Zeilen auf der Seite entfernen möchten, verwenden Sie diesen Schnellcode:

ob_start(function($b){
if(strpos($b, "<html")!==false) {
return str_replace(PHP_EOL,"",$b);
} else {return $b;}
});

0

Danke an Andrew . Folgendes wurde getan, um dies in cakePHP zu verwenden:

  1. Laden Sie minify-2.1.7 herunter
  2. Entpacken Sie die Datei und kopieren Sie den Unterordner min in den Vendor-Ordner von pie
  3. Erstellt MinifyCodeHelper.php in View / Helper von pie wie folgt:

    App::import('Vendor/min/lib/Minify/', 'HTML');
    App::import('Vendor/min/lib/Minify/', 'CommentPreserver');
    App::import('Vendor/min/lib/Minify/CSS/', 'Compressor');
    App::import('Vendor/min/lib/Minify/', 'CSS');
    App::import('Vendor/min/lib/', 'JSMin');
    class MinifyCodeHelper extends Helper {
        public function afterRenderFile($file, $data) {
            if( Configure::read('debug') < 1 ) //works only e production mode
                $data = Minify_HTML::minify($data, array(
                    'cssMinifier' => array('Minify_CSS', 'minify'),
                    'jsMinifier' => array('JSMin', 'minify')
                ));
            return $data;
        }
    }
  4. Aktiviert meinen Helfer in AppController

    public $ helpers = array ('Html', '...', 'MinifyCode');

5 ... Voila!

Mein Fazit: Wenn die Deflate- und Header-Module von Apache auf Ihrem Server deaktiviert sind, ist Ihr Gewinn 21% geringer und 0,35 Sekunden plus bei der Anforderung der Komprimierung (diese Zahlen waren in meinem Fall).

Wenn Sie jedoch die Apache-Module aktiviert haben, hat die komprimierte Antwort keinen signifikanten Unterschied (1,3% für mich) und die Zeit zum Komprimieren ist die gleiche (0,3 Sekunden für mich).

Also ... warum habe ich das getan? 'couse das Dokument meines Projekts ist alles in Kommentaren (PHP, CSS und JS) und mein Endbenutzer muss dies nicht sehen;)


0

Sie können einen gut getesteten Java-Minifier wie HTMLCompressor verwenden, indem Sie ihn mit passthru( exec) aufrufen .
Denken Sie daran, die Konsole mit umzuleiten2>&1

Dies ist jedoch möglicherweise nicht sinnvoll, wenn die Geschwindigkeit ein Problem darstellt. Ich benutze es für statische PHP-Ausgabe

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.