Come minimizzare l'output html della pagina php?


143

Sto cercando uno script o una classe php in grado di minimizzare l'output html della mia pagina php come fa la velocità della pagina di Google.

Come posso fare questo?


14
One-liner basato sulla risposta di @RakeshS:ob_start(function($b){return preg_replace(['/\>[^\S ]+/s','/[^\S ]+\</s','/(\s)+/s'],['>','<','\\1'],$b);});
Francisco Presencia,

5
@FranciscoPresencia È davvero una brutta cosa da fare. Stai rompendo tag di script, pre tag, ecc.
Brad

È vero, come notato nei suoi commenti di risposta con cui non funziona <pre>o <code>tag poiché hanno bisogno di spazi bianchi per una struttura adeguata. Tuttavia, <script>dovrebbe essere normalmente esterno o in linea ma utilizzato ;in modo rigoroso in modo che funzioni. Quali altri tag potrebbero rompere @Brad? Non riuscivo a pensare agli altri. Avrei dovuto aggiungere un modo rapido e sporco prima del mio commento precedente.
Francisco Presencia,

Risposte:


213

CSS e Javascript

Considera il seguente link per minimizzare i file Javascript / CSS: https://github.com/mrclay/minify

HTML

Di 'ad Apache di fornire HTML con GZip - questo generalmente riduce le dimensioni della risposta di circa il 70%. (Se usi Apache, il modulo che configura gzip dipende dalla tua versione: Apache 1.3 usa mod_gzip mentre Apache 2.x usa mod_deflate.)

Accetta-codifica: gzip, deflate

Codifica del contenuto: gzip

Utilizzare il frammento seguente per rimuovere gli spazi bianchi dall'HTML con il buffer della guida di ob_start:

<?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
Questa è una buona funzione, ma fai attenzione se usi i tag PRE , a volte le nuove righe verranno rimosse lì.
fedmich

2
Dove dovrebbe essere questo codice, nella parte superiore dello script o in fondo?
jdepypere,

8
Puoi anche usare la classe Minify_HTML da quella libreria di Minify ( $content = \Minify_HTML::minify($content);puoi anche aggiungere callback ai minificatori js / css per il codice inline). Vedi github.com/mrclay/minify/blob/master/min/lib/Minify/HTML.php
Barryvdh

21
Questo interrompe anche JavaScript <script>incorporato (cioè nei tag) che non ha ;alla fine di ogni affermazione o contiene commenti che usano//
Konstantin Pereiaslov

8
questo rimuoverà gli spazi da textarea, pre, input, img anche questo interrompe javascript in linea. se qualcuno non è felice di usare una lezione voluminosa con DOM che analizza questa soluzione basata su regexp funziona alla grande
Peter,

28

Attiva gzip se vuoi farlo correttamente. Puoi anche fare qualcosa del genere:

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

Questo rimuove circa il 30% delle dimensioni della pagina trasformando il tuo html in una riga, nessuna scheda, nessuna nuova riga, nessun commento. Il chilometraggio può variare


1
Fare entrambe le cose ridurrebbe ulteriormente la quantità di byte necessari.
Vaga per Nauta il

1
effettivamente fare entrambi è lo stesso di fare gzip, su una pagina di 700kb gzip lo porterà a circa 400kb e preg_replace () circa 450kb (tutto a seconda del contenuto) entrambi saranno come 399kb poiché gzip rimuove gli spazi uguali e poi lo comprime
dogmatic69,

18
Questo potrebbe essere potenzialmente pericoloso, dal momento che rimuoverebbe anche i condizionali IE ... - Dovresti cambiarlo in /<!--(?![if).*?-->/
Katai

3
Non funziona, rimuovendo troppo, rovinare il codice. Prima era valido W3C e dopo non lo è.
Codebeat

3
Sfortunatamente, rompe anche il codice Javascript, come per generare implementazioni più complesse di Google Maps - che è esattamente per cui avrei bisogno di una tale funzione.
Richey,

19

Tutte le preg_replace()soluzioni sopra hanno problemi di commenti a riga singola, commenti condizionali e altre insidie. Consiglierei di approfittare del collaudato progetto Minify piuttosto che creare il tuo regex da zero.

Nel mio caso inserisco il seguente codice nella parte superiore di una pagina PHP per minimizzarlo:

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
Il tuo codice non inserisce l'html in una riga
karadayi,

Leggi la prima domanda nelle FAQ del progetto Minify . TL; DR: ignorali.
Andrew,

Ho provato, non funziona. Ho sul mio file php, css tra tag <style> e javascript incorporato con php tra tag <script>
João Pimentel Ferreira,

dove si inserisce questo codice? ultimo nel piè di pagina o nell'intestazione?
Francesco,

@francesco Questo dovrebbe essere il primo pezzo di codice sulla tua pagina.
Andrew,

19

Ho provato diversi minificatori e rimuovono troppo poco o troppo.

Questo codice rimuove gli spazi vuoti ridondanti e i tag HTML (finali) opzionali. Inoltre lo gioca in modo sicuro e non rimuove nulla che potrebbe potenzialmente rompere HTML, JS o CSS.

Anche il codice mostra come farlo in Zend Framework:

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

Tuttavia, quando si utilizza la compressione gZip, il codice viene compresso molto più di qualsiasi minificazione, pertanto la combinazione di minificazione e gZip è inutile, poiché il tempo risparmiato dal download viene perso dalla minificazione e consente di risparmiare anche il minimo.

Ecco i miei risultati (download tramite rete 3G):

 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
Sì, sono d'accordo sul fatto che sia apparentemente inutile, ma può segnarti uno o due punti preziosi nella velocità della pagina per google, che è rilevante per il tuo posizionamento su Google. Il tuo codice è perfetto per rimuovere gli spazi non necessari. Grazie :-)
Tschallacka,

1
funziona alla grande, ho avuto problemi con = "/" quindi ho tolto / estratto da '~ ([\ r \ n \ t])? ([a-zA-Z0-9] +) = "([a-zA -Z0-9 _ / \\ -] +) "([\ r \ n \ t])? ~ S '=>' $ 1 $ 2 = $ 3 $ 4 ', // $ 1 e $ 4 inseriscono il primo carattere vuoto trovato prima / dopo l'attributo
ask_io

Beh, succede che non sto cercando di rimuovere gli spazi bianchi solo per velocizzare le cose, ma piuttosto perché è così che dovrebbe essere HTML in modo che le cose non si rovinino completamente, come elementi di blocco in linea, ma sto anche cercando uno capace di ignorare le cose che devono avere uno spazio prima o dopo (ad esempio elementi in grassetto in un blocco di testo).
Deji,

Ho riscontrato un problema con alcune cose di Jquery / Foundation ... a meno che non abbia commentato le seguenti righe: // rimuovi le righe "vuote" contenenti solo il carattere di fine blocco di JS; unisciti alla riga successiva (ad es. "} \ n} \ n </script>" -> "}} </script>" // '/} [\ r \ n \ t] + / s' => '} ', //' /} [\ r \ n \ t] +, [\ r \ n \ t] + / s '=>'}, ',
Ian

1
Se si utilizza la memorizzazione nella cache lato server (per me Smarty V3), min + gzip è una buona soluzione esclusa alla prima chiamata. Quindi, se dopo la quindicesima chiamata, sarà interessante per l'ora del server. regola = 40x15 = (30x15 + 150) Ma per la seconda chiamata sarà già più veloce per il visitatore.
Meloman,

6

Questo lavoro per me.

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

Crea un file PHP al di fuori della radice del documento. Se la radice del documento è

/var/www/html/

crea un file chiamato minify.php a un livello sopra di esso

/var/www/minify.php

Copia incolla il seguente codice PHP in esso

<?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");?>

Salvare il file minify.php e aprire il file php.ini. Se si tratta di una ricerca server / VPS dedicata per la seguente opzione, su hosting condiviso con php.ini personalizzato aggiungerlo.

auto_prepend_file = /var/www/minify.php

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



2

Puoi guardare in HTML TIDY - http://uk.php.net/tidy

Può essere installato come modulo PHP e rimuoverà (correttamente, in modo sicuro) gli spazi bianchi e tutte le altre cattiverie, pur generando un markup HTML / XHTML perfettamente valido. Pulirà anche il tuo codice, che può essere una cosa grandiosa o terribile, a seconda di quanto sei bravo a scrivere codice valido in primo luogo ;-)

Inoltre, è possibile decomprimere l'output utilizzando il seguente codice all'inizio del file:

ob_start('ob_gzhandler');

il problema è che il sito sarà ospitato su condiviso e non avrò accesso per installare tali moduli.
m3tsys,

È probabile che sarà già installato. Controlla phpinfo()... Almeno zlibdovrebbe essere installato consentendo di utilizzare il ob_gzhandler.
Rudi Visser,

già uso if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) ob_start("ob_gzhandler"); else ob_start();non è la stessa cosa?
m3tsys,

2
Sì, non hai davvero bisogno della else ob_start()parte, né il controllo gzip ... ob_gzhandlerrileva se il browser supporta internamente qualsiasi metodo di compressione. Basta avere ob_start('ob_gzhandler');sarà sufficiente.
Rudi Visser,

Qualche possibilità che TIDY sia più lento delle altre risposte qui a causa del sovraccarico di analisi extra? Potrebbe essere buono per lo sviluppo - quindi puoi correggere quegli errori HTML nel codice sorgente effettivo - ma mi chiedo se questa sia la scelta migliore per la produzione.
Matt Browne,

2

Prima di tutto, gzip può aiutarti più di un minimizer HTML

  1. Con 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. Con apache puoi usare mod_gzip

Secondo: con gzip + Html Minification puoi ridurre drasticamente le dimensioni del file !!!

Ho creato questo HtmlMinifier per PHP .

È possibile recuperare attraverso compositore: composer require arjanschouten/htmlminifier dev-master.

C'è un fornitore di servizi Laravel. Se non stai usando Laravel, puoi usarlo da PHP.

// 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();

Come puoi vedere puoi estendere un sacco di cose qui e puoi passare varie opzioni. Controlla il file Leggimi per vedere tutte le opzioni disponibili.

Questo HtmlMinifier è completo e sicuro. Sono necessari 3 passaggi per il processo di minificazione:

  1. Sostituisci temporaneamente i contenuti critici con un segnaposto.
  2. Esegui le strategie di minificazione.
  3. Ripristina il contenuto originale.

Suggerirei di memorizzare nella cache l'output delle visualizzazioni. Il processo di minificazione dovrebbe essere una volta. Oppure fallo ad esempio in base all'intervallo.

I benchmark chiari non sono stati creati al momento. Tuttavia, il minificatore può ridurre le dimensioni della pagina del 5-25% in base al markup!

Se vuoi aggiungere le tue strategie, puoi usare addPlaceholderi addMinifiermetodi e.


Grazie per la biblioteca Le istruzioni non dicono quali file PHP devo includere. Alla fine lo capirò, ma è qualcosa che probabilmente dovresti aggiungere sul tuo sito web.
acqua di rose

Sembra che richieda ancora Illuminate \ Support \ Collection. Non è una soluzione PHP indipendente.
acqua di rose

Grazie per il feedback! È un pacchetto compositore . Ho aggiornato il file Leggimi con la seguente regola: require __DIR__ . '/vendor/autoload.php';l'unica cosa che devi fare è includere questo file. Questo è generato dal compositore!
ArjanSchouten,

2

Ho una sintesi di GitHub contiene funzioni PHP per minimizzare i file HTML, CSS e JS → https://gist.github.com/taufik-nurrohman/d7b310dea3b33e4732c0

Ecco come minimizzare l'output HTML al volo con il buffer di output:

<?php

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

ob_start('minify_html');

?>

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

<?php echo ob_get_clean(); ?>

link gist conduce a una pagina 404
1111161171159459134

2
Aggiornato il collegamento.
Taufik Nurrohman,

1

Se si desidera rimuovere tutte le nuove righe nella pagina, utilizzare questo codice rapido:

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

0

Grazie a Andrew . Ecco cosa ha fatto per usarlo in cakePHP:

  1. Scarica minify-2.1.7
  2. Decomprimere il file e copiare la sottocartella minima nella cartella Venditore della torta
  3. Crea MinifyCodeHelper.php in View / Helper di cake in questo modo:

    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. Abilitato il mio aiuto in AppController

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

5 ... Voila!

La mia conclusione: se i moduli deflate e headers di apache sono disabilitati nel tuo server, il tuo guadagno è del 21% in meno di dimensioni e 0,35s più nella richiesta di compressione (questo numero era nel mio caso).

Ma se avessi abilitato i moduli di apache la risposta compressa non avrebbe differenze significative (1,3% per me) e il tempo di compressione è il samne (0,3 secondi per me).

Quindi ... perché l'ho fatto? 'uso del documento del mio progetto è tutto nei commenti (php, css e js) e il mio utente finale non ha bisogno di vedere questo;)


0

È possibile utilizzare un minificatore Java ben collaudato come HTMLCompressor invocandolo con passthru( exec).
Ricorda di reindirizzare la console utilizzando2>&1

Questo tuttavia potrebbe non essere utile, se la velocità è un problema. Lo uso per output php statico

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.