HTML in TYPO3 komprimieren
Möchte man den Pagespeed einer TYPO3 Website optimieren, ist das Komprimieren des HTML-Outputs eine gute Möglichkeit. Dadurch werden sämtliche überflüssigen Leerzeichen, Zeilenumbrüche und Einrückungen entfernt.
Das <f:spaceless /> Problem
Der <f:spaceless>Viewhelper in TYPO3 entfernt alle Leerzeichen, die zwischen einem „>“ und einem „<“ stehen. Dies reduziert zwar den HTML-Output deutlich, bringt allerdings auch ein paar Probleme mit sich.
Das erste Problem wäre, dass zwischen einem <p>-Tag beispielsweise zwar die Leerzeichen zum nächsten <p>-Tag entfernt werden, die Leerzeichen hingegegen innerhalb des Paragraphs bleiben erhalten. Somit ist der Output nicht richtig kompakt zu bekommen.
Das andere haupsächliche Problem liegt in der Mechanik des Ganzen. Was bei HTML-Block-Elementen zwar sinnvoll ist, führt bei HTML-Inline-Elementen zu Darstellungsfehlern. Wenn beispielsweise ein <b>Bold</b> und ein <i>Italic</i> aufeinanderfolgen, werden durch den Viewhelper die Leerzeichen dazwischen entfernt, wodurch diese beiden Wörter direkt aneinanderkleben (BoldItalic). Das gleiche fehlerhafte Ergebnis erhält man auch bei zwei aufeinanderfolgenden Links.
Was ist zu tun?
Nachdem durch TYPO3 sämtlicher HTML-Output unter Berücksichtigung aller Content-Elemente, typoscript und Konfigurationen zusammengestellt wurde, läuft das ganze Ergebnis letztlich noch durch zwei PHP-Funktionen:
- function contentPostProcOutput (Wenn die Seite nicht im Cache liegt)
- function contentPostProcAll (Wenn die Seite bereits gecached wurde)
Alles, was wir nun benötigen, ist eine Klasse, die innerhalb der beiden Funktionen eine weitere Funktion zur Komprimierung des HTML-Outputs aufruft.
Funktion erstellen:
private function compressHtml(&$content) { $sr = array( '/\/\*\*.\*\//' => ' ', // remove javascript inline comments '/\n/' => ' ', // convert linebreaks to spaces '/\t/' => ' ', // convert tabs to spaces '/[ ]+/' => ' ', // convert multible spaces to one single space '/\>\s\<(?:(?!(?:a|b|strong|img|em|i|span|small|big)[ ]))/' => '><', // remove spaces between tags, but ignore on some inline-tags ); // replace content with a compressed string $content = preg_replace(array_keys($sr), array_values($sr), $content) . "\n\n<!-- powered by bloomproject.de -->"; }
PHP-Klasse erstellen, welche die Funktion aufruft:
<?php namespace Vendor\Extension\Hooks; /** * Compress the wohle html output */ class CompressHtml extends \TYPO3\CMS\Frontend\Plugin\AbstractPlugin { /** * No cache * * @return void */ public function contentPostProcOutput(&$params, &$that) { if (!$GLOBALS['TSFE']->isINTincScript()) { return; } $this->compressHtml($params['pObj']->content); } /** * Cached * * @return void */ public function contentPostProcAll(&$params, &$that) { if ($GLOBALS['TSFE']->isINTincScript()) { return; } $this->compressHtml($params['pObj']->content); } /** * Compress HTML * * @return void */ private function compressHtml(&$content) { … } }
PHP-Klasse registrieren:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-output'][] = 'Vendor\\Extension\\Hooks\\CompressHtml->contentPostProcOutput'; $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-all'][] = 'Vendor\\Extension\\Hooks\\CompressHtml->contentPostProcAll';
Alternativen
Wer es etwas einfach haben möchte und lieber eine fertige Erweiterung installieren möchte, könnte mit folgenden beiden TYPO3-Extensions ganz gut beraten sein: