Du bist nicht angemeldet. Der Zugriff auf einige Boards wurde daher deaktiviert.

#1 07. Oktober 2011 20:13

piratos
arbeitet mit CMS/ms
Registriert: 12. August 2011
Beiträge: 545

HTML Compressor für die index.php

Ein paar Zeilen Code und schon geht die Standardinstallation bei Pagespeed bezüglich HTML Größe aus den Meckerbereich.


[== php ==]
$html = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $html);
$html = str_replace(array("\r\n", "\r", "\n", "\t"), '', $html);
$html = str_replace(array('  ', '    ', '    ', ' } )', '" /> ', '<br />', ';</p>  </div>', '</div> <p>', '( { ', '"> <', ' }, { parameters: arguments}); }'), array(' ', ' ', ' ', '})', '"/> ', '<br/>', ';</p></div>', '</div><p>', '({', '"><', '},{parameters:arguments});}'), $html);
# HIer die normale Originalausgabe
echo $html;

Beitrag geändert von piratos (07. Oktober 2011 20:14)

Offline

#2 07. Oktober 2011 20:27

NaN
Moderator
Ort: Halle (Saale)
Registriert: 09. November 2010
Beiträge: 4.437

Re: HTML Compressor für die index.php

Man kann doch auch einfach das Template zwischen {strip} ... {/strip} packen.
Oder einfach einen Postfilter einsetzen.
Für sowas muss man nichts an der index.php ändern.


Module: GBFilePicker, AdvancedContent
Sicherheit: Beispiel .htaccess-Datei
CMSms 1.12 unter PHP 7:
cmsms-1.12.3.zip (inoffiziell - komplett inkl. Installer)
CMSms 1.12 unter PHP 8:
cmsms-1.12.4.zip (inoffiziell - komplett inkl. Installer)

Offline

#3 08. Oktober 2011 22:21

piratos
arbeitet mit CMS/ms
Registriert: 12. August 2011
Beiträge: 545

Re: HTML Compressor für die index.php

strip hat mehrere Nachteile:

1. does not affect the contents of template variables
2. compression ist geringer, man kommt selten aus der Meckerzone
3. langsam weil modifierer, man erreicht schlechte Werte für first byte time

Offline

#4 08. Oktober 2011 23:28

NaN
Moderator
Ort: Halle (Saale)
Registriert: 09. November 2010
Beiträge: 4.437

Re: HTML Compressor für die index.php

Naja, also zu erstens kann ich nur sagen, dass manche Leerzeichen eben gewollt sind.
(Bsp. in Textareas, in <pre> oder <code> ...)
Aber egal. First Byte Time ist ein guter Punkt.

Ich verstehe allerdings diesen Part nicht ganz:

$html = str_replace(array('  ', '    ', '    ', [...] ), array(' ', ' ', ' ' [...] ));

Das erste ist klar, doppelte Leerzeichen durch ein einzelnes ersetzen.
Aber die anderen beiden?
Wozu jetzt noch zweimal nach vier Leerzeichen suchen?
Hat da das Forum irgendwas zerschossen?

Wäre hier ein preg_replace('/\s+/', ' ', $html); nicht besser?
Wäre zwar langsamer, aber dafür genauer.

Abgesehen davon zerschießt Dein Code leider einige inline Scripts.


Module: GBFilePicker, AdvancedContent
Sicherheit: Beispiel .htaccess-Datei
CMSms 1.12 unter PHP 7:
cmsms-1.12.3.zip (inoffiziell - komplett inkl. Installer)
CMSms 1.12 unter PHP 8:
cmsms-1.12.4.zip (inoffiziell - komplett inkl. Installer)

Offline

#5 08. Oktober 2011 11:35

piratos
arbeitet mit CMS/ms
Registriert: 12. August 2011
Beiträge: 545

Re: HTML Compressor für die index.php

Also mal zur Einleitung.
Es kommt NICHT darauf an möglichst alles was überflüssig ist zu entfernen, denn dann würde der Aufwand höher sein als der echte Nutzen.
Der Nutzen besteht darin, HTML in einer Menge auszuliefern, welche die höchstmögliche Geschwindigkeit beim Nutzer erzeugt - sprich Besucher.
Geht  die Endgeschwindigkeit bei höherem Kompressionsaufwand runter ist die Kompression übertrieben und sorgt dafür das es nun langsamer wird.

Es gibt Kompressoren auch welche die auf Basis C erstellt wurden die pusten alles weg was überflüssig ist, dafür benötigen sie aber länger als wenn man eine Seite ohne Kompression direkt ausliefert.

Die Entfernung von Leerzeichen kann man so oder so probieren.

Tatsächlich immer korrekt ist wenn man '  ' ==2 x leer    4 mal entfernt (bis 16 Leerzeichen)

[== php ==]
$test=str_pad(' ', 13);
echo 'Start:'.strlen($test).'|';
$test =str_replace('  ',' ',$test);
echo ' Erste Kürzung:  '.strlen($test);          
$test =str_replace('  ',' ',$test);
echo ' | Zweite Kürzung:  '.strlen($test);          
$test =str_replace('  ',' ',$test);
echo ' | Dritte Kürzung:  '.strlen($test);          
$test=str_pad(' ', 13);
echo '<br/>Start mit 4 Kürzungen:'.strlen($test).'|';
$test =str_replace(array('  ','  ','  ','  '),array(' ',' ',' ',' '),$test);
echo ' Array Kürzung  (4x):  '.strlen($test);          

Die Kompressionscode ist nun

[== php ==]
$html = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $html);
        $html = str_replace(array("\r\n", "\r", "\n", "\t"), '', $html);
        echo  str_replace(array('  ','  ','  ','  ',' } )','" /> ','<br />',';</p>  </div>','</div> <p>','( { ','"> <',' }, { parameters: arguments}); }','" >','</li>  <li>','.</li> </ul>','</div> <div','>  <','() { return xajax',' = function','>  <','> <'), array(' ',' ',' ',' ','})','"/> ','<br/>',';</p></div>','</div><p>','({','"><','},{parameters:arguments});}','" >','</li><li>','.</li></ul>','</div><div','>  <','(){return xajax','=function','><','><'), $html);

aber auch da sind Bestandteile enthalten, die nicht in allen Sites wirken werden, da nie vorhanden - aber da reden wir bei 50KB HTML über Mikrosekunden pro Teil.

NaN schrieb:

Abgesehen davon zerschießt Dein Code leider einige inline Scripts.

Bislang habe ich da rein nichts feststellen können, weder bei js inliner noch bei heftigen CSS Inlinern bzw. beides kombiniert, aber irgendwann ist es immer das erste Mal.
Wäre nett wenn du da mal einen solchen Inliner posten könntest oder auf eine Seite zeigen kannst wo das der Fall wäre.

Beitrag geändert von piratos (08. Oktober 2011 12:05)

Offline

#6 08. Oktober 2011 12:18

NaN
Moderator
Ort: Halle (Saale)
Registriert: 09. November 2010
Beiträge: 4.437

Re: HTML Compressor für die index.php

Das Script was bei mir dann nicht mehr lief war dieses hier:

jsLoader.load({
    url: '{/literal}{uploads_url}{literal}/template/js/jq.min.js',
    ready: function() { 
        return(typeof jQuery == 'function');
    },
    callBack: function(ready) { 
        if(ready){
            jQuery.noConflict();
            jQuery(document).ready(function() {
                weta = {
                    ajaxLoad: function(url, target) {
                        if (typeof target == 'string') { 
                            target = jQuery(target);
                        }
                        else if(typeof target == 'object' && typeof target.jquery == 'undefined') { 
                            target = jQuery(target);
                        }

                        //display loading indicator
                        jQuery('.loading_indicator').remove();
                        target.append('<div class="loading_indicator" style="width:100%;height:100%;left:0;top:0;position:absolute;background: url({/literal}{uploads_url}{literal}/template/images/ajax-loader.gif) center no-repeat #E9E9EA;opacity:0.7"></div>');

                        var regExp = /mact=(\w+),(\w+),(\w+),\d/;
                        var result = regExp.exec(url);
                        if(result != null){
                            var newUrl = url.replace(regExp,'mact='+result[1]+',cntnt01,'+result[3]+',0').replace(new RegExp(result[2],'g'),'cntnt01')+'&showtemplate=false';
                            jQuery.get(newUrl, function(data) { 
                                target.html(data);

                                //hide loading indicator
                                jQuery('.loading_indicator').remove();

                                if(typeof jQuery().fancybox != 'undefined') { 
                                    jQuery("a.group").fancybox({'speedIn':300,'speedOut':300,'overlayColor':'#000000','overlayOpacity':0.7});
                                }
                            });
                            return false;
                        }
                    }
                };
                var ajaxLinks = jQuery('#content a.ajax_link');
                ajaxLinks.live('click',function() {
                    weta.ajaxLoad(this.href, jQuery(this).parents('div.wrapper:first'));
                    return false;
                });
            });
        }
    }
});

Hier auf meiner "Spielwiese".
Die Fehlerkonsole meldet dann immer "missing } after function body" was ich selber nicht so richtig nachvollziehen kann.
Hab Deinen Code da jetzt nicht mehr drin sondern nutze wieder {strip}. Da ich das aber in allen Templates nutzen muss (also auch in allen Modul-Templates) würde ich lieber darauf verzichten und die gesamte Ausgabe am Ende in einem Rutsch komprimieren.
Falls Du die Seite jetzt gleich auf ihre Performance analysierst, da habe ich derzeit auch noch arge Probleme mit 1st byte time - die Bildgrößen sind da erstmal zu vernachlässigen, weil nicht das Hauptproblem bzw. leicht zu beseitigen. Die Antwortzeit vom Server ist da für mich gravierender.

Mal noch eine blöde Frage, wenn ich die Index.php modifiziere, dann wird doch die Komprimierung jedesmal erneut vorgenommen. Wenn ich mit {strip} oder einem Postfilter arbeite, sollte das komprimierte Template doch auch komprimiert im Cache landen und nicht jedesmal erneut komprimiert werden. Hebt sich da der Geschwindigkeitsnachteil eines Modifiers bzw. Postfilters gegenüber der Änderung an der index.php auf Dauer nicht wieder auf?


Module: GBFilePicker, AdvancedContent
Sicherheit: Beispiel .htaccess-Datei
CMSms 1.12 unter PHP 7:
cmsms-1.12.3.zip (inoffiziell - komplett inkl. Installer)
CMSms 1.12 unter PHP 8:
cmsms-1.12.4.zip (inoffiziell - komplett inkl. Installer)

Offline

#7 08. Oktober 2011 13:24

dc2
kennt CMS/ms
Registriert: 26. November 2010
Beiträge: 140
Webseite

Re: HTML Compressor für die index.php

Ich halten den Nutzen dieser "Komprimierung" - zumindest On-the-Fly bei jedem Aufruf - für sehr eingeschränkt.
Gängige Kompressionsalgorithmen wie gzip, die auf einer Huffman-Codierung basieren, sind gerade bei häufigen Wiederholungen (also auch vielen Leerzeichen) ziemlich effizient.
Der Komprimierungseffekt, der durch die Entfernung solcher überflüssiger Zeichen erzielt wird, ist marginal (bei einem Test mit der Rohgröße von 37,0kb lag die Einsparung bei 0,3kb, also unter 1%).

Anders sieht das natürlich aus, wenn es um Seiten geht, die danach zwischengespeichert werden - da lohnt sich der zusätzliche Zeitaufwand zur Entfernung durchaus.

NaN schrieb:

Hebt sich da der Geschwindigkeitsnachteil eines Modifiers bzw. Postfilters gegenüber der Änderung an der index.php auf Dauer nicht wieder auf?

Im Prinzip schon - allerdings gilt das nur für Filter. Modifier werden auch bei zwischengespeicherten Templates jedes Mal neu ausgeführt, Pre- oder Postfilter hingegen nur einmalig vor oder nach der Übersetzung von Smarty nach PHP.

Beitrag geändert von dc2 (08. Oktober 2011 13:26)

Offline

#8 08. Oktober 2011 13:46

piratos
arbeitet mit CMS/ms
Registriert: 12. August 2011
Beiträge: 545

Re: HTML Compressor für die index.php

Das Problem wegen des Javascriptes liegt in der Entfernung vom single  "\n", lässt man das läuft es auch lokal prima.
Auf meiner Website würde das 38 Bytes mehr Transfer bedeutet - kann man also vergessen.
Strip entfernt ebenfalls \n und damit hast du das Problem permanent.

Der Code sieht dann nun so aus (habe den ein wenig optimiert und etwas schöner gestylt) - deine Seite läuft bei mir lokal nun problemlos - keine Consolenmeldung:

[== php ==]
        $html = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $html);
        #$html = str_replace(array("\r\n", "\r", "\n", "\t"), '', $html);
        $html = str_replace(array("\r\n", "\r", "\t"), '', $html);
        $ar1=array(
            '  ',
            '  ',
            '  ',
            '  ',
            '  ',
            ' } )',
            '" /> ',
            '<br />',
            ';</p>  </div>',
            '</div> <p>',
            '" >',
            '</li> </ul>',
            '</div> <div',
            '> <');
        $ar2=array(
            ' ',
            ' ',
            ' ',
            ' ',
            ' ',
            '})',
            '"/> ',
            '<br/>',
            ';</p></div>',
            '</div><p>',
            '" >',
            '</li></ul>',
            '</div><div',
            '><');
        
        echo str_replace($ar1,$ar2, $html);

Was deine Speedproblem betrifft - zunächst würde ich das billigste lösen - favicon fehlt, das hemmt die Browser enorm.
Du verwendest base64 - images - die Frage stellt sich ob diese auch gecacht werden oder laufend neu produziert werden.
Du schiesbt 692 kb rüber , das ist nicht gerade wenig.
Die Bildgrößen spielen eine große Geige aber noch wichtiger ist, das du height und width angibst (sonnenuntergang), da ansonsten jeder Browser erst einmal wartet bis das Ding da ist um die Größe zu ermitteln.

Und du skalierst die Images per html statt die richtige Größe zu liefern.

strip arbeitet Templates und Inhalte (sind ja hier auch Templates)  zur Laufzeit ab.

Ich wüsste im Moment nicht das CMSMS Smarty Cache einsetzt.

Offline

#9 08. Oktober 2011 14:03

piratos
arbeitet mit CMS/ms
Registriert: 12. August 2011
Beiträge: 545

Re: HTML Compressor für die index.php

Noch mal kurz zum Thema  Leistung.

826 Bytes Reduzierung haben dazu geführt das Seiten im Bereich 0,04 Sekunden schneller beim Empfänger (USA) fertig gerendert wurden und ja natürlich wird die Seite zudem echt komprimiert ausgeliefert und nein es geht nicht nur um Leerzeichen.
Was hier nicht verstanden wurde - es geht um den Speed beim Empfänger der hauptsächlich durch den Browser und dessen Verarbeitung der Inhalte bestimmt wird , wer das nicht verstanden hat der hat Pagespeed nicht verstanden.

Dieser echte Speed ist genau das was die Suchmaschinen ja auch als Faktor bewerten. 0,04 Sekunden für einen solch kleinen Fliegenfurz das ist schon enorm, da kann man schon ein paar Pings unterbringen und das auf einer Seite die bereits extrem hoch optimiert ist und so ziemlich genau der durchschnittlichen Generierungszeit der Seite selbst entspricht.

Der Eingriff ist so winzig das man da eigentlich nicht lange darüber reden muss.

Offline

#10 08. Oktober 2011 14:19

NaN
Moderator
Ort: Halle (Saale)
Registriert: 09. November 2010
Beiträge: 4.437

Re: HTML Compressor für die index.php

piratos schrieb:

Strip entfernt ebenfalls \n und damit hast du das Problem permanent.

Nein eben nicht, weil {strip} nicht auf Inhalte wirkt, die zwischen {literal} ... {/literal} stehen wink

Du verwendest base64 - images - die Frage stellt sich ob diese auch gecacht werden oder laufend neu produziert werden.

Die werden selbstverständlich gecached.

favicon fehlt

Hatte ich drin, wurde aber außer im FF und IE nirgends angezeigt.
Im Opera hat es sogar zu ewig langen Ladezeiten geführt.
Also hab ich's erstmal wieder rausgenommen.
Favicon war ursprünglich auch base64, dann kam's von einer Subdomain und später dann von der eigentlichen Domain - hat alles nichts geholfen. Gab gestern allerdings auch Probleme mit dem DNS Lookup (laut Googles Webmastertools).

Der Code sieht dann nun so aus (habe den ein wenig optimiert und etwas schöner gestylt)

Okay, erstmal danke für die Mühe.
Ich werd's mal in der index.php und als Postfilter testen.


Module: GBFilePicker, AdvancedContent
Sicherheit: Beispiel .htaccess-Datei
CMSms 1.12 unter PHP 7:
cmsms-1.12.3.zip (inoffiziell - komplett inkl. Installer)
CMSms 1.12 unter PHP 8:
cmsms-1.12.4.zip (inoffiziell - komplett inkl. Installer)

Offline

#11 08. Oktober 2011 14:28

piratos
arbeitet mit CMS/ms
Registriert: 12. August 2011
Beiträge: 545

Re: HTML Compressor für die index.php

<link rel="shortcut icon" href="data:image/png;base64,....." type="image/x-icon"/>

klappt bei mir einwandfrei.

Offline

#12 08. Oktober 2011 15:01

piratos
arbeitet mit CMS/ms
Registriert: 12. August 2011
Beiträge: 545

Re: HTML Compressor für die index.php

defer und async wirkt nur auf externe js - ich denke da an den dicken loader, wenn du kannst auf extern legen.

Offline

#13 08. Oktober 2011 15:16

NaN
Moderator
Ort: Halle (Saale)
Registriert: 09. November 2010
Beiträge: 4.437

Re: HTML Compressor für die index.php

Ja, der ewige copy & paste Fluch... roll
Aber so dick ist der garnicht. Als ich ihn extern hatte, hat mir Pagespeed vorgeschlagen in inline einzufügen.  roll
Wie man's auch macht, macht man's verkehrt.
Man kann's diesen Suchmaschinendingern auch nie recht machen.


Module: GBFilePicker, AdvancedContent
Sicherheit: Beispiel .htaccess-Datei
CMSms 1.12 unter PHP 7:
cmsms-1.12.3.zip (inoffiziell - komplett inkl. Installer)
CMSms 1.12 unter PHP 8:
cmsms-1.12.4.zip (inoffiziell - komplett inkl. Installer)

Offline

#14 08. Oktober 2011 18:43

NaN
Moderator
Ort: Halle (Saale)
Registriert: 09. November 2010
Beiträge: 4.437

Re: HTML Compressor für die index.php

Hab nochmal genauer hingeschaut. Das Problem bei meinem Script lag nicht an Deinem Code. Es lag an einer Kommentarzeile in meinem Script. Sowas hier:

wird dann zu

D.h. der Rest des Scripts ist dann nur noch Kommentar, was logischerweise zu einem Fehler führt.
Javascripts dürfen also keine solchen Kommentare mehr enthalten. Dann klappts auch mit Deiner ursprünglichen Version.


Module: GBFilePicker, AdvancedContent
Sicherheit: Beispiel .htaccess-Datei
CMSms 1.12 unter PHP 7:
cmsms-1.12.3.zip (inoffiziell - komplett inkl. Installer)
CMSms 1.12 unter PHP 8:
cmsms-1.12.4.zip (inoffiziell - komplett inkl. Installer)

Offline