Javascript-Minifier beim Response – ohne Bundles

ASP.net bringt von Haus aus ja bekanntlich die Funktionalität mit, viele Javascripts zu einem Bundle zusammenzufassen und diese minimiert an den Client zu übertragen.

Was jedoch, wenn man Scripts hat, die dynamisch – z.B. mit require.js nach – nachgeladen werden?

Die eine Möglichkeit ist, (1)diese nach der Erstellung direkt zu minimieren – eine andere wäre, (2)das Script dynamisch zur Laufzeit zu optimieren und an den Client zu geben.

Zweiteres möchte ich in diesem Post näher Beleuchten.

Um Javascript zur Laufzeit zu minimieren, bedarf es einem Eingriff in der global.asax. Hier kann man sich den PostReleaseRequestState-Event zunutze machen.

Die Beschreibung zu diesem Event lautet:

Occurs when ASP.NET has completed executing all request event handlers and the request state data has been stored.

Und einer Helfer-Klasse, die das minimieren des Scripts übernimmt. Diese nimmt den OutputStream entgegen und minimiert mit Hilfe des Minifier-Objekts aus dem Namespace Microsoft.Ajax.Utilities die Ausgabe:

public class JavascriptRequestMinifier : MemoryStream{
private readonly Stream _stream;

public JavascriptRequestMinifier(Stream stream){
this._stream = stream;
}

public override void Write(byte[] buffer, int offset, int count){
string code = Encoding.UTF8.GetString(buffer);
Minifier m = new Minifier();
code = m.MinifyJavaScript(code, new CodeSettings {
EvalTreatment = EvalTreatment.MakeImmediateSafe,
PreserveImportantComments = false
});

this._stream.Write(
Encoding.UTF8.GetBytes(code),
offset,
Encoding.UTF8.GetByteCount(code));
}
}

In der Global.asax wird nun noch der PostReleaseRequestState-Event behandelt und geprüft, ob es sich um ein Javascript handelt – ist das der Fall, tritt der JavascriptRequestMinifier in Aktion:

protected void Application_PostReleaseRequestState(
Object sender, EventArgs e) {

if (this.Response.ContentType.Equals(„application/javascript“)) {
this.Response.Filter = new
JavascriptRequestMinifier(this.Response.Filter);
}
}

ACHTUNG: An der Stelle wird der Minifier immer dann verwendet, wenn es sich um eine Response handelt, dessen ContentType „application/javascript“ ist.

Das heißt, auch bereits minimierte Scripts werden noch einmal versucht, zu minimieren – was natürlich gelegentlich auch klappt, und das ein oder andere Byte zusätzlich gespart werden kann!

Um das zu verhindern, könnte man ggfs. prüfen, ob der angefragte Dateiname auf .min.js endet oder zu minimierende Scripts immer mit QueryString-Argumenten aufrufen und diese dann zu prüfen…

 

Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s