DEPRECATION WARNING

This documentation is not using the current rendering mechanism and is probably outdated. The extension maintainer should switch to the new system. Details on how to use the rendering mechanism can be found here.

Gzip Output

Author:Kasper Skårhøj
Created:2002-11-01T00:32:00
Changed by:Georg Grossberger
Changed:2008-12-26T15:54:23
Classification:TYPO3 Extension
Keywords:gzip, cache, css, javascript
Author:Georg Großberger
Email:georg@grossberger.at
Info 3:
Info 4:

Gzip Output

Extension Key: gzip

Copyright 2008, Georg Großberger, <georg@grossberger.at>

This document is published under the Open Content License

available from http://www.opencontent.org/opl.shtml

The content of this document is related to TYPO3

- a GNU/GPL CMS/Framework available from www.typo3.com

Table of Contents

Gzip Output 1

Introduction 1

What does it do? 1

Requirements 1

Which headers are sent 1

Additional Note 2

Installation 2

Administration 2

Configuration 3

PHP 3

URL Rewrite 3

Known Problems 3

Changelog 3

Introduction

What does it do?

When using big Javascript files, the delay of execution, caused by the loading time, may be nerve-racking for your customers and the end users. So there are are a lot of tools, that compress the files by restructuring them, like Jsmin (shipped with Typo3 4.2), YUI Compressor or Packer. Those tools reduce the size of a big JS file already a lot, but using Gzip compression reduces the files even A LOT more. Typo3 can do this for regular pages, but not for external files like Javascripts or CSS files. So you could use mod_compress or mod_deflate for this. If this webserver modules are not available you can use this extension, to get the job done with PHP.

Additionally you can tell the client, how long a file may remain in the browser/proxy – cache before it needs to be reloaded from the server. Typo3 Core has some .htaccess files, which show you how to use this for images (like icons) in the backend. Of course you can use this for your javascripts too, but it requires mod_expires to be installed. This extension will send those caching headers for you too.

So, what does it do? It gzips files and sends them to the client with caching headers.

You can use this for your files, using a PHP class, a simple Typoscript or (the simple way) by doing a URL rewrite. Much of the code of this extension is based upon a sample PHP file, written by Julien Lecomte. For more information on this issue, please visit his blog

Requirements

To make this work you need at least PHP 5.0, because the main class of this tool has methods, declared as protected, public and final. You will get a parse error when trying to use it with PHP 4.x

This tool makes use of the eID feature of TYPO3 which is available since version 4.0, so it won't work with 3.x

To get the full advantage of the caching headers feature, you will need the pecl_http extension for PHP, but most of the tool will work without it.

Which headers are sent

There are several checks before the actual sending of the file.

Is the request a vaild eID request with all parameters needed? Is it a TYPO3 process at all?If not, the script ends with a 400 – Bad Request header.

Is the file inside the allowed paths (a simple security check)?If not, a 403 – Forbidden header is send

Does the request wants an existing file?If not, the script quits with a 404 – Not found header

Has the file already be sent, but expired?If yes, and the file didn't change in between, a 304 – Not modified header is sent, so the client still takes the cached file. (Works only of pecl_http extension is installed!)

If the script didn't quit yet, the following headers are sent with the content (Customisable at the extension manager):

  • Last-ModifiedThe last modified date of the file itself
  • ExpiresThe current date + x days (Defined during installation. Defaults to seven days, but it can be a good idea to use a “never expire” header, by setting it to eg.: 300 days)
  • The Etag
  • The Pragma header is set to “public”
  • And Cache-Control headers which complete the Expires header

Note: To calculate the max-age header, Gzip now uses the current timestamp instead of the last modified timestamp of a file, so there is no problem with old files.

Additional Note

The API currently supports adding CSS and Javascript files, but you can use it for more files using a simple URL rewrite. This is explained in the “Configuration” chapter.

It's actually not a good idea to use gzipping and an advanced compressing script together (like Packer by Dean Edwards), because the gain of speed while transfering maybe lost, if the browser has to decompress it twice. You should consider using a less “aggressive” compressor like JSMin or YUI Compressor .

Installation

Install through the Extension Manager. After installation you have the following options available:

  • Cache Lifetime:Defines the count of days the file should be cached at the client or proxy. Used in the Cache-Control: max-age and the expores header. Defaults to seven days. For live sites, you should consider a higher value, up to one year or more. By this you can also use the proxies of the users ISP.
  • Last modifiedDate of the last modification of the file. If not set, your webserver will most likely send one, which is maybe better or worse, depending on your purporse.
  • EtagSend the Etag, which is a hash that identifies the resource, includings it's properties. Useful for using 304 headers.
  • ExpiresSend the date of expiration
  • Cache HeadersSends the Cache-Control and the Pragma header
  • Revalidate:If set, the Cache-control: must-revalidate, proxy- revalidate headers are sent. Default is true.
  • Expand Symlinks:For security reasons, a requested file must be inside the allowedPaths, set in the TYPO3 configuration (Take a look at the Install – Tool). Now if you have a file outside this path, using a symlink, access to this file is denied if this option is set and the path is not allowed. Defaults to false to make compressed backend scripts and the concept of a symlinked core, work out of the box.

Administration

This part explains, how to use Gzip with Typoscript, if you want to know, how to use the API, refer to the “Configuration” section

The Typoscript part is quite simple:

First: Add a userfunc to your page like

page.100 = USER
page.100.userFunc = tx_gzip_pi1->main

Second: Add Javascript and/or CSS files inside the USER object

For this you can use a comma separated list like

...
js = fileadmin/script1.js,fileadmin/script2.js
css = fileadmin/style1.css,fileadmin/style2.css
...

Or an array:

...
js {
        0 = fileadmin/script1.js
        1 = fileadmin/script2.js
}
css {
        0 = fileadmin/style1.css
        1 = fileadmin/style.2.css
}
...

Or both like:

...
js = fileadmin/script1.js,fileadmin/script2.js
js {
        0 = fileadmin/script3.js
        1 = fileadmin/script4.js
}
...

So the whole block could look like this:

page.100 = USER
page.100 {
        userFunc = tx_gzip_pi1->main
        js = fileadmin/script1.js,fileadmin/script2.js
        css = fileadmin/myBigCSSfile.css
}

Not so difficult so far, right?

If you want to add files inside your extension directory, simply use the EXT: prefix

Example:

...
css = EXT:myExt/res/myExtStyles.css
...

Configuration

This chapter explains, how to use gzip within your own extensions or scripts, if you want to know, how to add a file inside your Typoscript template, refer to the “Administration” section

PHP

This is pretty simple, just get an instance of the script, call the url method and give the path to your file as first parameter. For performance resons, the class is not loaded by default but there is a loader function available.

Example:

// My file I want to compres
$file = t3lib_extMgm::siteRelPath('myExtKey') . 'res/coolCalenderApp.js';

// Load and compress it
$gzip = tx_gzip_load();
$compressed_file = $gzip->url($file);

// Add to header
$GLOBALS['TSFE']->additionalHeaderData[] = '<script type=”text/javascript” src=”'.$compressed_file.'”></script>';

This example will take the file, save a gzipped version to typo3temp/gzip and give back an url to index.php with the needed params set. The method supports a secound parameter: $fullURI. Set this to true to prepend the index.php with the URL of the set page. This method also supports the EXT: prefix

So:

$file = 'EXT:myext/res/big.js';
$gzip = tx_gzip_load();

// Will usally return
// index.php?eID=tx_gzip_ouput&amp;uri=typo3conf%2Fext%2Fmyextt%2Frest%2Fbig.js
$gzip->url($file);

// And this will return
// http://www.domain.tld/index.php?eID=tx_gzip_ouput&amp;uri=typo3conf%2Fext%2Fmyextt%2Frest%2Fbig.js
$gzip->url($file, TRUE);

I developed this for the frontend, but though I did not much testing with the backend yet, it should work without problems. At least when using the $fullURI option

URL Rewrite

Note: The example below and inside the example files rewrite both frontend and backend URLs. I made some testing without running into troubles with that. The backend was even faster!

Inside the doc folder of this extension there is the file example.htaccess which contains a complete rewrite setup for Gzip and RealURL which succeeded on all systems I tested yet. just take a look.

It simply adds two lines, which takes every .css or .js file, and puts them to the gzip script. This looks like this:

RewriteCond  %{REQUEST_FILENAME} .*\.(css|js)$
RewriteRule .*  index.php?eID=tx_gzip_output [L]

I recently fell in love with lighty (lighttpd). So a rewrite configuration for this tool was needed and here it is:

...
        url.rewrite-once = (
                "^.*\.(js|css)$" => "index.php?eID=tx_gzip_output",
        )
...

Inside the doc folder you will find an example file (lighttpd- rewrite.conf) which contains the example above together with a tested RealURL configuration.

After some testing I feel like to prefer this method over calling $gzip->url();, simply for two reasons:

You don't have to take care of the availability of tx_gzip while writing your own code

Since the URI changes, relative links to external files in CSS files (eg: background images) are currently broken.

Known Problems

The PECL extension pecl_http is not installed by default, so there should may be provided a workaround. Make the 304 headers not dependend on the availability of those functions. (Is this possible at all?)

Changelog

  • 0.4Made the class a singletonDon't load the whole class always, but rather make a lightweight loader function.Made the headers customisableFixed a bug, considering compressed JavaScript filesUpdated the manual
  • 0.3Some further minor improvementsUpdated the manualAdded the possibility to use the REWRITE_URI header (no need to attach the source URL to the rewritten one anymore)Made some things configurable through the Extension ManagerShould be the last beta release
  • 0.2Some minor improvements and bug-fixes
  • 0.1.3Fixed a bug in the plug-inAdded some infos to the manual
  • 0.1.2Fixed a bug with realpath on windowsFixed a bug that created empty return values in tx_gzip::urlFixed a bug that created some PHP warnings in tx_gzip_pi1
  • 0.1.0First upload

img-1 Gzip Output - 5