For coders TYPO3 Tech Corner

[PHP] Compress HTML output from TYPO3

[PHP] Compress HTML output from TYPO3

Google Pagespeed also complains from time to time: In addition to the recommended GZIP compression, you can also remove unnecessary characters (e.g. spaces, breaks and comments) from the rendered HTML of a TYPO3 page. Although there is already a ViewHelper (f:spaceless) that helps you to compress the code a bit in the Fluid, it usually only takes care of the body area of your website. If you really want to compress everything, the use of PSR-15 middleware is recommended.

PHP package wyrihaximus/html-compress helps with compressing. Just add it to your composer.json:

{ "name": "vendor/sitepackage", "description": "Sitepackage extension", "type": "typo3-cms-extension", "homepage": "https://www.in2code.de", "require": { "typo3/cms-core": "^10.4", "wyrihaximus/html-compress": "^1" }, "autoload": { "psr-4": { "Vendor\\Sitepackage\\": "Classes/" } } }

EXT:sitepackage/Configuration/RequestMiddlewares.php:

<?php return [ 'frontend' => [ 'sitepackage-compress-html' => [ 'target' => \Vendor\Sitepackage\Middleware\HtmlCompress::class, 'before' => [ 'typo3/cms-frontend/output-compression' ], 'after' => [ 'typo3/cms-adminpanel/renderer' ] ] ] ];

EXT:sitepackage/Classes/Middleware/HtmlCompress.php:

<?php declare(strict_types=1); namespace Vendor\Sitepackage\Middleware; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; use TYPO3\CMS\Core\Http\StreamFactory; use WyriHaximus\HtmlCompress\Factory; /** * Class HtmlCompress */ class HtmlCompress implements MiddlewareInterface { /** * @param ServerRequestInterface $request * @param RequestHandlerInterface $handler * @return ResponseInterface */ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { $response = $handler->handle($request); if ($this->isTypeNumSet($request) === false) { $stream = $response->getBody(); $stream->rewind(); $content = $stream->getContents(); $newBody = (new StreamFactory())->createStream($this->compressHtml($content)); $response = $response->withBody($newBody); } return $response; } /** * @param string $html * @return string */ protected function compressHtml(string $html): string { $parser = Factory::construct(); $html = $parser->compress($html); $html = $this->removeComments($html); return $html; } /** * Remove all html comments but not "<!--TYPO3SEARCH_begin-->" and "<!--TYPO3SEARCH-end-->" * @param string $html * @return string */ protected function removeComments(string $html): string { return preg_replace('/<!--((?!TYPO3SEARCH)[\s\S])*?-->/', '', $html); } /** * @param ServerRequestInterface $request * @return bool */ protected function isTypeNumSet(ServerRequestInterface $request): bool { return $request->getAttribute('routing')->getPageType() > 0; } }

Note: If you remove HTML comments, please note that you need the comments "TYPO3SEARCH _..." for Solr or the index search! The code above already takes this into account.

Back

"Code faster, look at the time" - does this sound familiar to you?

How about time and respect for code quality? Working in a team? Automated tests?

Join us