HTML_AJAX aus dem PEAR-Framework mit JsMin zu schlankerem JavaScript Code optimieren

Im Ferienhauskatalog von Location Bretagne nutzen wir eine typische LAMP-Installation. Einige Funktionen des Katalogs (bspw. die Geo-Suche) werden durch AJAX-Technologien unterstützt, die das HTML_AJAX Paket aus dem PEAR-Framework nutzen. Dieses Paket wird entwickelt und unterstützt von Elizabeth Smith, David Coallier, Joshua Eichhorn (er stellt auch eine gute Dokumentation bereit), Laurent Yaish und Arpat Ray.

Insgesamt finde ich das Paket sehr gelungen und auch nutzbar, obwohl es leider seit 16.6.2008 im Beta-Stadium (0.5.6) “verharrt”. Dafür steht es unter eine L-GPL Lizenz und lässt sich als Bestandteil von PEAR bequem mit dem PEAR-Installer installieren und updaten. Zusammengefasst lassen sich mit HTML_AJAX PHP-Funktionen und Klassenmethoden als AJAX-Funktionen registrieren, so dass der PHP-Code komfortabel als JavaScript-Code bereitgestellt wird und sich so bequem aus JavaScript aufrufen lässt.

Einen gravierenden Nachteil hat das Paket jedoch: Der generierte JavaScript-Code ist alles andere als “kompakt”. Zwar lässt sich der Code mit gzip komprimieren, doch führt dies dennoch regelmäßig zu schlechten Bewertungen mit YSlow! oder Google Page Speed. Folgender Beispielcode zeigt, wie die Kompression mit gzip aktiviert wird:

//a session is required(you can also set session.auto_start=1 in php.ini)
session_start();
include ‘HTML/AJAX/Server.php’;
$server = new HTML_AJAX_Server();
// activate gzip compression
$server->compression['enabled'] = true;
$server->handleRequest();

Ein Ausweg ist die Aktivierung von “packJavaScript”, die wie folgt aktiviert wird:

//a session is required(you can also set session.auto_start=1 in php.ini)
session_start();
include ‘HTML/AJAX/Server.php’;
$server = new HTML_AJAX_Server();
// activate gzip compression
$server->compression['enabled'] = true;
// activate pack javascript
$server->ajax->packJavaScript = true;
$server->handleRequest();lan

Dadurch wird der Code schon deutlich kompakter, da überflüssige Zeilenumbrüche etc. weggelassen werden. Die Testergebnisse bei YSlow! und Page Speed werden besser, allerdings sind sie noch lange nicht optimal. Statt dessen zeigte Page Speed bei mir immer noch mögliche Verbesserungsraten von ca. 1/3 an. Doch wie können wir den Code noch kompakter und schlanker machen? Standardmäßig leider gar nicht, statt dessen sind Modifikationen am HTML_AJAX Paket notwendig.

Mein Ansatz besteht darin, die Bibliotheken JsMin für PHP von Ryan Grove bzw. die nochmals optimierte Version JsMin+ für PHP von Tino Zijdel in den “Packalgorithmus” von HTML_AJAX zu integrieren. Dafür habe ich die Methoden packJavascript aus dem HTML_AJAX Paket (Klassenname: AJAX.php) insoweit modifiziert, dass nun über die zusätzliche öffentlich verfügbare Objekteigenschaft packJavaScriptEngine ausgewählt werden kann, mit welchem Mechanismus der JavaScript Code optimiert werden soll. Dabei muss als Stringparameter einer der folgenden Werte angegeben werden ORIGINAL, JSMIN oder JSMIN+.

In ersten Tests funktionierte die modifizierte Version problemlos. Die Nutzung von JsMin erzeugte nochmals deutlich kompakteren JavaScript Code, so das die Testresultate von YSlow! oder Google Page Speed immerhin “grün” wurden. Allerdings wurde noch immer bemängelt, dass der JavaScript Code noch kompakter sein könnte. Die Nutzung von JsMin+ brachte dann die erhoffte “Erlösung”: Der Code wird derart kompakt, dass bei Tests nichts(!) nichts mehr zu bemängeln haben.

Den beispielhaften Aufruf meiner modifizierten Version unter Nutzung von JsMin+ zeigt folgender Beispielcode (dabei muss die Bibliothek jsmin.php bzw. jsminplus.php seperat eingebunden werden – beide Bibliotheken können kostenlos auf den Seiten der Autoren geladen werden):

// jsminplus.php must be required because it’s not provided by HTML_AJAX!
require_once ‘jsminplus.php’;

$server = new HTML_AJAX_Server();
$server->compression['enabled'] = true;
$server->ajax->packJavaScript = true;
// Use JsMin+ to compact JavaScript
$server->ajax->packJavaScriptEngine = ‘JSMIN+’;
$server->handleRequest();

Die modifizierte Version von AJAX aus dem PEAR-Paket HTML_AJAX kann hier heruntergeladen werden. Ich habe die Modifikation ebenso wie die Originalautoren unter eine LGPL Lizenz gestellt.

Über Kommentare, Verbesserungsvorschläge und Anregungen freue ich mich sehr!!

/**
* Makes JavaScript code smaller, using 3 possible engines: JsMin for PHP, JsMin+ for PHP or the orginial one provided by the authors of HTML_AJAX
*
* @param string $input Javascript to pack
*
* @access public
* @return string packed javascript
*/
function packJavaScript($input) {
switch($this->packJavaScriptEngine) {
case ‘JSMIN’:
return JSMin::minify($input);
break;
case ‘JSMIN+’:
return JSMinPlus::minify($input);
break;
default:
return $this->_packJavaScript($input);
}
}
/**
* Make JavaScript code smaller
*
* Currently just strips whitespace and comments, needs to remain fast
* Strips comments only if they are not preceeded by code
* Strips /*-style comments only if they span over more than one line
* Since strings cannot span over multiple lines, it cannot be defeated by a
* string containing /*
*
* @param string $input Javascript to pack
*
* @access private
* @return string packed javascript
*/
function _packJavaScript($input)
{
$stripPregs    = array(
‘/^\s*$/’,
‘/^\s*\/\/.*$/’
);
$blockStart    = ‘/^\s*\/\/\*/’;
$blockEnd      = ‘/\*\/\s*(.*)$/’;
$inlineComment = ‘/\/\*.*\*\//’;
$out           = ”;
$lines   = explode(“\n”, $input);
$inblock = false;
foreach ($lines as $line) {
$keep = true;
if ($inblock) {
if (preg_match($blockEnd, $line)) {
$inblock = false;
$line    = preg_match($blockEnd, ‘$1′, $line);
$keep    = strlen($line) > 0;
}
} elseif (preg_match($inlineComment, $line)) {
$keep = true;
} elseif (preg_match($blockStart, $line)) {
$inblock = true;
$keep    = false;
}
if (!$inblock) {
foreach ($stripPregs as $preg) {
if (preg_match($preg, $line)) {
$keep = false;
break;
}
}
}
if ($keep && !$inblock) {
$out .= trim($line).”\n”;
}
/* Enable to see what your striping out
else {
echo $line.”<br>”;
}//*/
}
$out .= “\n”;
return $out;
}

Autor:
Datum: Montag, 21. Dezember 2009 2:03
Trackback: Trackback-URL Themengebiet: Entwicklung, Technik und Technologie

Feed zum Beitrag: RSS 2.0 Diesen Artikel kommentieren

Kommentar abgeben