Index

GZIP compressie

HTML pagina's bestaan uit tekst en afbeeldingen. Indien je JPEG en GIF bestanden gebruikt zijn de afbeeldingen reeds gecomprimeerd en worden ze zo efficient mogelijk over het internet gestuurd. Tekstbestanden kunnen echter gemakkelijk gecomprimeerd worden, waarbij ze gereduceerd worden tot minder dan 1/3 van hun originele grootte. Tekstbestanden gebruiken maar een deel van het ASCII alfabet (een 50-tal tekens uit een alfabet van 256 tekens) en bevatten talrijke herhalingen (het tekstbestand is redundant). Het woord "bestand" komt bijvoorbeeld een 4-tal keren voor in deze inleiding.

De webserver Apache is in staat tekstbestanden automatisch en volledig transparant te comprimeren voor verzending over het internet. Xitami kan dit echter niet, maar daar kunnen wij iets aan doen.

De headers van een bestand

Een bestand wordt niet zomaar over het internet verstuurd: het bevat ook een header dat meer informatie geeft over het bestand. Windows systemen gebruiken bestandsextensies om aan te geven over welk soort bestand het gaat, maar Apple gebruikt bijvoorbeeld resource forks. Met de extensie kan men dus niet aangeven over welk soort bestand het gaat.

De header bevat ook andere informatie: wanneer het bestand aangemaakt of veranderd werd (zodat de ontvanger kan bepalen of zijn versie in cache bijgewerkt moet worden of niet), hoe groot het bestand is, welk formaat het heeft (HTML, JPEG, enz), maar ook of er compressie toegepast werd.

Dit zijn de headers zoals die met de vorige opdracht opgevraagd werden:


HTTP/1.1 200 OK
Date: Sun, 03 Jun 2007 06:29:17 GMT
Server: Apache/1.3.33 (Debian GNU/Linux)
Last-Modified: Fri, 25 May 2007 07:46:10 GMT
ETag: "6ac126-113e-46569442"
Accept-Ranges: bytes
Content-Length: 4414
Content-Type: text/html
X-Cache: MISS from hostingpool012.isp.belgacom.be
Connection: close
De enige headers die echt nodig zijn, zijn de volgende:
HTTP/1.1 200 OK moet er altijd bij zijn. "200" is de "alles is correct verlopen" kode, en "OK" is de vertaling ervan in mensentaal.
Content-Length: 4414 geeft de grootte aan van het bestand.
Content-Type: text/html geeft het formaat van het bestand aan.

Andere headers zijn niet echt nodig. Enkel Connection: close is het vermelden waard. Bij HTTP/1.1 wordt de verbinding tussen server en klant niet afgesloten op het einde van iedere transfer (zodat de volgende elementen sneller verstuurd kunnen worden). Met de instruktie "Connection: close" wordt aangegeven dat de verbinding wel verbroken moet worden op het einde van de transfer. Ik had de connection: close aangevraagd bij de aanvraag van het bestand, en de server heeft mijn aanvraag bevestigd.

Dit is een bestand dat gecomprimeerd verstuurd wordt, de headers zijn nu:


HTTP/1.0 200 OK
Content-Length: 721
Content-Type: text/html
Content-Encoding: gzip
Connection: close
We geven opnieuw de kode "alles OK", de lengte en het type van bestand dat verwacht wordt, maar ook Content-Encoding: gzip, waarmee we aangeven dat het bestand gecomprimeerd zal verstuurd worden. Als je dan ook de inhoud bekijkt, dan zal je merken dat er van het origineel bestand niet veel meer overblijft.

In de praktijk

Nadat je outputpagina aangemaakt werd kijkt Xitami of je zelf je headers voorzien hebt (men noemt dit nph of non-parsed headers) of niet. Indien er geen headers zijn (dus enkel html, dit is de normale situatie), dan zal Xitami de headers zelf aanmaken. Komt Xitami echter headers tegen, dan zal Xitami niets ondernemen.
Bij andere programmeertalen zoals PHP moet je aangeven in de script-naam zelf of je met non-parsed headers wenst te werken (in dit geval moet de script beginnen met nph-.
Xitami bekijkt echter de output zelf, zodat de gebruikte scriptnaam geen rol speelt.

Dit is de kode om een pagina gecomprimeerd door te sturen:

FUNCTION PBMAIN()
    ....                                             ' a$ is de naam van het html-bestand dat gecomprimeerd
    a$ = ...                                         ' en doorgestuurd moet worden.
    SHELL "d:\gzip -f9 " + a$
    OPEN a$ + ".gz" FOR BINARY AS #2                 ' We shellen naar GZIP dat de compressie uitvoert
    GET$ #2, LOF(#2), a$                             ' De arguments zijn f (force compression, no prompt)
    CLOSE                                            ' en 9 (maximale compressie).
    OPEN ENVIRON$("CGI_STDOUT") FOR OUTPUT AS #1     ' Hier maken we de output aan; we schrijven de
    PRINT #1, "HTTP/1.0 200 OK"                      ' headers en dan het bestand. De headers en het
    PRINT #1, "Content-Length:" LEN(a$)              ' bestand worden door een blanco regel gescheiden
    PRINT #1, "Content-Type: text/html"              ' (zoals ook toegepast wordt bij mail MIME).
    PRINT #1, "Content-Encoding: gzip"
    PRINT #1, "Connection: close"
    PRINT #1,
    PRINT #1, a$
    CLOSE
END FUNCTION

gzip kan u hier vinden (samen met een korte handleiding).

Opgelet: na de compressie wordt het origineel bestand door gzip gewist! Indien het origineel bestand niet gewist mag worden, eerst een copie maken!

Je zal moeten overwegen of het de moeite is van HTML bestanden te comprimeren. Bij gewone pagina's met niet teveel tekst (tot 100 k) is het nutteloos GZIP aan te roepen. De tijd dat je wint door het bestand gecomprimeerd door te sturen verlies je door het programma aan te roepen.
Voor het versturen van real-time pagina's (pagina's die on-the-fly aangemaakt worden) is GZIP compressie zeker aangeraden vanaf een 20-tal kb. Deze pagina's werden reeds door het programma aangemaakt, dus verlies je minder tijd (het programma draait al!). Het versturen van 20 kb (upload van je home account) vraagt ongeveer 1 seconde.

Grafische formaten zoals JPG, PNG en GIF zijn reeds gecomprimeerd, zodat je geen winst zal boeken door het bestand opnieuw met gzip te comprimeren. Je bekomt de hoogste compressie met HTML-bestanden (zich herhalende formateringsopdrachten en redundante tekst) en TXT-bestanden (redundantie, beperkte characterset), maar ook PDF (zonder embedded beelden) comprimeert heel goed.

Index

Individuele landingspage bezoekers: