Hier im Forum bekommt ihr bei euren fragen schnelle hilfe.Hier geht es rund um das Web SeitenProgrammieren.Alles rund ums Javascript,Html,Php,Css und Sql.Auf fast allen Fragen haben wir eine Antwort.
Der Soforthilfe-chat verspricht das ,was sein Name sagt. Hier sind Leute Online die sofort ihre hilfe anbieten.Seht in der OnlineListe nach und wenn einer Online ist werdet ihr auch antwort bekommen. Admine ,Moderatoren und Helfer sind unsere Spezialisten in Sachen Web Programierung

Sie sind hier : sebastian1012.bplaced.net/ homepage-neu / kreuz-und-quer / tutorials-info-neuigkeiten-javascript / index.php

Random Javascript Themen, Tutorials und co

12.10.2019 02:43:55

Optimierungen von CSS und JavaScript on-the-fly

In meinem letzten Beitrag habe ich einige Möglichkeiten aufgezeigt, wie man HTML-, CSS und JavaScript-Code verkleinern kann ohne die Darstellung und Funktionalität zu beeinträchtigen. Wenn man jedoch keine Lust hat, immer nach einem Bearbeiten die Optimierungen wieder vorzunehmen, hab ich hier eine praktikablere Lösung. Außerdem wollen wir zusätzlich die Komprimierung der Daten einsetzen sowie das Client-side Caching einsetzen.
Das Ziel soll also eine Lösung sein, bei der wir mit unseren wohlstrukturierten Dateien weiterarbeiten können, aber trotzdem sollen möglichst wenig Daten vom Client geladen werden müssen.

Warum wollen wir eigentlich um jeden Preis die zu ladenden Daten so klein wie möglich halten? Es gibt 2 Gründe:

  • schnellerer Seitenaufbau: jedes Byte, was nicht geladen werden muss, beschleunigt den Seitenaufbau beim anfordernden besucher
  • geringere Kosten: oft ist das Trafficvolumen beim Webhosting oder Server begrenzt bzw. wird immer teurer je mehr Daten an den Client geschickt werden

Wenn wir es also schaffen, mit wenig Aufwand die Datenmenge zu verringern, können wir sowohl etas für unsere User als auch für unseren Geldbeutel tun.

Zuerst schauen wir uns CSS-Dateien an. Ich habe bereits bei Projekten mitgemacht, bei denen die CSS-Datei 40 kB groß war. Schönen Gruß an die 56k-Modem-User! Wir gehen hier natürlich davon aus, dass in der CSS-Datei nur wirklich genutzte Klassen und Definitionen enthalten sind – ansonsten wirkt dieser Tuningversuch lächerlich für das Projekt. Gut, wir nehmen und als Beispiel eine CSS-Datei mit einer Definition für das DIV-HTML-Element. Natürlich haben wir Multiformateigenschaften genutzt, um dadurch schon mal einige Bytes zu sparen, denn dabei geht die Übersicht auf keinen Fall verloren.

div {   font:bold 0.9em/12px Arial; /* fett groesse/zeilenabstand schriftart */   border:solid 1px red; /* typ breite farbe */   background:url(images/bild.jpg) top repeat-x; /* url position wiederholung */ }

Diese CSS-Datei kann nun nur noch durch 2 Dinge optimiert werden: Entfernung von Zeilenumbrüchen und Entfernen der Kommentare. Allerdings kann man mit der entstehenden 1-Zeilen-Datei später kaum noch arbeiten, deshalb wäre es doch toll, wenn diese Optimierungen zwar gemacht würden, wir uns aber nicht darum kümmern müssten.
Wir brauchen demzufolge ein Lösung, die on-the-fly die optimierte CSS-Datei erstellt und an den Client schickt. Um überhaupt an der Datei etwas ändern zu können, bevor sie geladen wird, brauchen wir erstmal PHP bzw. dessen Output Buffering. Dazu lassen wir unsere CSS-Datei(en) durch den PHP-Parser laufen. Das legt man über einen zusätzlichen Eintrag in der .htaccess fest (wenn diese Datei im root ihres Webprojekts noch nicht existiert, legen sie sie einfach an).
AddType application/x-httpd-php .css
Eine andere PHP über das Stylesheet schicken zu können, wäre die .css-Datei in .php umzubenennen, aber dann müssten alle Referenzierungen in der Anwendung umgeschrieben werden.

Was tun wir nun damit? Wir packen den PHP Output Buffer mit einer eigenen Callback-Funktion in die CSS-Datei. Die Callbackfunktion wird aufgerufen, nachdem die gesamte Dateiausgabe feststeht (der eigentliche CSS-Code geladen wurde), und erhält als Parameter genau diesen CSS-Code als String.

<?php header("Content-type: text/css"); ob_start("compress"); header ("content-type: text/javascript"); header ("cache-control: must-revalidate; max-age: 3600"); header ("expires: " . gmdate ("D, d M Y H:i:s", time() + 3600) . " GMT");   function compress($buffer) {   // remove comments   $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);   // remove tabs, newlines, etc.   $buffer = str_replace(array("\r\n", "\r", "\n", "\t"), '', $buffer);   //remove multiple spaces   $buffer = preg_replace('/\s\s+/', ' ', $buffer);   return $buffer; } ?> div {   font:bold 0.9em/12px Arial; /* fett groesse/zeilenabstand schriftart */   border:solid 1px res; /* typ breite farbe */   background:url(images/bild.jpg) top repeat-x; /* url position wiederholung */ } <?php ob_end_flush(); ?>

Die Funktion compress ist unsere Callback-Funktion. Wir bearbeiten den Buffer (den CSS-Code) durch das Entfernen von Kommentaren, Zeilenumbrüchen und Tabulatoren sowie mehrfachen Leerzeichen. Dadurch wird folgende CSS-Datei im Endeffekt wirklich an den Client geschickt:

div { font:bold 0.9em/12px Arial; border:solid 1px red; background:url(images/bild.jpg) top repeat-x; }

Durch diese recht trivialen Änderungen konnte die ursprüngliche Größe von 212 Bytes auf jetzt nur noch 103 Bytes verkleinert werden. Das sind über 50% weniger Daten! Und wenn man es mit der CSS-Datei vergleicht, bevor man Multiformateigenschaften genutzt hat (wenn man diese auflöst und alle Einzeleigenschaften aufschreibt kommt man auf 358 Bytes), beträgt die Speicherplatzeinsparung sogar über 70%!

Mit JavaScript-Dateien können wir ähnlich verfahren. Wir fügen die Endung .js zur .htaccess hinzu, damit sie vom PHP Parser verarbeitet wird. Bei JavaScript sind die gleichen Formatierungen möglich, nur müssen wir zusätzlich die einzeiligen Kommentare entfernen, da es sonst zu Problemen beim Entfernen von Zeilenumbrüchen kommen kann. Unsere Callback-Funktion sieht bei js-Dateien also so aus:

function function compress($buffer) {   // remove comments   $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);   $buffer = preg_replace('!//[^\n\r]*!', '', $buffer);   /*   Konstrukte wie    var variable = {     var1:"test",     var2:function() {       doSomething();     }   }   müssen nach der letzten schließenden Klammer ein Semikolon bekommen --> funktioniert nicht   */   //$buffer = preg_replace('/var ([^=]*) = \{(([^\}]*\})*)[\n\r]+/', "var ".'$1'." = {".'$2'.";", $buffer);   // remove tabs, spaces, newlines, etc. - funktioniert nicht, weil das vorhergehende nicht funktioniert   //$buffer = str_replace(array("\r", "\n", "\t"), "", $buffer);   $buffer = str_replace("\t", "", $buffer);   // multiple whitespaces   $buffer = preg_replace('/(\n)\n+/', '$1', $buffer);   $buffer = preg_replace('/(\n)\ +/', '$1', $buffer);   $buffer = preg_replace('/(\r)\r+/', '$1', $buffer);   $buffer = preg_replace('/(\r\n)(\r\n)+/', '$1', $buffer);   $buffer = preg_replace('/(\ )\ +/', '$1', $buffer);   return $buffer; }

In JavaScript gibt es komplexe Konstrukt (welche genau, steht im Kommentar im Quellcode), die ich versuche, durch ein Semikolon zu ergänzen. Leider funktioniert das nicht richtig. Aus diesem Grund habe ich auch nicht alle Zeilenumbrüche entfernt, denn sonst kommt es da zu Fehlern. Trotzdem bringt diese Funktion einiges an eingespartem Traffic.
Bei einem von mir geschriebenen Script zur Darstellung der Tooltips auf SucheBiete.com brachte diese Veränderung eine Einsparung von ca 20 % (Original: 3,24 kB, optimiert: 2,65 kB). Bei viel kommentierten Scripten wie beispielsweise Lightbox konnte ich sogar etwa 40 % einsparen (Original: 22,9 kB, optimiert: 13,8 kB).
Trotzdem muss ich sagen, dass es mit einigen JavaScripts Probleme gibt, beispielsweise mit der Bibliothek Prototype, da darin in Strings ‚/*‘ und ‚//‘ vorkommen. Man sollte also überprüfen, ob es nach dem Einbau JavaScript-Fehlermeldungen gibt.

Wenn diese On-the-fly-Optimierungen durchgeführt wurden, kann man die entstandenen Code dann noch als GZip senden, was die Größe des optimierten Codes auf ca ein Drittel zusammenpackt. Außerdem habe ich noch eine Cache-Control eingebaut, damit die Datei nicht jedes mal vom selben User erneut geladen wird.
Für CSS:

header("Content-type: text/css"); header ("cache-control: must-revalidate; max-age: 2592000"); header ("expires: " . gmdate ("D, d M Y H:i:s", time() + 2592000) . " GMT"); ob_start("compress"); function compress($buffer) {   // remove comments   $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer);   // remove tabs, spaces, newlines, etc.   $buffer = str_replace(array("\r\n", "\r", "\n", "\t"), '', $buffer);   $buffer = preg_replace('/\s\s+/', ' ', $buffer);   if (stripos($_SERVER["HTTP_ACCEPT_ENCODING"],'x-gzip') !== false) {     header("Content-encoding:x-gzip");     $buffer = gzencode($buffer);   }   elseif (stripos($_SERVER["HTTP_ACCEPT_ENCODING"],'gzip') !== false) {     header("Content-encoding:gzip");     $buffer = gzencode($buffer);   }   elseif (stripos($_SERVER["HTTP_ACCEPT_ENCODING"],'deflate') !== false) {     header("Content-encoding:deflate");     $buffer = gzdeflate($buffer);   }   header('Content-Length: ' . strlen($buffer));   return $buffer; }

Entsprechend funktioniert es auch für JavaScript (außer eben mit den oben genannten Replaces). Wer eine js-Datei hat, die durch die angegebene Funktion nicht optimiert werden kann, weil dadurch Fehler entstehen, sollte zumindest gzippen. Wenn man aber nix mehr mit dem Buffer vorhat, reicht auch ob_start("ob_gzhandler");.

Durch diese kleinen Eingriffe lassen sich also durchaus ohne viel Aufwand (Vorsicht, Untertreibung) einige Bytes an Trafficvolumen einsparen.
An die On-the-fly-Optimierung von HTML-Code traue ich mich im Moment nicht so recht ran, weil das mittlerweile nicht mehr sauber ist. Erstens haben viele Seiten nicht valides HTML und zweitens erschweren Geschichten wie Conditional Comments und vorformatierte Bereiche (z.B. in Textareas und <pre>-Abschnitten) das Optimieren.

javascript

12.10.2019 02:43:56

HTML-Code auf Produktivsites so klein wie möglich

Es ist nicht sonderlich überraschend, wenn ich sage, je weniger Daten vom Server geschickt und vom Client empfangen werden müssen, desto schneller funktioniert der Seitenaufbau. Ich habe bereits im Beitrag zur Komprimierung des Ausgabestroms gezeigt, wie man den an den Client gesendeten Code verkleinern kann. In diesem Beitrag möchte ich aber einmal näher darauf eingehen, wie der an den Browser gesendete HTML-Code selbst verkleinert werden kann.

Zu allerest möchte ich eine wichtige Grundlage festlegen, damit man mit dem Code auch später noch arbeiten kann: Man sollte sich im CVS, SVN oder einfach nur auf der Festplatte 2 Ordner anlegen. Einen Source-Ordner, der die Quellcodes in ihrer ursprünglichen Form enthält, und einen Veröffentlichungsordner, in dem wir alle Dateien ablegen, die wir nach den folgenden Anweisungen verkleinern.
Alle hier aufgelisteten Tipps beziehen sich auf den HTML-Code, der entweder als fertige HTML-Datei vorliegt oder von einer PHP-Datei generiert wird, CSS-Dateien und JavaScript – kurz: alles, was vomClient geladen werden muss.

Zuerst entfernen wir alle unnötigen Leerzeichen und Zeilenumbrüche. Das sind vor allem solche zwischen Tags. Da HTML auf XML basiert, haben Zeilenumbrüche, Leerzeichen und Tabulatoren zwischen Tags sowieso keinen Einfluss. Es ist allerdings darauf zu achten, dass nicht innerhalb von Textareas oder vorformatierten Abschnitten (<pre>) für die Ausgabe bedeutsame Whitespaces entfernt werden.
Auch in CSS-Dateien sowie innerhalb von <style>-Tags können Leerzeichen und Zeilenumbrüche entfernt werden. Für Javascript gilt ähnliches, allerdings ist hier darauf zu achten, dass man keine syntaktisch notwendigen Leerzeichen löscht, aber ganz allgemein gesagt kann jeder Zeilenumbruch in JavaScript gelöscht werden und nach einem Semikolon braucht kein Leerzeichen zu stehen – vorausgesetzt, man hat nach jedem Befehl ordentlicherweise ein Semikolon gemacht.

Anschließend entfernen wir die HTML-Kommentare (<!– … –>), außer dem Kommentar um JavaScript-Angaben. Wichtig und auf jeden Fall beizubehalten sind auch die Doctype-Definition sowie Conditional Comments für den IE.
Das gleiche gilt für JavaScript (// und /* … */) und CSS (/* … */) – auch hier sind Kommentare auf dem Produktivsystem überflüssig.

Bestimmte Farben können in CSS in Kurzschreibweise angegeben werden: Immer dann, wenn sich die Hex-Ziffern der einzelnen Rot-Grün- und Blau-Werte wiederholen, geht das. So wird aus #ff0000 einfach #f00 oder aus #ddeeff #def.

Sinnlose Tags wie leere Absätze <p></p> oder bestimmte Meta-Angaben, welcher Editor benutzt wurde, können gefahrlos entfernt werden.
Wem es nicht auf Suchmaschinenoptimierung ankommt, sondern nur darauf, wie die Seite dargestellt wird, kann auch <i> statt <em> sowie <b> statt <strong> benutzen.

Benutze CSS !!! Mit dem gekonnten Einsatz von CSS-Eigenschaften für bestimmte Tags oder Klassen kann sehr viel Code eingespart werden. Wenn man dazu noch Vererbung von CSS-Klassen gekonnt einsetzt, kann richtig viel Code gespart werden.
Hinzu kommt, dass externe CSS-Dateien nach dem ersten Laden einer Seite (je nach Einstellung) beim Client im Browser-Cache gespeichert werden und somit beim nächsten Aufruf nicht geladen werden müssen. Ähnlich verhält es sich mit externen js-Dateien.

In CSS kann man viele Eigenschaften zusammenfassen. border-color, border-width und border-style beispielsweise können zusammengefasst werden:

/* alte Definition */ div {   border-color:red;   border-style:solid;   border-width:1px; }   /* neue Definition */ div {   border:solid 1px red; }

Das gleiche geht mit font-size, font-family, line-height und font-weight.

/* alt */ blockquote {   font-size:0.9em;   font-family:Arial,sans-serif;   line-height:12px;   font-weight:bold; }   /* neu */ blockquote {   font:bold 0.9em/12px Arial,sans-serif; }

Und es gibt weitere Beispiele, die nach diesem Muster funktionieren. Ich empfehle dazu die Beschreibungen auf CSS 4 You

In JavaScript können auch Codeoptimierungen vorgenommen werden: Aus x = x + 1; kann nach dem Umschreiben auf eine Inkrementierung x++; werden. Ebenso müssen auf Produktivsystemen Variablennamen nicht nachvollzogen werden können – aus var gesamtsumme kann per search-and-replace einfach var g1 gemacht werden. Ein automatisches Tool würde darauf achten, dass es nicht zu Variablenüberschneidungen kommt, deshalb die eins. Wenn man diese Optimierung per Hand durchführt, ist peinlichst genau darauf zu achten, dass man wirklich suchen-und-ersetzen benutzt, da man sonst eventuell ein Vorkommen einer Variable nicht umbenennt und das zu Fehlermeldungen und Funktionalitätseinbußen führen kann.

In JavaScript kann man auf die eingebauten Objekte (und Funktionen) wie window eine Referenzvariable legen. Statt

alert(window.navigator.appName);  alert(window.navigator.appVersion);  alert(window.navigator.userAgent);

könnte man

w=window;n=w.navigator;a=alert;  a(n.appName);  a(n.appVersion);  a(n.userAgent);

schreiben. Nebenbei erhöht diese Art der Programmierung auch die Ausführungsgeschwindigkeit des JavaScripts, da die Variablen einfacher auf die Objekte zugreifen können.
Ein Nebeneffekt dieses Tipps und dem im vorherigen Absatz ist, dass es Codediebe nicht mehr so leicht haben, den Code nachzuvollziehen und für eigene Aktionen zu verwenden.

JavaScript-Imports können optimiert werden. Man sieht oft Code-Blöcke wie diesen im Head einer Seite:

<script src="scripts/rollovers.js"></script>  <script src="scripts/validation.js"></script>  <script src="scripts/tracking.js"></script>

Wenn man die Inhalte der 3 Funktionen in eine große js-Datei kopiert, kann diese sehr viel einfacher geladen werden (nur noch eine HTTP-Anfrage nötig statt drei) und der Markup-Aufwand verringert sich ebenfalls.

Und zum Schluss noch einer der besten Tipps: Divs statt Layout-Tabellen nutzen. Das spart oft sehr viel Code und ist dazu noch wesentlich flexibler.

Ich sage es nochmal deutlich: Der Code, der am Ende nach all diesen Optimierungen herauskommt, ist für die Entwicklung nicht mehr zu gebrauchen, da er kaum noch Struktur enthält. Dem Browser ist das aber völlig egal, denn der verarbeitet die Scripte auch so ohne Probleme, nur müssen somit viel weniger Daten gesendet werden. Und ihre Benutzer interessiert der Quellcode auch nicht – die Hauptsache ist, dass es im Browser keinen Unterschied gibt. Weiterentwicklung wird eh mit dem Originalcode durchgeführt. Wer also sehr häufig Änderungen am Code durchführt, sollte sich den Einsatz eines (kostenpflichtigen) Tools wie dem W3 Compiler überlegen, statt die Optimierungen ständig von Hand durchzuführen.
Einzelne Tipps allein mögen nicht viel bringen. Wenn aber alle konsequent durchgeführt werden, können Ersparnisse von bis zu 30% herausspringen.

javascript

24.09.2019 21:42:35

Probleme mit dem Document Object Model

Das Document Object Model ermöglicht die Be- und Verarbeitung von XML-basierten Sprachen – so auch XHTML. Mittels DOM kann demzufolge der HTML-Baum nach Belieben erweitert, verkleinert oder verändert werden. Das klingt zunächst super, allerdings gibt es in den derzeitigen Browser-Versionen einige Probleme.

Das Document Object Model an sich ist eine sehr gut durchdachte (und standardisierte) Sache. Es verwandelt jeden Knoten des HTML-Baums eines Dokumentes in ein Objekt im Sinne der OOP. Besonders für AJAX-Anwendungen ist das DOM integraler Bestandteil. So können dessen Eigenschaften verändert werden (z.B. einem bestimmten Div-Element eine andere Hintergrundfarbe zuweisen) oder auf Methoden dieses Elementes zugegriffen werden (z.B. Kindelemente hinzufügen).

Das ganze funktioniert über JavaScript. Und leider ist es auch Zeiten einer durch die ECMA standardisierten JavaScript-Version so, dass es in verschiedenen Browsern Unterschiede gibt. Das ist bei JavaScript ähnlich wie bei CSS.
Dem IE ist manchmal der Unterschied zwischen id- und class-Attributen unklar. Beim Event Model gibt es ebenfalls Unterschiede. In vielen DOM-Methoden sind Bugs eingebaut usw. – ein Zustand, mit dem man nur ziemlich schwer cross-browser-fähige JavaScript-Anwendungen schrieben kann.
John Resig, der „Erfinder“ von jQuery und Mitarbeiter der Mozilla Foundation, hat nun die aktuellen Probleme mit dem Document Object Model in eine Präsentation gegossen:

Wer lieber das Video mit der Präsenation und Kommentaren von John Resig sehen möchte:


John Resig: "The DOM Is a Mess" @ Yahoo! Video

Welche Erfahrungen habt ihr im Umgang mit dem DOM gemacht? Kennt ihr solche Probleme? Ich würde mich über Kommentare freuen.

javascript

24.09.2019 21:42:35

JavaScript- und CSS-Dateien parallel downloaden

Um den HTML-Code schlank zu halten, doppelten Code zu vermeiden und Browser-Caching optimal einsetzen zu können, lagern viele Entwickler JavaScript- und CSS-Code in eigene Dateien aus und referenzieren diese Dateien anschließend im HTML-Code mit dem <script>- bzw. <link>-Tag. Doch sollte einiges beachtet werden.

Zuerst ist zu sagen, dass auf CSS-Dateien stets im <head> der Seite referenziert werden sollte und auf JavaScript am Ende des Bodys. Das ist deshalb gut, weil der Browser dann sofort alle CSS-Regeln hat und sofort mit der Formatierung der HTML-Elemente beginnen kann. Ansonsten wartet der Browser mit dem Rendering der Seite bis alle CSS-Dateien geladen sind.
JavaScript-Dateien sollten aus dem Grund direkt vor </body> eingefügt werden, da mit JavaScript HTML-Elemente erzeugt werden können, z.B. durch document.write() oder document.createElement(). Dadurch wird der HTML-Baum verändert. Deshalb muss der Browser mit dem Rendern des folgenden HTML-Codes warten bis die JavaScript-Datei geladen ist (denn der Browser weiß ja vorher nicht, was in der JS-Datei gemacht wird).
Mehr dazu, warum CSS im Head eingebunden werden sollte, gibt es bei Google Page Speed und im Yahoo Developer Network.

Nun kommt es aber manchmal vor, dass man noch einzelne kleine Code-Anweisungen nicht auslagern kann, beispielsweise wenn per PHP noch eine Variable eingefügt werden muss. Man hat dabei zwei Möglichkeiten:

  1. Dynamische CSS- bzw. JS-Datei per PHP-Script erstellen und Variable als GET-Parameter übergeben
  2. CSS- bzw. JS-Code mit dem Parameter direkt in den HTML-Code unterbringen

zu 1.: Diese Variante ist sehr schlecht, da mit der Änderung des Parameters sich der Dateiname der Ressource ändert. Dadurch muss die gesamte Datei erneut geladen werden, denn der Browser kann nicht auf die Datei aus dem Browser-Cache zugreifen.
zu 2.: erstmal noch kurz, was genau mit parametrisierten CSS- und JS-Anweisungen gemeint ist:

<style type="text/css"> .klasse { width: <?php echo $breite; ?> } </style> <link rel="stylesheet" href="restliches_CSS.css" type="text/css" />   <script type="text/javascript"> var elemente = "<?php implode(",",$elementeArray); ?>"; </script> <script src="restliches-Javascript.js" type="text/javascript"></script>

Diese Variante ist besser, da der größte Teil der Ressource aus dem Browser-Cache geladen werden kann. Aber es gilt folgendes zu beachten:
Wie oben gesagt, beginnt der Browser erst mit dem Rendering, sobald er alle CSS-Dateien und -regeln geladen hat. Deshalb sollten die parametrisierten CSS-Regeln, die im HTML-Code stehen möglichst auch im <head> stehen. Es ist aber zu beachten, dass JavaScript-Code zwischen 2 externen Ressourcen die Parallelisierung verhindert. Deshalb sollten stets alle externen JS-Dateien direkt hintereinander eingebunden werden. Erfolgt zwischen den einzelnen Referenzierungen zu CSS-Dateien oder JS-Dateien ein JS-Befehl, kann der Download nicht parallel erfolgen.

Beispiel (ganz schlecht):

<head> <link rel="stylesheet" type="text/css" href="stylesheet1.css" /> <script type="text/javascript" src="scriptfile1.js" /> <script type="text/javascript" src="scriptfile2.js" /> <link rel="stylesheet" type="text/css" href="stylesheet2.css" /> <link rel="stylesheet" type="text/css" href="stylesheet3.css" /> </head>

Hier wird der Download der Dateien stylesheet2.css und stylesheet3.css blockiert, weil die JS-Dateien dazwischen den HTML-Baum verändern könnten.

Beispiel (auch schlecht):

<head> <link rel="stylesheet" type="text/css" href="stylesheet1.css" /> <script type="text/javascript">  document.write("Hello world!"); </script> <link rel="stylesheet" type="text/css" href="stylesheet2.css" /> <link rel="stylesheet" type="text/css" href="stylesheet3.css" /> </head>

Zuerst wird die Ausführung des Inline-Style-Befehls durch stylesheet1.css verzögert. Anschließend verhindert die Inline-Anweisung wiederum, dass die Stylesheets parallel heruntergeladen werden können.

Beispiel (gut):

<head> <link rel="stylesheet" type="text/css" href="stylesheet1.css" /> <link rel="stylesheet" type="text/css" href="stylesheet2.css" /> <link rel="stylesheet" type="text/css" href="stylesheet3.css" /> <script type="text/javascript">    document.write("Hello world!"); </script> </head>

Zuerst alle externen Ressourcen einbinden. Alle werden parallel heruntergeladen. Anschließend das Inline-Script. Natürlich sollte das JavaScript möglichst weit unten in den Body geschrieben werden, da es genauso das Laden von Bildern verzögert.
Alle Beispiele stammen von hier.

Folgende Tipps kann ich demzufolge geben:

  • alle CSS-Datei-Referenzierungen per <link>-tag in den <head> direkt hintereinander schreiben
  • alle <script>-Tags direkt vor </body> (wenn möglich)
  • möglichst keine JS-Anweisungen (inline oder extern) zwischen CSS-Referenzierungen
  • keine JS-Inline-Anweisungen zwischen mehreren Referenzierungen auf JS-Dateien

Interessant in diesem Zusammenhang ist auch der Beitrag von Rakesh Pai namens Download JavaScript Files in Parallel. Er geht dabei auf das HTML-Attribut defer ein, das schon lange im Internet Explorer und seit Version 3.1 auch im Firefox implementiert ist. Damit umgeht man die Blockierung anderer Ressourcen durch JavaScript, da das defer einfach dem Browser mitteilt, dass das Script nicht sofort geladen werden muss, sondern erst, wenn der gesamte Body geladen ist. Dadurch brauchen dann andere Ressourcen nämlich auch nicht blockiert zu werden. Dadurch bräuchten die JS-Referenzierungen dann auch nicht mehr zwingend ganz am Ende des Bodys stehen.

javascript

24.09.2019 21:42:36

Optimierung externer Client-Ressourcen durch Ant-Deploy-Prozess

Auf diesem Blog gibt es viele interessante Beiträge, wie man die Performance serverseitig verbessert.
Eine mindestens genauso gute Möglichkeit für eine Verbesserung der Performance ist, es dem Client-Rechner etwas leichter zu machen. Dieser Beitrag soll einen Überblick über die Möglichkeiten dazu geben.

Engpässe finden
Eine sehr hilfreiche Erweiterung ist die Firefox-Extension YSlow. Diese identifiziert Engpässe und gibt im Yahoo!-Developer-Network direkte Anleitungen und Hilfsmittel. Einige sollen hier näher erklärt werden

Der deploy-Prozess
Viele Punkte in YSlow, wie z.B: „Make fewer HTTP requests“, „Gzip components“ oder „MinifyJS“ können mit dem sogenannten deploy-Prozess erreicht werden. Ein deploy ist eine Methode, die aus den Entwicklungsdateien optimierte Versionen für den online-Einsatz erstellt, z.B. indem Dateien zusammengefasst oder komprimiert werden.

ANT
Ein wunderbares Tool, um den deploy-Prozess umzusetzen, ist ANT. ANT ist ein Java-Tool von Apache Foundation, das entweder als Konsolen-Tool oder aber – was ich wesentlich interessanter finde – als Eclipse-Plugin verwendet werden kann. Verwendet man PHPEclipse, ist ANT direkt vorinstalliert und kann über Window – Show View – ANT eingeblendet werden.

build.xml – Allgemein
ANT wird über eine xml-Datei gesteuert, die build.xml. Diese folgt bestimmten Formalien, damit ANT die Datei versteht. Um die Datei zu verwenden, klickt man in der ANT-View auf die Ameise mit dem grünen Plus daneben und wählt die build.xml-Datei aus. Danach ist der play-Button in der ANT-View aktiv und der deploy-Prozess kann theoretisch starten ????

build.xml – Aufbau
Die build.xml ist in sogenannte tasks untergliedert. Damit kann man seinen deploy-Prozess sauber strukturieren.
Hier mal eine beispielhafte build.xml-Datei:

<?xml version="1.0" encoding="UTF-8"?> <project name="dein_projektname" default="deploy" basedir=".">     <property name="tmp" location="Pfad/Zum/Temporaeren/DeployVerzeichnis" />     <target name="deploy">         <echo message="Dein deploy-Task"></echo>     </target> </project>

Mit einer property kann man eine Variable setzen, auf die dann später mit ${propertyName} zugegriffen werden kann.
In einem target kann man jetzt alle beliebigen ANT-Tasks ausführen.

Konkrete Umsetzung
Nun geht es an die konkrete Umsetzung der Aufgaben „Dateien zusammenfassen“, „Minifyen“ und „Gzip“.

Dateien zusammenfassen
Dieser Teil hat folgenden Vorteil: während der Entwicklungsphase können z.B. CSS-Dateien auseinander gehalten werden (layout.css, colors.css, forms.css), in der Online-Version muss aber nur eine Datei (general.css) vom Server geladen werden. Das bedeutet weniger HTTP Requests und weniger HTML-Code, um die einzelnen CSS-Dateien einzubinden. Um eine zusammengefasste Datei zu erstellen, wird der concat-Befehl verwendet:

<concat destfile="${tmp}/general.css" force="no" fixlastline="true">     <filelist dir="pfad/zu/deinen/cssdateien">         <file name="layout.css" />         <file name="colors.css" />         <file name="forms.css" />     </filelist> </concat>

Darin gebt ihr die Zieldatei an und welche Dateien zusammengefasst werden sollen. Damit es kein Durcheinander in den Dateien gibt, die Datei am Besten in ein temporäres Verzeichnis (${tmp}) legen.

Minify
Minify entfernt Leerzeichen und Zeilenumbrüche und ersetzt
function meinLangerFunktionsname()
durch
function A()
Das bringt eine Ersparnis von bis zu 70% in der Dateigröße! Und keine Sorge, dass hier was durcheinander kommt ???? In aktuellen Projekten von mir werden über 100 JavaScript-Dateien damit gehandelt und es funktioniert 1a.
Um ein Minify durchzuführen gibt es verschiedene Tools, die man mit ANT ausführen kann. Ich verwende das von Yahoo. Dafür müsst ihr yuicompressor und YUIAnt runterladen. Anschließend folgenden Code außerhalb eines tasks in eure build.xml einfügen:

<taskdef name="yuicompress" classname="com.yahoo.platform.yui.compressor.YUICompressTask">    <classpath>      <pathelement path="pfad/zu/den/tools/yuicompressor-2.3.5.jar" />      <pathelement path="pfad/zu/den/tools/YUIAnt.jar" />    </classpath>  </taskdef>

So, jetzt haben wir die technischen Voraussetzungen, um den minify-Prozess durchzuführen. Das geht so:

<yuicompress linebreak="300" warn="false" munge="yes" preserveallsemicolons="true" outputfolder="${tmp}">   <fileset dir="${tmp}/" >     <include name="**/*.js" />     <include name="**/*.css" />   </fileset> </yuicompress>

Zwischenstand
Im temporären Verzeichnis liegen jetzt die zusammengefassen und minifyten JavaScript- und CSS-Dateien. Sind schon schön klein geworden, oder :-)? Um hier noch mehr an der Größe zu tun, können diese Dateien noch gzip-komprimiert werden.

Gzip-Komprimierung
Hierfür sind keine besonderen Tools notwendig, es reicht eine Zeile:

<gzip src="${tmp}/general.css" destfile="pfad/zu/deinem/htdocs/verzeichnis/general.css"/>

Der Gzip-Vorgang kann leider nicht über ein fileset gemacht werden, sondern jede Datei braucht eine eigene Zeile…

Ergebnis
Die Dateien sind jetzt perfekt für den Online-Einsatz vorbereitet und ihr müsst trotzdem kein bisschen auf Übersichtlichkeit oder andere Strukturierung während der Entwicklung verzichten.
Die fertige build.xml sieht so aus:

<?xml version="1.0" encoding="UTF-8"?> <project name="dein_projektname" default="deploy" basedir=".">     <!-- Variablen festlegen -->   <property name="tmp" location="Pfad/Zum/Temporaeren/DeployVerzeichnis" />     <!-- Definition des Minify-Tasks -->   <taskdef name="yuicompress" classname="com.yahoo.platform.yui.compressor.YUICompressTask">     <classpath>       <pathelement path="pfad/zu/den/tools/yuicompressor-2.3.5.jar" />       <pathelement path="pfad/zu/den/tools/YUIAnt.jar" />     </classpath>   </taskdef>     <!-- Der deploy-Task -->   <target name="deploy">     <echo message="Dein deploy-Task"></echo>       <!-- Die Dateien zu einer zusammenfassen -->     <concat destfile="${tmp}/general.css" force="no" fixlastline="true">       <filelist dir="pfad/zu/deinen/cssdateien">         <file name="layout.css" />         <file name="colors.css" />         <file name="forms.css" />       </filelist>     </concat>       <!-- Die Dateien minifyen -->     <yuicompress linebreak="300" warn="false" munge="yes" preserveallsemicolons="true" outputfolder="${tmp}">       <fileset dir="${tmp}/" >         <include name="**/*.js" />         <include name="**/*.css" />       </fileset>     </yuicompress>       <!-- Die Dateien gzipen -->     <gzip src="${tmp}/general.css" destfile="pfad/zu/deinem/htdocs/verzeichnis/general.css"/>   </target> </project>

Jetzt in der ANT-View in Eclipse play drücken ????
Wenn ihr es ausprobieren und nicht Stück für Stück aus diesem Artikel kopieren möchtet, könnt ihr die fertige build.xml auch herunterladen.

Ich hoffe, diese kurze Einführung in die Arbeit mit einem deploy-Prozess und ANT hat euch weitergeholfen.

Christian

javascript