Bagaimana cara meminimalkan output html halaman php?

143

Saya mencari skrip atau kelas php yang dapat mengurangi output html halaman php saya seperti kecepatan halaman google.

Bagaimana saya bisa melakukan ini?

m3tsys
sumber
14
One-liner berdasarkan jawaban @RakeshS:ob_start(function($b){return preg_replace(['/\>[^\S ]+/s','/[^\S ]+\</s','/(\s)+/s'],['>','<','\\1'],$b);});
Francisco Presencia
5
@FranciscoPresencia Itu hal yang sangat buruk untuk dilakukan. Anda melanggar tag skrip, tag pra, dll.
Brad
Itu benar, seperti yang tercantum dalam komentar jawabannya tidak bekerja dengan <pre>atau <code>tag karena mereka membutuhkan ruang kosong untuk struktur yang tepat. Namun, <script>harus eksternal, atau sebaris tetapi menggunakan ;dengan cara yang ketat sehingga juga berfungsi. Tag lain mana yang mungkin merusak @Brad? Saya tidak bisa memikirkan orang lain. Saya seharusnya menambahkan cara yang cepat dan kotor sebelum komentar saya sebelumnya.
Francisco Presencia

Jawaban:

213

CSS dan Javascript

Pertimbangkan tautan berikut untuk memperkecil file Javascript / CSS: https://github.com/mrclay/minify

HTML

Beri tahu Apache untuk mengirim HTML dengan GZip - ini umumnya mengurangi ukuran respons sekitar 70%. (Jika Anda menggunakan Apache, modul yang mengonfigurasi gzip tergantung pada versi Anda: Apache 1.3 menggunakan mod_gzip sementara Apache 2.x menggunakan mod_deflate.)

Terima-Pengkodean: gzip, deflate

Content-Encoding: gzip

Gunakan cuplikan berikut untuk menghapus spasi putih dari HTML dengan bantuan buffer 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");

?>
Rakesh Sankar
sumber
54
Ini adalah fungsi yang baik tetapi berhati-hatilah jika Anda menggunakan tag PRE , kadang-kadang baris baru akan dihapus di sana.
fedmich
2
Di mana kode ini berada, di bagian atas skrip Anda atau di bagian bawah?
jdepypere
8
Anda juga dapat menggunakan kelas Minify_HTML dari pustaka Minify itu ( $content = \Minify_HTML::minify($content);, Anda bahkan dapat menambahkan panggilan balik ke js / css minifiers untuk kode inline). Lihat github.com/mrclay/minify/blob/master/min/lib/Minify/HTML.php
Barryvdh
21
Ini juga memecah JavaScript sebaris (yaitu dalam <script>tag) yang tidak ada ;di akhir setiap pernyataan atau memiliki komentar yang menggunakan//
Konstantin Pereiaslov
8
ini akan menghapus spasi dari textarea, pre, input, img juga ini memecah javascript inline. jika seseorang tidak senang menggunakan kelas besar dengan DOM mem-parsing solusi ini berdasarkan regexp works great
Peter
28

Nyalakan gzip jika Anda ingin melakukannya dengan benar. Anda juga dapat melakukan sesuatu seperti ini:

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

Ini menghapus sekitar 30% dari ukuran halaman dengan mengubah html Anda menjadi satu baris, tidak ada tab, tidak ada baris baru, tidak ada komentar. Jarak tempuh dapat bervariasi

dogmatic69
sumber
1
Melakukan keduanya akan menurunkan jumlah byte yang dibutuhkan lebih jauh.
Wander Nauta
1
sebenarnya melakukan keduanya sama dengan melakukan gzip, pada halaman 700kb gzip akan menurunkannya menjadi sekitar 400kb dan preg_replace () sekitar 450kb (semua tergantung pada konten) keduanya akan seperti 399kb karena gzip menghilangkan spasi sama dan kemudian kompres itu
dogmatic69
18
Ini bisa berpotensi berbahaya, karena itu juga akan menghapus persyaratan IE ... - Anda harus mengubahnya ke /<!--(?![if).*?-->/
Katai
3
Tidak berfungsi, menghapus terlalu banyak, mengacaukan kode. Sebelum itu W3C valid dan setelah ini tidak.
Codebeat
3
Sayangnya, itu juga merusak kode Javascript, seperti untuk menghasilkan implementasi yang lebih kompleks dari Google Maps - yang sebenarnya saya akan membutuhkan fungsi seperti itu untuk.
richey
19

Semua preg_replace()solusi di atas memiliki masalah komentar satu baris, komentar bersyarat dan perangkap lainnya. Saya akan merekomendasikan mengambil keuntungan dari proyek Minify yang teruji dengan baik daripada membuat regex Anda sendiri dari awal.

Dalam kasus saya, saya menempatkan kode berikut di bagian atas halaman PHP untuk memperkecilnya:

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');
Andrew
sumber
1
Kode Anda tidak menempatkan html ke dalam satu baris
karadayi
Baca pertanyaan pertama di Minify project FAQ . TL; DR: Abaikan mereka.
Andrew
Saya mencoba, itu tidak berhasil. Saya miliki di file php saya, css antara tag <style> dan javascript yang tertanam dengan php antara tag <script>
João Pimentel Ferreira
di mana Anda menempatkan kode ini? terakhir di footer atau header?
Francesco
@ francesco Ini harus menjadi bagian pertama dari kode di halaman Anda.
Andrew
19

Saya sudah mencoba beberapa minifiers dan mereka menghapus terlalu sedikit atau terlalu banyak.

Kode ini menghilangkan spasi kosong yang berlebihan dan tag HTML (akhir) opsional. Itu juga memainkannya dengan aman dan tidak menghapus apa pun yang berpotensi memecah HTML, JS atau CSS.

Kode juga menunjukkan cara melakukannya di 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);
  }
}

Tetapi perhatikan bahwa ketika menggunakan kompresi gZip, kode Anda akan dikompresi lebih banyak sehingga setiap minifikasi dapat melakukannya sehingga menggabungkan minification dan gZip tidak ada gunanya, karena waktu yang disimpan dengan mengunduh hilang oleh minifikasi dan juga menghemat minimum.

Inilah hasil saya (unduh melalui jaringan 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
Radek Pech
sumber
4
yup, saya setuju bahwa ini sepertinya tidak ada gunanya, tetapi dapat memberi Anda satu atau dua poin berharga dalam kecepatan halaman untuk google, yang relevan untuk peringkat Google Anda. Kode Anda sangat cocok untuk menghilangkan ruang yang tidak dibutuhkan. Terima kasih :-)
Tschallacka
1
ini berfungsi dengan baik, memiliki masalah dengan = "/" jadi saya mengambil / keluar dari '~ ([\ r \ n \ t])? ([a-zA-Z0-9] +) = "([a-zA -Z0-9 _ / \\ -] +) "([\ r \ n \ t])? ~ S '=>' $ 1 $ 2 = $ 3 $ 4 ', // $ 1 dan $ 4 masukkan karakter spasi putih pertama yang ditemukan sebelumnya / setelah atribut
asked_io
Yah seperti yang terjadi saya tidak ingin menghapus spasi hanya untuk mempercepat, tetapi karena itulah seharusnya HTML agar hal-hal tidak benar-benar kacau, seperti elemen blok inline, tapi saya juga mencari yang mampu mengabaikan hal-hal yang perlu memiliki satu ruang sebelum atau sesudah (misalnya, elemen tebal dalam blok teks).
Deji
Saya menemukan masalah dengan hal-hal Jquery / Foundation tertentu ... kecuali jika saya mengomentari baris berikut: // hapus baris "kosong" yang hanya berisi karakter akhir blok JS; bergabung dengan baris berikutnya (mis. "} \ n} \ n </script>" -> "}} </script>" // '/} [\ r \ n \ t] + / s' => '} ', //' /} [\ r \ n \ t] +, [\ r \ n \ t] + / s '=>'}, ',
Ian
1
Jika Anda menggunakan caching sisi server (bagi saya Smarty V3) min + gzip adalah solusi yang bagus kecuali pada panggilan pertama. Jadi, jika setelah panggilan ke-15, itu akan memotong waktu server. rule = 40x15 = (30x15 + 150) Tapi untuk panggilan kedua, itu sudah lebih cepat bagi pengunjung.
Meloman
6

Ini bekerja untuk saya.

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;
}
Mohamad Hamouday
sumber
5

Buat file PHP di luar root dokumen Anda. Jika root dokumen Anda

/var/www/html/

buat file bernama minify.php satu tingkat di atasnya

/var/www/minify.php

Salin tempel kode PHP berikut ke dalamnya

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

Simpan file minify.php dan buka file php.ini. Jika ini adalah pencarian dedicated server / VPS untuk opsi berikut, tambahkan hosting bersama dengan php.ini khusus.

auto_prepend_file = /var/www/minify.php

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

Avi Tyagi
sumber
2

Anda dapat melihat ke HTML TIDY - http://uk.php.net/tidy

Itu dapat diinstal sebagai modul PHP dan akan (dengan benar, aman) menghapus spasi putih dan semua kekesalan lainnya, sementara masih menghasilkan markup HTML / XHTML yang valid. Ini juga akan membersihkan kode Anda, yang bisa menjadi hal yang hebat atau yang mengerikan, tergantung pada seberapa baik Anda menulis kode yang valid di tempat pertama ;-)

Selain itu, Anda dapat gzip output menggunakan kode berikut di awal file Anda:

ob_start('ob_gzhandler');
Rudi Visser
sumber
masalahnya adalah bahwa situs tersebut akan di-host di shared dan saya tidak akan memiliki akses untuk menginstal modul tersebut.
m3tsys
Kemungkinannya, itu sudah akan diinstal. Periksa phpinfo()... Paling tidak zlibharus diinstal memungkinkan Anda untuk menggunakan ob_gzhandler.
Rudi Visser
saya sudah menggunakan if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) ob_start("ob_gzhandler"); else ob_start();bukan hal yang sama?
m3tsys
2
Ya itu, Anda benar-benar tidak memerlukan else ob_start()bagian itu, maupun pemeriksaan gzip ... ob_gzhandlermendeteksi apakah browser mendukung metode kompresi apa pun secara internal. Memiliki ob_start('ob_gzhandler');keinginan saja sudah cukup.
Rudi Visser
Adakah kemungkinan TIDY lebih lambat daripada jawaban lain di sini karena overhead parsing ekstra? Mungkin bagus untuk pengembangan - maka Anda dapat memperbaiki kesalahan HTML dalam kode sumber yang sebenarnya - tetapi saya mempertanyakan apakah ini adalah pilihan terbaik untuk produksi.
Matt Browne
2

Pertama-tama, gzip dapat membantu Anda lebih dari Html Minifier

  1. Dengan 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. Dengan apache Anda dapat menggunakan mod_gzip

Kedua: dengan gzip + Html Minification, Anda dapat mengurangi ukuran file secara drastis !!!

Saya telah membuat HtmlMinifier ini untuk PHP .

Anda dapat mengambilnya melalui komposer: composer require arjanschouten/htmlminifier dev-master.

Ada penyedia layanan Laravel. Jika Anda tidak menggunakan Laravel, Anda dapat menggunakannya dari 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();

Seperti yang Anda lihat, Anda dapat memperluas banyak hal di sini dan Anda dapat melewati berbagai opsi. Periksa readme untuk melihat semua opsi yang tersedia.

Ini HtmlMinifier selesai dan aman. Dibutuhkan 3 langkah untuk proses minifikasi:

  1. Ganti konten penting sementara dengan placeholder.
  2. Jalankan strategi minifikasi.
  3. Kembalikan konten asli.

Saya menyarankan agar Anda men-cache output dari pandangan Anda. Proses minifikasi harus merupakan proses satu kali. Atau lakukan misalnya berbasis interval.

Hapus benchmark tidak dibuat pada saat itu. Namun minifier dapat mengurangi ukuran halaman dengan 5-25% berdasarkan markup Anda!

Jika Anda ingin menambahkan strategi Anda sendiri, Anda dapat menggunakan addPlaceholderdan addMinifiermetode.

ArjanSchouten
sumber
Terima kasih untuk perpustakaannya. Instruksi tidak mengatakan file PHP apa yang perlu saya sertakan. Saya akhirnya akan mengetahuinya, tetapi itu adalah sesuatu yang mungkin harus Anda tambahkan di situs web Anda.
rosewater
Sepertinya masih membutuhkan Koleksi Illuminate \ Support \ Collection. Ini bukan solusi PHP yang berdiri sendiri.
rosewater
Terima kasih untuk umpan baliknya! Ini adalah paket komposer . Saya telah memperbarui readme dengan aturan berikut: require __DIR__ . '/vendor/autoload.php';Satu-satunya hal yang harus Anda lakukan adalah memasukkan file ini. Ini dihasilkan oleh komposer!
ArjanSchouten
2

Saya memiliki inti GitHub yang berisi fungsi PHP untuk memperkecil file HTML, CSS, dan JS → https://gist.github.com/taufik-nurrohman/d7b310dea3b33e4732c0

Berikut cara meminimalkan hasil HTML saat itu dengan buffer output:

<?php

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

ob_start('minify_html');

?>

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

<?php echo ob_get_clean(); ?>
Taufik Nurrohman
sumber
tautan inti mengarah ke halaman 404
1111161171159459134
2
Memperbarui tautannya.
Taufik Nurrohman
1

Jika Anda ingin menghapus semua baris baru di halaman, gunakan kode cepat ini:

ob_start(function($b){
if(strpos($b, "<html")!==false) {
return str_replace(PHP_EOL,"",$b);
} else {return $b;}
});
زياد
sumber
0

Terima kasih untuk Andrew . Inilah yang dilakukan untuk menggunakan ini di cakePHP:

  1. Unduh minify-2.1.7
  2. Buka paket file dan salin subfolder min ke folder Vendor cake
  3. Membuat MinifyCodeHelper.php dalam tampilan / Pembantu kue seperti ini:

    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. Diaktifkan Pembantu saya di AppController

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

5 ... Voila!

Kesimpulan saya: Jika modul deflate dan header apache dinonaktifkan di server Anda, keuntungan Anda adalah 21% lebih kecil dan 0,35 plus dalam permintaan kompres (angka ini ada dalam kasus saya).

Tetapi jika Anda telah mengaktifkan modul apache respon terkompresi tidak memiliki perbedaan yang signifikan (1,3% untuk saya) dan waktu untuk kompres adalah samne (0,3s kepada saya).

Jadi ... mengapa saya melakukan itu? 'buat dokumen proyek saya semuanya dalam komentar (php, css dan js) dan pengguna akhir saya tidak perlu melihat ini;)

bocapio
sumber
0

Anda dapat menggunakan Java minifier yang teruji dengan baik seperti HTMLCompressor dengan menjalankannya menggunakan passthru( exec).
Ingatlah untuk mengarahkan ulang konsol menggunakan2>&1

Namun ini mungkin tidak berguna, jika kecepatan menjadi perhatian. Saya menggunakannya untuk output php statis

Ujjwal Singh
sumber