Ladezeit verbessern mit PHP Caching?


Jahr für Jahr wachsen nicht nur die Anforderungen an Webseiten, sondern auch die Besucherzahlen. Zusätzlich möchte man als Webseitenbetreiber seine Webseite schnell und einfach verwalten können. Genau das richtige Einsatzgebiet für Skriptsprachen wie PHP und Konsorten.

PHP - Ladezeit verbessern mit Caching?

Zu den Anfangszeiten des Internets bestanden Webseiten hauptsächlich aus einfachen HTML Seiten. Heutzutage gibt es kaum mehr Webseiten mit statischen Inhalten. Es werden immer häufiger Skriptsprachen wie PHP und ASP.NET zur dynamischen Generierung der Inhalte eingesetzt. Skriptsprachen sind aus dem Web also nicht mehr wegzudenken, sie sind ein wichtiger Baustein für die Interaktion zwischen Besucher und Webseite.

Jahr für Jahr wachsen nicht nur die Anforderungen an Webseiten, sondern auch die Besucherzahlen. Zusätzlich möchte man als Webseitenbetreiber seine Webseite schnell und einfach verwalten können. Genau das richtige Einsatzgebiet für Skriptsprachen wie PHP und Konsorten.

Es gibt viele einfache und schnelle Wege eine Webseite skalierbar zu gestalten. Schwieriger wird es, wenn die Faktoren Verwaltungsaufwand und Geschwindigkeit dazukommen. Ich möchte heute mit diesem Beitrag auf den Faktor Geschwindigkeit eingehen.

Für PHP Applikationen gibt es eine Vielzahl von Tools, die die Ladezeit einer Seite verbessern können. Zunächst möchte ich ein paar etablierte Cache Systeme vorstellen.

Einige bekannte Cache Systeme:

Zend Optimizer (kostenpflichtig)

Der Zend Optimizer arbeitet mit vorkompilierten PHP Dateien, dadurch werden unter anderem Festplattenzugriffe verringert.

Der Zend Optimizer bietet unter anderem auch Code Verschlüsselung, was für eine Lizenzierung sehr hilfreich sein kann.

http://www.zend.com/products/server/

 

Memcache (OpenSource)

Ist ein Cache-Server der Daten im Arbeitsspeicher ablegt und ausliest. Memcache wird hauptsächlich für die Optimierung von zeitintensiven Datenbankabfragen genutzt. Dabei werden die Abfrage Ergebnisse gecached.

http://memcached.org/

 

- Alternative PHP Cache – APC (OpenSource)

APC ist fast schon Standart wenn es um PHP-Cache Systeme geht. APC nutzt den PHP Bytecompiler und erzeugt vorkompilierten PHP Code welcher in einem gemeinsamen Speicher abgelegt wird.

http://pecl.php.net/package/APC

 

Smarty (OpenSource)

Smarty ist eigentlich kein Cache System, sondern vielmehr ein Template-System. Jedoch verfügt Smarty über ein Cache System, welches PHP Seiten in HTML übersetzt und dadurch die Skriptaufrufe verringert.

http://www.smarty.net/


 

Anhand eines kleinen Beispiels möchte ich die prinzipielle Funktionsweise erklären.

Ausgangssituation:

Eine Liste mit dynamischen Spalten und Zeilen soll gecached werden. Damit die Ladezeit besser beobachten werden kann, habe ich einen Daten-Array mithilfe dieses Skripts angelegt:

data.php

$buffer = ' ;
$row = '';
for (
$i=1;$i<=1000;$i++) {
$buffer .= '$dataArray[] = array(';
$row = '';
for (
$j=1;$j<=10;$j++) {
if (
$row!='') $row .= ',';
$row .= $i+$j-1;
}
$buffer .= $row . ');';
}
$buffer .= '?>';
file_put_contents('data.php',$buffer);
echo
'back';

Die ersten Überlegungen zum Cache System:

Folgende Anforderungen soll unser kleines Cache System erfüllen:

- PHP Dateien sollen „gecached" werden können.

-Strings sollen „gecached" werden können

Das eigentliche Caching in unserem Beispiel soll PHP übernehmen. Dabei lassen wir uns eine Datei oder einen String durch PHP übersetzen und speichern die gepufferte Ausgabe in einer Datei. Bei jedem Aufruf wird geprüft ob bereits eine Cache Datei existiert und ob diese noch „aktuell" ist.

Hinweis: Die Aktualität einer Datei zu prüfen ist nicht ganz trivial, deswegen werden wir in diesem Beispiel den Cache in bestimmen Zeitintervallen erneuern lassen.

CacheHandler.class.php

/**
* CacheHandler.class.php
* Cache Example
*/

/**
* CLASS CacheHandler
*
* Der CacheHandler verwaltet alle Cache Resourcen und stellt
* Methoden zum hinzufuegen und loeschen von Cache Inhalten zur Verguegung.
*/
class CacheHandler {

/* Pfad fuer Cache Dateien */
public $cacheDir;
/* Array mit CacheResourcen */
public $cacheHandles = array();

/**
* @param - $cacheDir
* @return - CacheHandler Obj
*/
public function __construct($cacheDir='cache') {
$this->cacheDir = $cacheDir;
$this->templateDir = $templateDir;
}

/**
* String am Cache anmelden
* @param $resourceName - Variablenname fuer den String
* @param $content - Inhalt der Variablen
* @return - StringResource
*/
public function addString($resourceName,$content) {
return
$this->cacheHandles[$resourceName] = new StringResource($content,$this->cacheDir);
}

/**
* Datei am Cache anmelden
* @param $fileName - Name der Quelldatei
* @param $filePath - Pfad zur Quelldatei
*/
public function addFile($fileName,$filePath) {
return
$this->cacheHandles[$fileName] = new FileResource($filePath.DIRECTORY_SEPARATOR.$fileName,$this->cacheDir);
}

/**
* Loescht alle registrierten Cache-Dateien
* @return void
*/
public function clearCache() {
foreach (
$this->cacheHandles as $cacheHandle)
if (
is_file($cacheHandle->cacheFile))
unlink($cacheHandle->cacheFile);
}
}

/**
* ABSTRACT CLASS CacheResource
*
* Stellt alle grundlegenden Funktionen das Anlegen und erneuern der
* Cache-Dateien zur Verfuegung
*/
abstract class CacheResource {

/* Zeitintervall fuer die Cache-Ernerung in Sekunden */
public $cacheLifeTime = 900;
/* Cached-code Datei */
public $cacheFile;

/**
* Pruefen ob Cache Datei existiert und "aktuell" ist,
* ggf. cache Datei anlegen
* @return void
*/
public function display() {
if (!
file_exists($this->cacheFile))
$this->cache();
include
$this->cacheFile;
if (
$__cache__time__-time()<0)
$this->cache();
}

/**
* Cache Datei mit Erstellungsdatum speichern
* (Die Variable $__cache__time__ wird spaeter fĂĽr Abfrage benoetigt)
* @return void
*/
protected function saveBuffer($buffer) {
file_put_contents($this->cacheFile,' .(time()+$this->cacheLifeTime).'; ?>'.$buffer);
}

public function
setLifeTime($seconds) {
$this->cacheLifeTime = $seconds;
}

public function
cache() {}

}

/**
* CLASS FileResource
*
* Uebernimmt uebersetzten und Puffern einer Quelldatei
* @implements - CacheResource
*/
class FileResource extends CacheResource {

private
$fileRes;

public function
__construct($fileRes,$cacheDir) {
$this->fileRes = $fileRes;
$this->cacheFile = $cacheDir.DIRECTORY_SEPARATOR.sha1($cacheDir.DIRECTORY_SEPARATOR.$fileRes).'.php';
}

public function
cache() {
ob_start(array(&$this,'saveBuffer'));
include
$this->fileRes;
ob_end_clean();
}
}

/**
* CLASS StringResource
*
* Uebernimmt uebersetzten und Puffern eines Strings
* @implements - CacheResource
*/
class StringResource extends CacheResource {

private
$stringRes;

public function
__construct($stringRes,$cacheDir) {
$this->stringRes = $stringRes;
$this->cacheDir = $cacheDir;
$this->cacheFile = $cacheDir.DIRECTORY_SEPARATOR . sha1($_SERVER['SCRIPT_NAME'].DIRECTORY_SEPARATOR.$stringRes).'.php';
}

public function
cache() {
ob_start(array(&$this,'saveBuffer'));
echo
$this->stringRes;
ob_end_clean();
}
}

Beispielausgaben PHP Chaching:

Ausgabe ohne Cache

example.php

define('PATH',__DIR__);
if (!
file_exists(PATH.'/data.php')) die('Beispiel Datei fehlt. Datei generieren.');

$start = microtime(true);
/*----------------------------------------------------------------------*/

include 'filesources/header.php';
include
'filesources/table.php';
echo
'

'.date("d.m.Y - H:i").'

';
include
'filesources/footer.php';

/*----------------------------------------------------------------------*/
echo microtime(true)-$start.' Sekunden verbraucht';

 

Ausgabe mit Cache

example_cache.php

define('PATH',__DIR__);
if (!
file_exists(PATH.'/data.php')) die('Beispiel Datei fehlt. .');

$start = microtime(true);
/*----------------------------------------------------------------------*/
include 'CacheHandler.class.php';

$cache = new CacheHandler(PATH.'/cache');

$header = $cache->addFile('header.php',PATH.'/filesources');
$footer = $cache->addFile('footer.php',PATH.'/filesources');
$table = $cache->addFile('table.php',PATH.'/filesources');
$creationDate = $cache->addString('lastUpdate','

'.date("d.m.Y - H:i").'

');

$header->display();
$table->display();
$creationDate->display();
$footer->display();

/*----------------------------------------------------------------------*/
echo microtime(true)-$start.' Sekunden verbraucht';

 

Nachteile bei dem vorgestellten System:

 




Social Media
(04.09.2015)

Die Sozialen Medien schnell erklärt. Facebook, Twitter, Xing und Co in der Übersicht.
...mehr lesen
Call to Action
(03.09.2015)

Darf ich bitten? Natürlich gehört ein Besucher dezent aufgefordert auch etwas auf Ihrer Webseite zu tun. Ein Kontaktformular auszufüllen, einen Anruf zu tätigen oder einen Artikel in den Warenkorb hinzuzufügen. Wir erklären wie man das am besten macht.
...mehr lesen
Google Analytics
(03.09.2015)

Das umfangreiche Statistiktool Google Analytics kurz vorgestellt. Die wichtigsten Funktionen im Schnelldurchlauf.
...mehr lesen
Webseiten Texte gestalten
(25.08.2015)

Einen ansprechenden Text zu gestalten ist gar nicht so einfach. Oft schreiben viele Seitenbetreiber emsig drauf los und hoffen, dass die Besucher einen langen Blogtext gierig durcharbeiten. Hier stellen wir Ihnen ein paar Elemente und Möglichkeiten vor.
...mehr lesen
Guter Content
(24.08.2015)

Eine Webseite steht und fällt mir dem Inhalt. Den Content zu optimieren und eine eigene Struktur für die Inhalte zu gestalten ist daher ein wichtiger Arbeitsschritt im Webdesign.
...mehr lesen
Webdesign-Besucher-verstehen Webdesign heißt Kunden verstehen
(10.02.2013)

Bei vielen Webseiten (teilweise auch gerade erst erstellten Seiten) frage ich mich, wer beim Webdesigner eigentlich an den Besucher gedacht hat. Hier eine kleine Einführung wie wir Webdesign verstehen.
...mehr lesen
Webdesign-mobile-Endgeraete Webdesign für mobile Endgeräte
(01.05.2012)

Seit April bieten wir auch Webdesign für mobile Endgeräte (Smartphones) an. Hier wird meist eine verkürzte und kompakte Variante der Hauptseite mit größeren Schaltflächen und einfacher Navigation erstellt.
...mehr lesen
Stylesheet für den Ausdruck anlegen
(13.12.2011)

Nicht jeder liest gerne am Bildschirm und druckt deshalb eine Website aus. Mit einem Print-Stylesheet erhöhen Sie den Lesespaß dieser Besucher, denn ein Ausdruck ist ohne angepasste CSS-Eigenschaften zwar tauglich, aber alles andere als optimal.
...mehr lesen
E-Mail-Adresse vor SPAM-Bots schützen
(13.12.2011)

Jeder, der seine E-Mail-Adresse online stellt, läuft Gefahr, SPAM-Mails zu erhalten. Warum ist das so? Das World Wide Web wird von sogenannten SPAM-Bots durchforstet. Diese Programme durchsuchen Webseiten nach E-Mail-Adressen, welche dann in einem Verteiler landen. Wurden Sie in dieser Liste aufgenommen, müssen Sie nicht mehr lange darauf warten, bis in Ihrem Postfach tolle Angebote für täuschend echte Rolex-Imitate oder unfassbar günstige Potenzmittel landen.Sie können sich allerdings vor diesen neugierigen Programmen schützen.
...mehr lesen
DIV mit CCS gestalten
(13.12.2011)

Im Layout jeder Website nehmen DIV-Container eine zentrale Bedeutung ein. Mit ihnen können mehrere Elemente gruppiert und positioniert werden. Sie bieten zudem viele Gestaltungsmöglichkeiten. Wir möchten Ihnen zeigen, was man alles mit einer DIV-Box anstellen kann.
...mehr lesen
Serverwechsel und Erweiterung
(14.10.2011)

Wenn die Familie größer wird, muss PLATZ geschaffen werden. Nach nun 3 Wochen der Vorbereitung wurde in der Nacht die Serverlandschaft umgestellt.
...mehr lesen
Webdesign-W3-Validator-Anleitung Webdesign und der W3 Validator
(01.08.2011)

Wenn man von einer "sauber programmierten" Webseite spricht, meint man einen Programmiercode, welcher nach dem W3 Standart erstellt wurde. Wir erklären hier, wie Sie bei Ihrem Webdesign den Quellcode prüfen können.
...mehr lesen