Monday, July 23, 2012

Core JavaScript – Imperative Programmierung Teil 1


Imperative Programmierung Teil 1

Cover-klein in Core JavaScript - Imperative Programmierung Teil 1 - Ajaxer
Wie die meisten bekannten Sprachen lässt sich mit JavaScript imperativ programmieren. Im imperativen Programmierstil schreibt man ein Programm in einer Abfolge von Anweisungen, die den Zustand des Programms verändern. Der imperative Programmierstil wurde bereits in den 50er-Jahren geprägt. Auf ihm basieren die Programmiersprachen Fortran, Pascal und C, die zu den Vorgängern von JavaScript zählen.

Ausdrücke und Operatoren

JavaScript kennt die aus C und Java bekannten Ausdrücke und Operatoren wie Multiplikation (*), Divison (/) und Modulo (%). Addition und Subtraktion lassen sich wie gewohnt, inklusive bekannter Kurzschreibweisen wie ++ oder –, durchführen. Selbst Zeichenketten lassen sich mit dem Plus-Operator verketten.
Bekannte logische Operatoren wie UND (&&), ODER (||) und NOT (!) können in JavaScript ebenfalls wie gewohnt verwendet werden. Auch Bit-Operatoren wie das Verschieben von Bits oder die Definition von Bitmasken bergen keine Überraschungen.
Da JavaScript dynamisch typisiert ist, lassen sich diese Operatoren auch zum Casten von Werten oder Variablen verwenden. Da beispielsweise ausschließlich Zahlen multipliziert werden können, lassen sich Strings durch eine Multiplikation in eine Zahl wandeln:

typeof ("42"*1) // number

Vergleiche

Einen etwas anderen Weg als die meisten gebäuchlichen Sprachen geht JavaScript bei den Vergleichsoperatoren. Gleichheit und Ungleichheit können entweder streng oder normal geprüft werden. Eine normale Prüfung (==, !=) vergleicht nur Werte, Typen werden zum Vergleich dynamisch zur Laufzeit angepasst. Eine strenge Typprüfung (===, !==) vergleicht außerdem den Typ der Operanden. Da die normale Prüfung Überraschungen in sich bergen kann, bevorzugen viele Entwickler die strenge Prüfung.

42 == “42” // true
42 === "42" // false
Bei Ausdrücken, die zu wahr oder falsch valuiert werden gibt es in JavaScript einige Besonderheiten zu beachten. Ein Ausdruck ist dann unwahr, wenn er folgenden Wert hat:
  • false
  • null
  • undefined
  • ” (leerer String)
  • 0 (die Zahl Null) oder NaN (der Zahlenwert „Not a Number“)
Ein Ausdruck ist wahr für alle Werte, die nicht unwahr sind.
Achtung: Dies gilt auch für den String „false“ oder den numerischen Wert -1!
Die Eigenschaft, dass ein Ausdruck wahr für alle Werte ist, die nicht unwahr sind, lässt sich nutzen, um eine Zahl oder einen String in einen booleschen Wert zu wandeln:

!!0 // false
!!1 // true
Neben Gleichheit und Ungleichheit kann auch auf Größe (< , <=, >, >=) geprüft werden. Wichtig ist, dass JavaScript die Größe meist lexikalisch und ohne strenge Typprüfung prüft. Dies kann zu merkwürdigen Ergebnissen führen, wenn man nicht bedenkt, dass von einer lexikalischen Sortierung ausgegangen wird. So ist die Zeichenkette „42“ größer als die Zeichenkette „411“, die Zahl 42 ist allerdings kleiner als die Zeichenkette „411“.

Variablen

Variablen und Konstanten werden in der Regel Werte (Literale) oder Objekte bzw. Funktionen zugewiesen. Variablen deklariert man mit der var-Anweisung.

var x;
Variablen können bereits in der Deklaration einen Initialwert bekommen, sie lassen sich also gleichzeitig deklarieren und definieren. Solange einer Variablen kein Wert zugewiesen wurde, ist ihr Wert gleich dem besonderen Wert „null“. Ihr Typ wird zu „undefined“ ausgewertet.

var x;
x == null; // true
typeof x; // undefined
x = 5;
x; // 5
typeof x; // number
In einer var-Anweisung können mehr als eine Variable definiert werden. Diese Variablen werden durch Kommas getrennt.

var x, y, z;
In vielen Coding-Conventions wird verlangt, dass man alle in einem Gültigkeitsbereich verwendeten Variablen zu Beginn des Gültigkeitsbereichs deklariert. Daher ist es nützlich, dass man mehrere Variablen in einer einzigen Zeile deklarieren kann.

Blöcke und Gültigkeit von Variablen

Code lässt sich in JavaScript in Blöcken strukturieren. Blöcke werden wie schon in C und auch in Java in geschweifte Klammern eingeschlossen. Allerdings haben Blöcke weit weniger Bedeutung in JavaScript als in C oder Java.

{
var x = 10;
print(x); // 10
}
JavaScript behandelt nämlich den Gültigkeitsbereich von Variablen anders als C oder Java. Variablen, die in einem Block deklariert wurden, sind nicht nur in diesem Block, sondern in der ganzen Funktion, in der sie deklariert wurden, sichtbar.

{
var x = 10;
print(x); // 10
}
print(x); // 10
Gültigkeitsbereich für Variablen

Achtung: Anders als in vielen anderen Programmiersprachen, wie Java und C, wird durch einen Block kein neuer Gültigkeitsbereich für Variablen definiert. Das heißt, auch Variablen, die in einem Block definiert wurden, sind außerhalb des Blocks nach ihrer Deklaration sichtbar.
Wenn eine var-Anweisung innerhalb einer Funktion verwendet wird, so wird eine lokale Variable erzeugt. Diese Variable ist nur innerhalb der Funktion sichtbar. Von außen kann nicht auf sie zugegriffen werden. Außerhalb einer Funktion erzeugt die var-Anweisung jedoch eine globale Variable. Globale Variablen sind in der Regel nicht erwünscht, da sie den globalen Namesnraum verschmutzen.
Eine Variable kann auch ohne die var-Anweisung erzeugt werden, dann aber stets als globale Variable, was zu einer „Verschmutzung“ des globalen Namensraums führt. In ECMAScript 5th Edition ist im Strict Mode daher die Definition einer Variablen ohne die var-Anweisung nicht mehr erlaubt.
Verwende die Var-Anweisung

Eine Variable sollte stets durch die Var-Anweisung definiert werden.
Außer über die var-Anweisung sollen sich lokale Variablen in der kommenden ECMAScript 6th Edition auch mit der let-Anweisung deklarieren und definieren lassen. Die let-Anweisung soll eindeutig zwischen lokalen und globalen Variablen unterscheiden. Zudem hat die let-Anweisung einen Blockgültigkeitsbereich und keinen Funktionsgültigkeitsbereich. Sie kommt daher der Variablendefinition anderer Sprachen wie Java sehr viel näher.
Neben Variablen lassen sich in der kommenden ECMAScript 6th Edition auch Konstanten defi-nieren. Werte werden Konstanten bereits während der Deklaration zugewiesen, sie werden direkt definiert. Diese Werte lassen sich später nicht mehr ändern.

const PI = 3.14159265;
Wenn man allerdings versucht, den Wert einer Konstanten später zu verändern, dann ignorieren die meisten Laufzeitumgebungen dies einfach, ohne einen Fehler zu verursachen. Dies kann zu schwer zu findenden Bugs im Code führen.

Zahlen

Zahlen, number-Literale, werden als 64-Bit-Fließkommazahlen (64 Bit entsprechen 8 Byte) gespeichert. Dies entspricht dem Typ double in Java. In Zukunft könnte sich dies durchaus ändern. Von der Genauigkeit her bedeutet dies, dass natürliche Zahlen bis zu einer Größe von 15 Zeichen (9E15) als genau angesehen werden können. Bruchzahlen sind nur so genau wie möglich anzusehen. Dies muss beispielsweise bei Währungsberechnungen berücksichtig werden.

0.05 + 0.01 = 0.060000000000000005
Es gibt keine Unterscheidung zwischen natürlichen Zahlen und Bruchzahlen.

const C1 = 299792458;
const C2 = 2.99792458E8; // C1 == C2
var saldo = -768;
Zahlen lassen sich auch hexadezimal ausdrücken.

print(0xFF); // liefert 255

NaN

NaN (Not a Number) ist keine Zahl. Über die Funktion isNaN lässt sich überprüfen, ob ein Wert eine Zahl ist. NaN lässt sich nicht vergleichen, auch nicht mit sich selbst.

var notANumber1 = NaN;
print(notANumber1 == NaN); // liefert false
print(isNaN("Hello")); // liefert true
print(isNaN("3.27E6")); // liefert false

Infinity

Eine besondere Zahl ist Infinity (Unendlich). Unendlich sind alle Zahlen, die größer sind als der Wertebereich, den eine Zahl annehmen kann. Vergleicht man zwei infinite Zahlen miteinander, so ist das Ergebnis wahr.

var infinite = 2E308;
print(infinite); // liefert Infinity
print(Infinity == infinite); // liefert true
print(infinite == infinite * 2); // liefert true

Formatierung und Konvertierung

Mit Zahlen möchte man nicht nur rechnen, sondern man möchte die Zahlen auch formatiert als String zur Anzeige bringen. Zur Formatierung von Zahlen gibt es verschiedene Methoden wie num-ber.toFixed, number.toPrecission, number.toString oder number.toExponential. Einzelheiten dazu lassen sich dem Anhang des Buchs entnehmen. Um Strings (zurück) in Zahlen zu wandeln, gibt es in JavaScript zwei globale Funktionen: parseInt und parseFloat. Auch diese werden im Anhang näher be-schrieben.

Zeichenketten

Zeichenketten werden im String-Literal gespeichert.

typeof "Hello World" // String
Als JavaScript entwickelt wurde, war Unicode noch ein 16-Bit-Zeichensatz. Darum ist ein Zeichen in JavaScript 16 Bit breit. Es gibt kein Literal für ein einzelnes Zeichen (Character). Ein einzelnes Zeichen lässt sich durch eine ein Zeichen lange Zeichenkette ausdrücken.
Zeichenketten werden durch einfache oder doppelte Anführungszeichen umschlossen. Als Escape-Zeichen wird der Backslash „\“ verwendet.

var myString = "Hello World\nJetzt kommt eine neue Zeile";
Unicode-Zeichen lassen sich direkt über ihren Unicode-Wert ausdrücken.

print("¢" === "\u00A2"); // true
Die Länge eines Strings lässt sich über die length-Eigenschaft ermitteln. Dies ist keine Methode, sondern eine echtes Attribut.

print("Hello World".length); //11
Wie alle Literale sind Strings unveränderlich. Methoden, die auf einem String aufgerufen werden, verändern diesen also nicht, sondern geben einen neuen String zurück.
Die Methoden des String-Literals entsprechen den Methoden des String-Objekts, da intern das Literal zu einem Objekt wird, wenn eine Methode aufgerufen wird.

Boolesche Werte

Das Boolean-Literal hat zwei Werte: true und false.

typeof true // boolean

Arrays

Ein Array ist eine lineare Liste von Werten, bei denen über Positionsangaben auf einzelne Werte zugegriffen werden kann. Man kann in einem Array Werte unterschiedlicher Typen mischen.

var planets = ["Merkur", "Venus", "Erde", "Mars"];
print(planets[2]); // Erde

Array-Literal und Array-Objekt

Array-Literale erzeugen Array-Objekte. Das heißt, eine durch ein Array-Literal definierte Variable ist nicht vom Typ „array“, sondern vom Type „object“.

typeof planets // object
Dies ist ein typisches Problem bei der Verwendung von Arrays. Oft wird in einer Methode als Eingabeparameter ein Array erwartet, man bekommt aber ein Objekt (z.B. einen String) oder es wird ein Objekt (z.B. ein String) erwartet und man bekommt ein Array. Es obliegt dem Programmierer zu prüfen, ob er ein Array oder ein anderes Objekt bekommen hat.
Der typeof-Operator ist hier nicht hilfreich, da dieser sowohl bei einem String-Objekt als auch bei einem Array schlicht object zurückliefert. Zu prüfen, ob das übergebene Objekt die length-Eigenschaft hat, funktioniert leider auch nicht, denn Array-ähnliche Objekte wie Strings haben auch diese Eigenschaft. Man muss also zusätzlich prüfen, ob der Konstruktor des übergebenen Objekts der Array-Konstruktor ist:

function isArray(value) {
return (value && // value ist defined
typeof value === "object" && // value ist ein Objekt
value.constructor === Array) // Konstruktor ist Array
}
print(isArray(["eins", "zwei", "drei"])); // true
print (isArray("Hello")); // false

toArray-Hilfsmethode

Manchmal ist es auch egal, ob das übergebene Objekt ein Array oder ein String ist. Array-ähnliche Objekte wie Strings lassen sich mit einer Hilfsmethode, die sich u.a. in der jQuery-Library von John Resig befindet, in Arrays wandeln. Inhalte von Arrays selbst werden durch diese Hilfsmethode nicht verändert:

function toArray(value) {
return Array().slice.call(value, 0);
}
print(toArray("Hello")); // H,e,l,l,o
print(toArray(47)); // empty
print(toArray(["eins", "zwei", "drei"])); // eins,zwei,drei

Reguläre Ausdrücke

Reguläre Ausdrücke in JavaScript entsprechen im Wesentlichen den regulären Ausdrücken in Perl. Reguläre Ausdrücke lassen sich in JavaScript direkt als Literal angeben. Sie werden durch einen Slash eingeleitet und auch beendet.

var regexp = /\((\d*)\)/;
Allerdings gibt es keinen Basistyp regexp. Ein solches Literal erzeugt eine Funktion.

typeof /\((\d*)\)/; // function
Da reguläre Ausdrücke eine eigene Sprache bilden, können sie sehr komplex werden. Darum er-folgt an dieser Stelle nur eine kurze Einführung.
Reguläre Ausdrücke werden verwendet, um Zeichenketten zu validieren bzw. diese Zeichenketten auf Muster abzubilden. Um eine Zeichenkette zu valideren, muss man ein Muster (Pattern) definieren, das einem Suchkriterium entspricht. Dieses Suchkriterium kann man dann auf eine Zeichenkette anwenden.
Muster werden aus String-Literalen und Metazeichen gebildet. Der oben bereits definierte reguläre Ausdruck sucht in einer Telefonnummer die Vorwahl. Um zu testen, ob eine Zeichenkette eine Vorwahl enthält, lässt sich die string.search-Methode verwenden:

var regexp = /\([\d\w]*\)/;
print("Telefon: (040) 55555".search(regexp)); //9
Der reguläre Ausdruck sucht eine öffnende Klammer „\(“ gefolgt von beliebig vielen Zahlen „\d“ oder Leerzeichen „\w“ ausgezeichnet durch „*“, gefolgt einer schließenden Klammer „/)“.
„\d“ und „\w“ sind Metazeichen.
Auf die Zeichenkette “Telefon: (040) 55555″ erfolgt eine Abbildung des regulären Ausdrucks. Die string.search-Methode liefert eine positive Position zurück, an der das gesuchte Muster beginnt. Also enthält die Zeichenkette eine Vorwahl.
Um zu überprüfen, ob eine Zeichenkette ausschließlich eine Vorwahl enthält, muss der reguläre Ausdruck durch weitere Metazeichen ergänzt werden.

var vorwahl = /^\([\d\w]*\)$/;
print("Telefon: (040) 55555".search(vorwahl)); //-1
print("(404)".search(vorwahl)); // 0
Das Metazeichen „^“ drückt aus, dass vom Anfang, das Metazeichen „$“, dass bis zum Ende der Zeichenkette der reguläre Ausdruck abgebildet werden muss.
Neben Metazeichen gibt es Flags, die einen regulären Ausdruck unabhängig von Groß-/Kleinschreibung machen oder ihm Mitteilen, dass über Zeilengrenzen hinweg abgebildet werden soll. Diese Flags werden an das Ende des regulären Ausdrucks angehängt.

Kommentare

Code lässt sich durch Kommentare leichter verständlich machen. Es gibt zwei Arten von Kommen-taren: Blockkommentare und Zeilenkommentare.
Blockkommentare
Blockkommentare können über Zeilen hinweg laufen. Sie werden durch /* */ eingeschlossen. Diese Zeichenfolge wurde gewählt, da sie in gewöhnlichem Programmcode nur sehr selten vorkommt. Trotzdem ist diese Zeichenfolge nicht gänzlich ausgeschlossen.

/*
var matches = /\d*/.match("1234");
*/
Dieses Listing führt zu einem Syntaxfehler, da in regulären Ausdrücken (siehe oben!) durchaus diese Zeichenfolge vorkommen kann.

$ v8 blockcomments.js
blockcomments.js:2: SyntaxError: Unexpected token .
var matches = /\d*/.match(1234);
^
SyntaxError: Unexpected token .
Zeilenkommentare
Zeilenkommentare gelten nur bis zum nächsten Zeilenumbruch. Sie beginnen mit einem Double-Slash //. Einige Autoren empfehlen, lediglich Zeilenkommentare zu verwenden.

// Folgender Codeblock demonstriert den Zeilenkommentar.
// Es wird der Wert 5 ausgegeben, da das Inkrement auskommentiert wurde.
var a = 5;
// a++;
print(a);
Für reine Dokumentationszwecke sind jedoch Blockkommentare lesbarer.

/*
Folgender Codeblock demonstriert den Zeilenkommentar.
Es wird der Wert 5 ausgegeben, da das Inkrement auskommentiert wurde.
*/
var a = 5;
// a++;
print(a);

Tokens und Whitespaces

Der Quelltext eines JavaScript-Programms wird in eine Reihe von Tokens, Kommentaren und Whitespaces gewandelt. Der Interpreter wertet diese von links nach rechts aus.
Whitespaces, also Leerzeichen, Tabs und Zeilenumbrüche, werden verwendet, um einzelne Tokens voneinander zu trennen. Darüber hinaus haben sie keine Bedeutung. Man setzt sie ein, um Code zu strukturieren.
Eine Anweisung kann man mit einem Semikolon abschließen. Dieses Semikolon ist allerdings optional. In Fällen, in denen Semikola fehlen, wird stets die längst mögliche Sequenz von Zeichen interpretiert. Daher führt folgendes Skript, wenn man es nicht in einer REPL verwendet, zu einer unerwarteten Ausgabe: 1.625

var a = 5 / 8
-8 + 9
print(a) // 1.625
Die Zeilen (1) und (2) werden von der Laufzeitumgebung nämlich zu einer einzigen Zeile zusam-mengefasst und dann wie folgt interpretiert.

var a = 5 / 8 - 8 + 9;
print(a);
Es gibt zwar einige Programmierer, die einen möglichst minimalen Stil pflegen und auf alle überflüssigen Zeichen verzichten. Trotzdem empfiehlt es sich, auch wenn Semikola optional sind, diese zur besseren Lesbarkeit des Codes und zur Vermeidung von Fehlern zu verwenden.

Wednesday, July 18, 2012

Core JavaScript – Typen und Werte

Einleitung

Cover-klein in Core JavaScript - Typen und Werte - Ajaxer
Eine Skriptsprache wird dazu verwendet, um ein bereits bestehendes System zu verändern, anzupassen oder um wiederkehrende Abläufe zu automatisieren. In einem solchen System existieren bereits Funktionalitäten. In der Regel lassen sich diese entweder über ein User Interface oder über Befehle aufrufen. Wenn das System seine Funktionen über eine programmierbare Schnittstelle anbietet, dann ist es scriptbar. Ein gutes Beispiel für ein Script ist ein Shell-Script, das einem lästige Wartungsaufgaben abnimmt.
Bei JavaScript steckt der Charakter der Scriptsprache bereits im Namen. Allerdings wurde JavaScript nicht entwickelt, um Java zu scripten; JavaScript wurde entwickelt, um eine HTML-Seite in einem Browser zu verändern.
Während der Browser Schnittstellen zum Dokumentenbaum und zum Netzwerkprotokoll bietet, beinhaltet die Sprache JavaScript selbst nur die Teile, die unabhängig vom Browser sind. JavaScript selbst ist also nicht abhängig vom Browser und kann auch außerhalb des Browser verwendet werden.
Egal, ob man in JavaScript im Browser, in einer nativen Applikation oder auf dem Server entwickeln möchte, man sollte die Kernkonzepte der Sprache verstehen. Die Kernkonzepte von JavaScript werden als Core JavaScript bezeichnet. Core JavaScript wird von allen JavaScript Laufzeit-Umgebungen implementiert. Auch Adobes Flash baut mit ActionScript auf Core JavaScript auf.
Obwohl JavaScript eine Scriptsprache ist, bietet sie viele Programmierparadigmen. Man kann JavaScript imperativ oder funktional, prototypisch oder objektorientiert programmieren.

Typen und Werte

JavaScript kommt mit wenigen Typen aus. Diese Typen lassen sich als Literale direkt im Programmcode verwenden.

Schwache Typsierung

JavaScript ist eine nur schwach typisierte Programmiersprache. Es kennt nur wenige Basistypen: Zahlen (number), boolesche Werte (boolean) und Zeichenfolgen (string). Neben diesen natürlichen Basistypen gibt es zwei besondere Werte: null und undefined.
Null ist ein Keyword, das einen null-Wert ausdrückt. Eine Variable hat dann den Wert null, wenn ihr noch kein (anderer) Wert zugewiesen wurde. Null selbst ist (in meinen Augen fälschlicherweise) ein Objekt.
Undefined ist ein Keyword, das zum Ausdruck bringt, dass z.B. eine Variable noch nicht defi-niert ist. Undefined selbst hat kein Typ. Der Typ von undefined selbst ist ebenfalls undefined.

Literale

Man kann in JavaScript direkt Werte dieser Basistypen verwenden, ohne sie vorher einer Variablen zugeweisen haben zu müssen. Diese Werte, die direkt verwendet werden können, nennt man Literale. Literale werden also zur Darstellung von Basistypen wie Zahlen oder Strings (Zeichenketten) verwendet.
Literale sind unveränderlich. Man kann den Wert eines Literals nicht verändern, da das Literal selbst der Wert ist.
Anders als in vielen anderen Programmiersprachen haben Literale, obwohl sie keine Objekte sind, einen Satz von Standardmethoden. Allerdings lassen sich Standardmethoden nicht direkt auf allen Literalen direkt anwenden, sondern erst auf Variablen eines Literals.
Literale kann man von Objekten dadurch unterscheiden, dass ihre Typ-Namen mit Kleinbuchstaben benannt werden. Objekte werden per Konvention durch einen führenden Großbuchstaben gekennzeichnet.

Typeof-Operator

Um zu erkennen, von welchem Typ ein Wert oder eine Variable ist, gibt es in JavaScript den Typeof-Operator:

typeof "Hallo Welt" // string
typeof 1234 //number
typeof true // boolean
typeof {"name": "Peter"} // object
typeof [1,2,3,] // object
Der Typeof-Operator lässt sich allerdings nicht verwenden, um festzustellen, von welchem Typ ein Objekt oder eine Funktion ist, denn bei diesen Typen liefert er folgerichtig stets „function“ oder „object“.

Typenlose Verwendung

Obwohl JavaScript Typen kennt, ist es keine statisch oder stark typisierte Sprache. Typen werden erst zur Laufzeit ermittelt und – wenn möglich – dynamisch angepasst. Es gibt also anders als in statisch tpyisierten Sprachen keinen Cast-Operator. JavaScript versucht Typen in ihrem Kontext implizit zu konvertieren. Daher kann man in JavaScript beispielsweise auch Zahlen mit Zeichenketten vergleichen:

123 == "123" // true
Oft geht diese dynamische Konvertierung gut und das Programm macht genau das, was der Programmierer beabsichtigt hat. Um sich nicht auf den Zufall verlassen zu müssen, ist für Programmierer, die aus dem statisch-typisierten Lager kommen, einiges Umdenken gefordert, um sich mit einer dynamisch typsierten Sprache anzufreunden

Monday, May 14, 2012

JavaScript für Enterprise-Entwickler: Professionell programmieren im Browser und auf dem Server

Buch-Cover

JavaScript ist längst nicht mehr nur für klassische Webprogrammierer interessant. Auch bei der Entwicklung von Unternehmensanwendungen spielt JavaScript eine immer größere Rolle: Enterprise-Entwickler mit Java- oder .NET-Hintergrund programmieren selbst Server- und Browser-seitig mit JavaScript, oder sie überarbeiten JavaScript-Code, der von Webagenturen erstellt wurde.

Das Buch "JavaScript für Enterprise-Entwickler: Professionell programmieren im Browser und auf dem Server" behandelt daher die Schwerpunkte, die für Entwickler aus dem Enterprise-Umfeld beim Umgang mit JavaScript besonders von Bedeutung sind.

Nach einem kompakten Überblick über die Kernkonzepte von JavaScript geht der Autor im Detail auf wichtige Themen der professionellen Anwendungsentwicklung ein. Behandelt werden u.a.:

  • JavaScript als funktionale, prototypische und objektorientierte Sprache
  • Testen
  • Packaging
  • Entwurfsmuster
  • node.js: JavaScript auf dem Server

Zielgruppe sind professionelle Backend-Enwickler, die sich schnell in JavaScript einarbeiten wollen. Darüber hinaus spricht das Buch Webentwickler an, die über den Browser-Rand hinausblicken möchten.

Kenntnisse in der Webentwicklung sind für die Lektüre erforderlich, ein Java-EE- (oder .NET-) Hintergrund ist hilfreich.

Die Website zum Buch ist hier. Das Buch erscheint heute in zwei Wochen.

Wednesday, March 28, 2012

MobileTech Conference 2012 - Tag 1

Mein Kollege Norman Erck und ich sind auf der MobileTech Conference 2012 in München.



Die Konferenz wurde durch Sebastian Meyen vom Software&Support-Verlag eröffnet. Er übergab die Session an Maks Giordano von Nunatak. Wer vom Design mobiler Applikationen spricht, meint dabei meist das Design von grafischen Oberflächen. Dass Audio genauso wichtig sein kann, liegt schon in der Historie der Telekommunikation begründet. Mobile Anwendungen laufen auf modernen Telefonen. Telefone wurden erfunden, um Sprache zu übertragen.



Manfred Lutzky von Fraunhofer IIS stellte den AAC-ELD-Codec vor. Dieser Codec ist ein Full HD Voice-Codec, der heute schon in Apple Facetime verwendet wird und in iOS 5 auch Entwicklern von Apps zur Verfügung steht. Die AAC-ELD-Codec ähnelt dem AAC-Codec, ist aber auf geringe Verzögerungen optimiert, was wichtig für die Real-Time-Kommunikation ist.



Philipp Eibach stellte sein neues Startup wahwah.fm vor. Eibach war schon an der Gründung von last.fm beteiligt und ist schon lange im Bereich Social Music unterwegs. Auf dem Smartphone hört jeder Musik für sich alleine. Das Ziel von wahwah.fm ist, dass Musik wieder gemeinsam und zusammen gehört wird. So lässt sich Musik von Bekannten und Unbekannten entdecken. In wahwah.fm kann jeder Nutzer mit seiner Playlist auf Sendung gehen. Jeder Nutzer ist damit ein eigener, kleiner Radiosender. Andere Nutzer können sich in diese Sendung einklinken und mithören. Hörer eine laufenden Sendung könnten über Chats etc. interagieren. Die Location eines Senders lässt sich bei der Suche nach Sendern berücksichtigen. wahwah.fm ist eine prima Möglichkeit, Musik neu zu entdecken.



Michael Breidenbrücker von Reality Jockey Ltd. zeigte RjDj. RjDj lässt einen Nutzer selbst Musik erschaffen. Dabei verwendet RjDj nicht ein klassisches User Interface sondern bezieht das komplette Sensor-Netzwerk des Smartphones ein. Musik wird also durch die Location, die Bewegung des Nutzers und sein Umfeld erschaffen. Der Nutzer taucht so in eine audiovisuelle Umgebung ein, in der die Intensität der Immersion sehr hoch ist. Auf Basis von RjDj wurden bereits weitere Apps entwickelt wie die Audio-App zum Film Inception, die in Zusammenarbeit mit dem Soundtrack-Komponisten Hans Zimmer und dem Regisseur Christopher Nolan entstanden sind.



Anika Brinkmann, die als Kommunikationsdesigner Mobile-Knowledge.de verantwortet, eröffnete den Mobile Web-Track. Sie gab einen allgemeinen Überblick über die Themen des Tracks: Was bedeutet „Always on“? Hat always online nur gute oder auch unangenehme Seiten wie die allzeitige Bereitschaft von Arbeitnehmern, die mit modernen Kommunikationsendgeräten ausgestattet werden. Ist „Always on“ nur ein Versprechen oder schon heute Realität? Gibt es immer noch die Schere zwischen Stadt und Land was die Netzabdeckung von UMTS und LTE angeht? Der Footprint (die Größe) der Seiten wächst im Moment noch stärker als die verfügbare mobile Bandbreite. Was nutzt die Cloud, wenn wenn gerade keine Verbindung zum Internet herstellen kann? Wie muss mit Nutzerdaten umgegangen werden - besonders im Spannungsfeld zwischen den Wünschen des Marketings und den Anforderungen des Datenschutzes? Wie befreie ich Daten aus Datensilos wie SAP oder gängigen CRM-Systemen? Content (sprich: Daten) muss in unterschiedlichen Kontexten unterschiedlich genutzt werden können. Daher muss Content in offenen Formaten (kein Flash) und in unterschiedlichen Ausprägungen (z.B. auch in hoher Auflösungen für Retina-Displays) vorliegen, um genutzt werden zu können. Um all diese Fragen zu beantworten, sollte zunächst eine Strategie erarbeitet werden. Aus dieser Strategie können Konzepte entwickelt werden. Content sollte sowohl für’s Web als auch für mobile Anwendungen verwendet werden können. Dabei sollte man auf offene, zukunftssichere Plattformen statt auf proprietäre Technologien setzen. Wir sind hier und jetzt dabei, ein neues Level der Kommunikation zu erreichen. Zu den Technologien, mit dem dies umgesetzt werden wird, gehören sicherlich HTML5 und CSS3.



Ulrich Schmidt von sevenval zeigte die Offlinemöglichkeiten von HTML5-Webapplikationen. Der Grund, warum man überhaupt Offline-fähige Applikationen braucht, ist die unvollständige Netzabdeckung. Gerade wenn man beispielsweise in der Bahn unterwegs oder im Ausland-Urlaub ist, dann hat man oft kein Netz. Offline zu sein ist ein temporäres Problem, das durch HTML5 gelöst werden kann. Konzeptionell ist zwischen Daten und Funktionen zu trennen. Entweder man kann nur Daten oder nur Funktionen offline vorhalten. Oder man kann eine komplett Offline-fähige Webapplikation erstellen. Technologien für ein „Aktives Offline“ für Daten sind Local Storage, das als Cookie-Ersatz in allen Browsern läuft, WebSQL, das inzwischen deprecated ist aber zumindest auf iOS und Android zur Verfügung steht, und IndexDB, die in neueren Browsern (allerdings noch nicht in mobilen Browsern) als Weiterentwicklung von Local Storage und WebSQL angesehen werden kann. Als Bleeding Edge kann die FileSystem API angesehen werden, die ab Chrome 13 einen direkten Zugriff aufs Filesystem zur Ablage von Binärdaten erlaubt. „Passives Offline“ für Funktionalität (JavaScript) und Ressourcen (HTML, CSS, Bilder) bietet der Application Cache. Die Herausforderung bei der Verwendung des Application Caches ist es, diesen „aktuell“ zu halten und das Update-Verhalten sinnvoll zu implementieren. Der Application Cache schlägt HTTP-Header (außer beim Firefox). Die Schritte zur Erstellung einer Offline-fähigen Webapplikation sind laut Schmidt zuerst das Erstellen von Layout und Struktur (analog zu einer normalen Webapplikation), danach das Einführen von Local Storage zur Speicherung der Daten und anschließend die Verwendung des Application Caches zur Speicherung der bereits erstellten Layout und der Struktur. Der Vortrag schloss mit Empfehlungen aus der Praxis zum Umgehen von Fallstricken.



Sven Günther von it-agile zeige die API des Zeitungskiosks in iOS 5. Zeitschriften-Apps lassen sich mit NewsstandKit implementieren. NewsstandKit bietet Features wie Push Notificiation und Background Downloads. Außerdem lässt sich programmatisch das Programm-Icon verändern, so dass das Cover der aktuellen Ausgabe als Icon verwendet werden kann. Payments lassen sich über das StoreKit abwickeln. Zur Anzeige von Content sind WebViews ungeeignet, das sich mit WebViews nur schwer die Anmutung einer Zeitung oder eines Magazins nachahmen lässt. Besser geeignet dazu ist CoreText und der UIPageViewController.



Torsten Drees präsentierte die MEAP (Mobile Enterprise Application Plattform), die mit einer Multi-Channel-Architektur die Herausforderung aktueller Enterprise Mobility Trends lösen soll. Eine Implementierung der MEAP ist die Magic Integration Plattform von Magic Software. Dieser Vortrag war ein reiner Marketing-Vortrag.



Georg Konjovic, der als Director Premium Content die Konzern-weite Paid Content-Stratgie bei Axel Springer verantwortet, präsentierte die Ziele des Verlags. ASV sieht sinkende Print-Reichweiten nicht als Gefahr sondern als neue Chance für den Qualitätsjournalismus. Die Paid Content-Stragie vom Axel Springer Verlag äußert sich in ca. 70 Apps (teilweise HD-Apps für das iPad), der Plattform iKosk (ePapers im Portable Document Format, der iKosk steht für andere Verlagshäuser offen), einem News-Aggregator (myEdition), der sich zurzeit in einer Closed Beta befindet, und zahlreichen News-Sites. Die größte Herausforderung ist die Schaffung neuer Abo-Modelle bzw. die Migration der Nutzer von kostenlosen Web-Diensten zu Nutzern kostenpflichtiger Dienste. Anders als in den USA entwickelt sich der Markt für Qualitätsjournalismus in Deutschland positiv. Vor allem Nutzer des iPads haben eine hohe Zahlungsbereitschaft. Alle zukünftigen Angebote bei Axels Springer sollen ein Preisschild bzw. einen Abo-Preis haben.



Rosemarie Wirtsmüller von Antenna International zeige Apps für Museumsbesucher. Diese Apps sind viel mehr als reine eGuides. Sie informieren den Nutzer schon vor dem Besuch des Museums (Pre-Visit-Kontakt) und unterstützen in bei der Nachbereitung (Post-Visit-Kontakt). Dies äußert sich auch in den Download-Zahlen. Diese Apps werden sogar von Nutzern verwendet, die gar nicht das Museum besuchen sondern sich mit der App über das Thema einer Ausstellung selbst lange nach der eigentlichen Ausstellung informieren möchen.


Tuesday, October 04, 2011

JSConf.eu - Roundup Tag 2

Nach einer richtig guten Party ging es am zweiten Tag mit der JSConf.eu direkt weiter.

Tomasz Janzcuk von Microsoft zeigte, wie sich leichtgewichtige Node-Anwendungen (Singe-Page-Anwendungen, die auf node.js aufbauen) kostengünstig skalieren lassen. Es lassen sich nicht nur einzelne Node-Instanzen pro virtualisierter Maschine, sondern auch innerhalb einer virtualisierten Maschine verschiedene Node-Prozesse starten. Statt einzelner Node-Prozesse lassen sich zudem auch leichtgewichtige Threads verwenden. Dies ist aber nicht effektiv genug. Erst mit dem Verwenden von isolierten Kontexten innerhalb einzelner Threads lassen sich die Betriebskosten einer leichtgewichtigen Node-Anwendung signifikant drücken.

Andrea Giammarchi von Nokia berichtete von Problemen, die beim Entwickeln von HTML5-Apps auf neuen Endgeräten (Mobile und Tablet) auftreten. HTML5 ist kein fester Standard und die Implementierungen in verschiedenen (mobilen) Browsern sind noch sehr unterschiedlich. Er konnte Lösungen und Workarounds für gängige Probleme aufzeigen. Dieser Talk schien direkt aus der Praxis zu kommen und Giammarchi Tipps erscheinen sehr wertvoll.

Jed Schmidt rockte den Saal mit seinem Vortrag über 140byt.es.

Jakub Siemiątkowski implementierte Voxels in JavaScript. Wenn eine 3D-Welt nicht aus Polygonen sondern aus Würfeln zusammengesetzt wird, dann nennt man diese Würfel Voxel bzw. die Welt Voxelspace. Voxel sind sehr speicher- und rechenzeitintensiv. Trotzdem konnte er eine - wenn auch langsame und nicht besonders stabile - Implementierung live demonstrieren.

Lea Verou hielt einen sehr umfangreichen Talk über Polyfills. Polyfills sind Softwarekomponenten, die fehlende Implementierungen von spezifizierten Features in Webbrowsern durch JavaScript nachimplementieren. Wenn ein Browser das spezifizierte Feature selbst implementiert, dann werden die Polyfills nicht verwendet sondern die native Implementierung des Browser führt das Feature selbst aus. Polyfills sind also Softwarekomponenten, die nur so lange leben sollten, bis die jeweiligen Features von allen Zielbrowsern unterstützt wird.

James Coglan verwendete Websockets, um nahezu alle Laptops im Raum fernzusteuern, um darauf Musik wiederzugeben.

David Coallier demonstrierte node-php. Mit node-php lassen sich PHP-Anwendungen in Node ausführen. Durch node-php sind Node und PHP nicht länger Konkurrenzplattformen sondern lassen sich gemeinsam in einer Webanwendung nutzen.

Tom Robinson, einer der Autoren des Cappuccino Webframeworks, hielt einen Talk über Compiler und Interpreter. Er führte anschaulich und durch Beispiele in die Welt von Compilern ein, die selbst in JavaScript implementiert sind oder JavaScript als Zielsprache erzeugen. Jeder Entwickler sollte selbst in der Lage sein, einen eigenen Compiler für eine eigene (domänenspezifische) Sprache zu schreiben, denn dies ist nicht so schwer, wie es auf den ersten Blick erscheint.

Douglas Campos präsentierte dyn.js. Dyn.js ist eine JavaScript-Implementierung auf der Java Virtual Machine. Anders als Rhino, das noch auf Java 1.2 aufbaut, verwendet dyn.js „Invoke Dynamic“, ein neues Feature der JVM seit Java 7. Durch „Invoke Dynamic“ kann JavaScript für die JVM sehr viel einfacher und evtl. sogar performanter implementiert werden als dies noch Rhino tut.

Michael Aufreiter hielt einen sehr interessanten Talk über data.js. Data.js ist eine JavaScript-Biblothek zum Bauen von datengetriebenen Webapplikation. Es bietet Features zur Defintion, Manipluation und Persistierungen von Graphen in Node und / oder im Webbrowser. Data.js ist die technische Basis von substance.io, einem webbasierten Dokumentenmanagementsystem.

Erik Corry führte in den neuen Garbage Collector von Googles V8 ein. Zudem konnte er Tipps zeigen, um Memory-Leaks zu vermeiden.

Michal Budzyinski hielt einen unterhaltsamen Talk über anaglyphe 3D-Darstellung (jene bunten Bilder, die über zweifarbige Brillen erst dreidimensional wahrgenommen werden). Er konnte in einer Live-Coding-Session eine Demo entwickeln, in dem Side-By-Side-Bilder der NASA anaglyph im Browser dargestellt werden. Dazu verwendete er das Canvas-Element und JavaScript.

Beendet wurde die Konferenz durch zwei sehr emotionsgeladene Talks. James Whelton stellte das Projekt „Coder Dojo“ vor, in dem Kinder unterrichtet werden. Ein T-Shirt, das von Brendan Eich getragen wurde, wurde zugunsten dieses Projekts für 1.500 € an die Veranstalter versteigert. Chris Williams hielt schließlich das Schluss-Plädoyer, in dem er alle Anwesenden zu einer positiveren Einstellung im Umgang miteinander aufforderte.

Die Konferenz war sehr gelungen - ein Lob an die Veranstalter!

Saturday, October 01, 2011

JSConf.eu - Roundup Tag 1

Ich bin auf der JSConf.eu 2011. Hier meine Eindrücke vom ersten Tag.

Der Veranstaltungsort - die Alte Münze Berlin - ist eine alte Geldfabrik in Berlin Mitte. Hier wurden 1935 bis 2006 Münzen geprägt. Seit der Schließung kann man die alten Münze als Veranstaltungsort mieten. Und die Alte Münze Berlin eignet sich hervorragend für eine Konferenz - etwas heruntergekommen aber mit dem gewissen etwas an Industrieromantik.

Nach dem Eröffnungssong von Bella Morningstar berichtete Dean McNamee von Plask. Laut der Konferenzbeschreibung ist Plask „is a multimedia programming environment. It brings together many of the recent advances in web-related technologies, graphics rendering, and languages, and brings them away from the web.“ Zwar hatte der Talk einige recht anschauliche Beispiele zur Verwendung von Plask, aber so richtig konnte ich die Essenz nicht fassen. Mir ist unklar, was Plask im Wesentlichen von anderen Exerimentier-Umgebungen wie Processing / Processing.js unterscheidet. Plask ist wie Processing auf Speed!

Peter van der Zee plädierte für mehr Tools. Im Bezug auf Entwicklerwerkzeuge befindet sich JavaScript - trotz Firebug, Web-Inspector und Chrome-Debugger - noch im Mittelalter. Als Beispiel für ein gelungenes Entwicklungswerkzeug präsentierte Van der Zee Zeon.js. Zeon.js is ist ein Tool, das im Browser läuft. In einer Text-Area lässt sich mit Zeon.js JavaScript bearbeiten. Zeon.js findet dabei Probleme. Anders als bekannte Tools wie JSLint ist Zeon.js jedoch interaktiv. Es ist eine wirkliche Hilfe und kein Hindernis beim Entwickeln. Zeon.js benutzt einen selbst geschriebenen Parser und statische Analsyse, um Probleme zu finden. Van der Zee führte Tiefer in dieses Thema ein und ermutigte die anwesenden Entwickler, ähnliche Werkzeuge zu schreiben, um die Arbeit mit JavaScript zu vereinfachen.

Aaron Quint ist der Autor von sammy.js. In seinem Talk rantete über Front-End-Frameworks. Frameworks sind keine Religion. Frameworks sollen Probleme lösen. Statt Hypes zu folgen sollten sich Entwickler wieder mehr ihren eigentlichen Aufgaben widmen und weniger fanatisch im Hinblick auf Technologien und Frameworks eingestellt sein.

Marijn Haverbeke, der Autor des Buchs „Eloquent JavaScript“ und des Minifizierers uglify.js, beschäftigte sich in letzter Zeit vermehrt mit Front-End-Performance, dem DOM und hardwarebeschleunigtem Rendering. In seinem Talk präsentierte er seine Erkenntnisse. Diese waren zwar teilweise nicht neu, trotzdem konnte man den Talk aber als gelungen bezeichnen.

Paul Bakaus, der Autor von jQuery-UI, ist inzwischen CTO bei der Social-Game-Schmiede Zynga. Er zeigte, welche Probleme es auch heute noch gibt, wenn man Spiele im Browser entwickeln möchte. Er plädierte dafür, alte Browser (< IE 9) nicht länger zu unterstützen. Zum Lösen des Problems des Scrollens und des Verschiebens des Viewports vor allem auf mobilen Endgeräten präsentierte er „Scroller“ und „Viewporter“. Diese stehen ab heute als OpenSource auf Github zur Verfügung.

Jan Kleinert und Paul Kinlan präsentierten Web-Intents. Web-Intents übertragen das Konzept der Intents auf Android-Smartphones („An intent is an abstract description of an operation to be performed…“) auf den Webbrowser. Statt eine Vielzahl von Diensten für Image Hosting, Social Bookmarking usw. zu integrieren (und den Benutzer damit zu verwirren), spezifiziert eine Anwendung lediglich einen Intent (wie „Sharing“ oder „Image Editing“). Der Webbrowser schlägt dann dem Nutzer Dienste vor, die genau dieses Feature bieten und bei denen er bereits registriert ist. Web-Intents könnten die Art, wie Webanwendungen Dienste dritter Webanwendungen integrieren, grundlegend verändern, sofern sich Web-Intents durchsetzen können.

Tobias Schneider, Nikolai Onken und Stephan Seidt präsentierten die „Arduino Extravaganza“. Dies ist ein Trinkspiel. Im Webbrowser müssen zwei Kontrahenten ein Problem in JavaScript lösen. Eine von einem Arduino-Board gesteuerte Zapfanlage mixt für den Verlierer ein hochalkoholisches Getränk. Die Farbe des Getränks wird vom Gewinner als Hexcode festgelegt - die Anlage kümmert sich vollautomatisch um die richtige Mischung.

Philip Tellis zeigte, wie sich Netzwerke mit JavaScript im Browser messen lassen. Dabei ging er ins Detail. Gegen Ende des Talks konnte er zeigen, wie sich ein Netzwerkscanner im Browser schreiben lässt, der automatisiert Cross-Site-Request-Forgery-Attacken durchführen kann. Dies war einer der interessantesten Talks bisher.

Jakob Mattson hielt ein Plädoyer für eine neue dynamische Sprache, die JavaScript ablösen sollte. JavaScript selbst sei zu statisch und zu wenig formbar, um den Ansprüchen an eine moderne, dynamische Sprache gerecht zu werden. Auch Sprachen wie CoffeeScript, die JavaScript erzeugen, sind laut Mattson kein Ausweg.

Alon Zakai zeige Emscripten. Emscripten ermöglicht es, C/C++-Code im Browser laufen zu lassen. Dazu nutzt Emscripten die LLVM (Low Level Virtual Machine). Ähnlich wie ein Java-Compiler Bytecode erzeugt, erzeugt LLVM-GCC (ein GCC-Compiler, der die LLVM unterstützt) Bitcode. Diesen Bitcode, der sehr viel einfacher als C/C++-Code ist, kann Emscripten zu JavaScript kompilieren. Standardbibliotheken bringt Emscripten gleich mit. So lassen sich C/C++-Bibliotheken direkt im Browser nutzen. Selbst komplexe Anwendungen wie das Computerspiel Quake laufen so im Browser. Dieser Talk war mehr als beeindruckend.

Als Überraschungsgast trat Bendan Eich, der Schöpfer von JavaScript, auf. Er zeigte, welche Features voraussichtlich in ES6 (ECMAScript 6th Edition) enthalten sein werden. Außerdem konnte er RiverTrail präsentieren. RiverTrail implementiert parallelisierbare Arrays in JavaScript. In einem grafischen Demo mit Web-CL zeigte er, dass eine parallelisierte Implementierung des Demos zehn mal so schnell lief wie eine sequentielle Implementierung.
Sein Talk entsprach im Wesentlichen dem Talk, den er auf der Capitol.js gehalten hatte. Er lässt sich auf seiner Website komplett einsehen.

Wednesday, September 21, 2011

WPO - DOM und CSS

In den letzen Monaten wanderte der Fokus in der Web Performance Optimierung von der Zeit, die zum Laden einer Seite benötigt wurde, zunehmend auf die Geschwindigkeit, in der das Rendering einer Seite und die anschließende Manipulation der Seite durchgeführt werden kann.

Der letzte Blog-Beitrag konzentrierte sich auf JavaScript, wohingegen sich dieser Blog-Beitrag mit dem DOM und CSS beschäftigt.

DOM

Die Verschachtelung des DOMs sollte nicht zu tief werden, genauer: Eine Schachtelungstiefe von mehr als 15 sollte unbedingt vermieden werden.

Elemente sollten über CSS gestylt werden. Direkt in Elementen sollten Style-Attribute nur in Ausnahmefällen (z.B. zur individuellen Platzierung) verwendet werden.

Leere DOM-Nodes sollten vermieden werden. Dies gilt auch für Spacer- oder Clear-DIVs.

Auch auf sonstige überflüssige Elemente (z.B. Grafiken für gerundete Ecken) sollte nach Möglichkeit (d.h. wenn dies der Style-Guide erlaubt) verzichtet werden.

Die Komplexität des DOMs lässt sich mit dem Bookmarklet DOM-Monster von Thomas Fuchs auch auf fremden Seiten überprüfen.

Benutze Hardware-Beschleunigung

Moderne Browser (IE9, Mozilla und Webkit) bieten hardwarebeschleunigtes Rendering. Dieses macht sich allerdings erst bei der Berechnung von Animationen (Ein- und Ausblenden von Dialogen, Bewegen von Infoboxen über den Bildschirm) wirklich bemerkbar.

Hardwarebeschleunigung steht allerdings (wenn man von Canvas und WebGL absieht) nur CSS, nicht aber JavaScript zur Verfügung. Darum sollten Animationen stets per CSS mit Transitions erfolgen. JavaScript sollte nur als Fallback eingesetzt werden.

#transition_animated { -moz-transition: all 5s ease-out; -o-transition: all 5s ease-out; -webkit-transition: all 5s ease-out; transition: all 5s ease-out; }

Nutze CSS-Features durchgänging

Effekte wie Schatten oder gerundete Ecken können und sollten mit CSS realisiert werden. Für Browser, die dies nicht unterstützen, wird dann auf eine Darstellung ohne diese Effekte zurückgegriffen. Einige CSS-Features kann man in alten IE-Versionen durch CSS3-Pie nachrüsten. Allerdings wirkt sich CSS3-PIE negativ auf die Laufzeit aus.

CSS-Selektoren

Ein Browser wertet CSS-Selektoren von rechts nach links aus. Eine Auswertung von rechts nach links ist nämlich technisch einfacher und performanter zu implementieren, da mit diesem Ansatz lediglich Listen gefiltert (reduziert) werden müssen. D.h., zunächst werden im Dokument alle Elemente ermittelt, die im rechten Teil des CSS-Selektors stehen, dann wird durch die Liste der gefundenen Elemente iteriert. Auf jedes vorher ermittelte Element wird dann der nächste Selektor ausgewertet. Die Liste wird um diesen Selektor reduziert.

Hierzu ein Negativbeispiel aus einem Stylesheet, das so wirklich existierte:

div#page_navigation #navbar_01 ul.navbar_02 li.act_childs a

• a – Es werden alle Links einer Seite in einer Liste gesammelt. Diese kann sehr lang werden, denn die Seite kann sehr viele Links enthalten.
• li.act_childs – Es werden von allen Elementen in der Liste die Parent-Nodes ermittelt, um zu prüfen, ob diese ein Listen-Element mit der Klasse act_childs enthalten. Die Liste wird anhand dieses Kriterium reduziert.
• ul.navbar_02 – Es werden von allen Elementen in der Liste die Parent-Nodes ermittelt, um zu prüfen, ob diese eine ungeordnete Liste mit der Klasse navbar_02 enhalten. Die Liste wird anhand dieses Kriterium reduziert.
• #navbar_01 – Es werden von allen Elementen in der Liste die Parent-Nodes ermittelt, um zu prüfen, ob ein Element die ID navbar_01 hat. Eine ID muss auf einer HTML-Seite eindeutig sein. Die Liste wird anhand dieses Kriterium reduziert.
• div#page_navigation – Obwohl im vorherigen Selektor bereits eine eindeutige ID angegeben wurde, werden von allen Elementen in der Liste die Parent-Nodes ermittelt, um zu prüfen, ob diese ein DIV mit der ID page_navigation enhalten. Ein ID-Selektor ist bereits eindeutig. Eine zusätzliche Überprüfung, ob dies ein DIV ist, ist überflüssig. Die Liste wird durch dieses Kriterium nicht wirklich reduziert, denn der vorhergehende ID-Selektor war bereits eindeutig.

Daher gelten einige Regeln für effektive CSS-Selektoren:

Verwende effektive Selektoren

IDs sind die effektivsten Selektoren, gefolgt von Klassen-, Tags- und Universal-Selektoren.

#main_navigation /* ID */
.main_navigation /* Class */
ul li a /* Tag */
li a [title='Zurück zur Startseite'] /* Universal */

Man sollte stets den schnellsten geeigneten Selektor möglichst weit rechts verwenden und den HTML-Code entsprechend gestalten. Selektoren auf Tags und Universal-Selektoren sollten komplett vermieden werden.

Ebenso sollten Descendant-Selektoren vermieden werden, die am langsamsten sind (siehe oben!). Oft lassen sich Descendant-Selektoren durch Child-Selektoren beschleunigen. Child-Selektoren sind zwar auch nicht schnell, aber doch schneller als Descendant-Selektoren, da von einem Element nicht potentiell alle Vorfahren, sondern lediglich das Elternelement ermittelt werden muss.

ul.navbar_02 li.act_childs /* bad */
ul.navbar_02 > li.act_childs /* still bad but better */

Überqualifiziere Selektoren nicht

IDs sind bereits eindeutig. Auch Klassen sollten nur für einen Tag definiert sein. Daher sind überqualifizierte Selektoren wie div#main_navigation oder li .act_childs überflüssig. Es genügt, die Elemente über den sehr schnellen ID-Selektor oder den Class-Selektor zu filtern.

Halte die Selektor-Kette kurz

Je länger die Selektor-Kette, desto mehr Operationen muss der Browser durchführen, um ein Element zu finden. Daher sollte die Kette der Selektoren kurz gehalten werden; überflüssige sollten ganz vermieden werden. Wenn sich eine Selektor-Kette nicht vermeiden lässt, dann sollte sie möglichst früh fehlschlagen, damit Elemente nicht überflüssig oft evaluiert werden müssen, bevor sie herausgefiltert werden.

Benutze Kaskadierung

Oft lässt sich eine lange Selektor-Kette durch Kaskadierung vermeiden. CSS kaskadiert Style-Informationen hin zu den Sub-Elementen. Daher lässt sich ein Style oft schon an einem Vater-Element notieren, damit er im Kinder-Element angewendet wird.

Lange Selektoren trifft man oft an: #navbar_01 ul.navbar_02 li a { font: „Arial“}

Dieser lange Selektor könnte durch die Verwendung eines kurzen Selektors minimiert werden.

#navbar_01 { font: „Arial“}

Dieser Blog-Beitrag sollte gezeigt haben, dass nicht nur dynamische Inhalte und Download-Größen sondern auch Struktur und Styling mitverantwortlich für die Performance einer Website sein können.

Dies ist ein Cross-Post vom Holisticon-Blog.

Tuesday, September 13, 2011

WPO - JavaScript und das DOM

Web Performance Optimierung konzentrierte sich in den letzten Jahren vor allem auf die Optimierung der Ladezeit einer Seite. Dazu haben sich Best Practices durchgesetzt, die bereits in einem Artikel in diesem Blog beschrieben wurden.

In jüngster Zeit wandert der Fokus jedoch immer mehr auf die Optimierung einer geladenen Seite, also auf die Zeit, die ein Browser für das Rendering und die Manipulation des DOMs benötigt.

In diesem Blog-Beitrag werden ich mich auf JavaScript konzentrieren.

Document.write

Die Verwendung von document.write ist generell – auch für JavaScripte von Dritten – untersagt. Es sind stattdessen DOM-Operationen (auch innerHtml) zu verwenden. Dies dient nicht nur der der Performance, sondern auch der Robustheit.

Inline-JavaScript

Inline-JavaScript sollte vermieden werden. Wenn dies nicht geht, sollten sie sich am Ende der Seite befinden. Das gilt auch für Event-Listener, die direkt in HTML-Elemente geschrieben werden. Diese sollten eigentlich erst nach dem Laden der Seite gebunden werden. Es sollten zudem so wenige JavaScript-Blöcke wie möglich verwendet werden, da jeder Block zu einer kurzen Verzögerung im Rendering führt.

JavaScript-Blöcke

Jeder JavaScript-Block wird isoliert abgearbeitet. Wenn in einem solchen ein Fehler auftritt, beeinflusst dies andere JavaScript-Blöcke nicht. Daher sollten Scripte, die mit Scripten von Dritten (Tracking, Targeting etc.) interagieren, in einem eigenen Block laufen. Dies widerspricht zwar der Anforderung, möglichst wenige Inline-JavaScripte einzubinden, sorgt aber für Robustheit der Seite. Um Performance-Einbußen zu minimieren, sollten diese Blöcke ausschließlich am Seitenende eingesetzt werden.

Selektoren

Selektoren, die z.B. in jQuery verwendet werden, sollten möglichst performant sein.

Nach Möglichkeit sollten nur Selektoren verwendet werden, die moderne Browser nativ implementieren können. Ob ein Selektor in der nativen Implementierung eines Browser funktioniert, kann man über die Funktion document.querySelectorAll in der Firebug-, Safari-, Internet Explorer- oder Chrome-Konsole testen (z.B. document.querySelectorAll(“.container .p–heading-1″)).

Zum Beispiel implementieren nicht alle Browser die Funktion document.getElementsByClassName. Ein Class-Selektor müsste also von einer Library wie jQuery implementiert werden. Wenn man einen Class-Selektor verwendet, dann muss jQuery alle Elemente der Seite (oder des Bereichs) über einen *-Selektor in eine Liste sammeln und jedes Element prüfen, ob seine Klasse der Klasse des Selektors entspricht. Dies kann auf einer Seite mit sehr vielen Elementen lange dauern. Statt Class-Selektoren sollte man also möglichst ID-Selektoren verwenden. Wenn ein ID-Selektor nicht möglich ist, kann man Events auch per Event Delegation (siehe unten!) an ein Vorfahren-Element binden, dass sich per ID referenzieren lässt.

Minimiere DOM-Manipulationen

JavaScript-Engines werden immer schneller. Dies gilt aber nicht unbedingt für den Zugriff auf das DOM. Manipulationen hieran sind teuer, weswegen sie minimiert werden sollten. Auf DOM-Manipulationen in Schleifen sollte nach Möglichkeit völlig verzichtet werden.

Cache DOM-Nodes und Attribute

Das Ermitteln von DOM-Elementen und -Attributen kostet Zeit. Daher sollten Elemente und Attribute einmalig ermittelt und dann in Variablen gecacht werden. Wenn sich das DOM verändert, so verändert sich auch automatisch das DOM-Element, das bereits ermittelt wurde – es besteht keine Notwendigkeit, erneut das Element im DOM zu suchen und auszuwerten. Module, die Objekte kapseln, können auch zur Zwischenspeicherung der DOM-Elemente genutzt werden.

Minimiere Redraws und Reflows

Jede Änderung im DOM führt zu einer Neuberechnung und einem Rendering der Seite. Dieser Redraw findet immer nach Events bzw. nach dem Beenden von JavaScript-Callbacks, die durch diese Events ausgelöst wurden, statt.

Änderungen sollten kumulativ erfolgen. Statt aus dem DOM zu lesen, in das DOM zu schreiben, erneut aus dem DOM zu lesen und wieder in das DOM zu schreiben, sollten Lese- und Schreiboperationen gebündelt erfolgen, so dass diese Operationen in einem einzigen Redraw bzw. Reflow erfolgen.

Das Document-Ready-Event

Im Document-Ready-Event sollte so wenig wie möglich getan werden. Lediglich Event-Listener dürfen an Elemente gebunden werden. Diese Elemente sollten nach Möglichkeit per ID referenziert werden. Wenn dies nicht möglich ist, bietet sich Event Delegation (siehe unten!) an.

Gänzlich verzichtet werden sollte auf DOM-Manipulationen, die schon beim Laden der Seite stattfinden (wie das Erzeugen von DIVs auf Reserve oder das Setzen von Attributen aufgrund von CSS-Klassen). Das DOM sollte bereits auf dem Server statt erst im Browser manipuliert werden.

Lazy Initialisation

Berechnungen und Bindings beim Document-Ready-Event sollten minimiert werden (siehe oben!), sondern erst durchgeführt werden, wenn sie benötigt werden (z.B. nach einen Klick-Event). Natürlich ist im Einzelfall abzuwägen, ob Lazy Initialisation einen Vorteil bietet. Eine Lazy Initialisation bei einem MouseOver-Event könnte als störend (verzögert) empfunden werden, während sie nach einem Klick-Event vom User nicht bemerkt wird.

Event Delegation

Es kann nach dem Laden der Seite lange dauern, bis alle Event Handler an DOM-Elemente gebunden sind. Um diese Zeit zu minimieren, bietet sich Event Delegation an, die der der Lazy Initalisation ähnelt. Man registriert ein Event (z.B. ein Klick-Event) an einem umschließenden Bereich, der sich z.B. über eine ID referenzieren lässt. Die Auflösung auf das einzelne geklickte Element findet dann erst nach dem Klick-Event statt. Die Zeit, die beim Laden der Seite eingespart wird, tritt dann also bei jedem einzelnen Event auf. Daher ist im Einzelfall abzuwägen, ob Event Delegation einen Vorteil bietet. Eine Event Delegation bei einem MouseOver-Event könnte als störend empfunden werden, während eine Event Delegation nach einem Klick-Event vom User nicht bemerkt wird.

Dies ist ein Cross-Post vom Holisticon-Blog und von Ajaxer.

Saturday, April 16, 2011

JSON-P mit Spring und CXF

Viele Webapplikationen laden Daten per JavaScript im JSON-Format von einem Server in den Browser, um sie dort darzustellen oder zu verarbeiten. Ein solcher Beispieldatensatz im JSON-Format könnte wie folgt aussehen:


{
  “cities”: [”Hamburg”, “New-York”, “Tokio”]
}

Ein Webbrowser lässt allerdings nicht zu, dass ein Script Daten von einer anderen Domain lädt als der, von der die Seite, in die das Script eingebettet wurde, geladen wurde. JavaScript hat also keinen Zugriff auf Daten, die von einer anderen Domain kommen. Diese Einschränkung ist ein Security-Feature des Browsers und als Same Origin Policy bekannt.

Oft ist es aber nötig, Daten von einer fremden Domain oder einer eigenen Subdomain zu ermitteln. Die saubere technische Lösung für dieses Problem ist Cross Origin Resource Sharing. Beim Cross Origin Resource Sharing werden Berechtigungen über HTTP-Header gesteuert. Leider funktioniert Cross Origin Resource Sharing nicht mit Legacy-Browsern, die noch häufig anzutreffen sind.

Ein Workaround, der in jedem Browser funktioniert, ist JSON-P: JSON with Padding. Ein Script darf selbst zwar keine Daten von einer fremden Domain anfordern, aber es darf einen Script-Tag generieren, der ein weiteres JavaScript von dieser fremden Domain lädt und direkt ausführt. Diesem nachgeladenen JavaScript übergibt man als GET-Parameter den Namen einer Callback-Funktion, die von dem nachgeladenen JavaScript ausgeführt werden sollte. Per Konvention trägt dieser GET-Parameter den Namen „_jsonp“.



script src="”http://my.otherdomain.de/rest-ws/myservice/mydata?_jsonp=jsonpCallback“" type="”text/javascript”"



Das so eingebundene Script muss dynamisch auf dem Server in einer Weise erzeugt werden, dass es die übergebene Callback-Funktion aufruft, sobald es vom Browser geladen wurde. Der Callback-Funktion werden in der Regel die Daten übergeben, die man ansonsten direkt als JSON-Objekt angefragt hätte:


jsonpCallback (
 
  {
 
    “cities”: [”Hamburg”, “New-York”, “Tokio”]
 
  }
 
);

Die Callback-Funktion wird von dem Script, das eigentlich die Daten anfordern wollte, bereitgestellt. So werden Daten von einer fremden Domain per JSON-P geladen. Front-End-Libraries wie jQuery stellen eine automatisch generierte Callback-Funktion bereit. Daher muss sich der Entwickler nicht um das Schreiben dieser Callback-Funktion kümmern.


return $.ajax({
 
type: “GET”,
 
url: “http://my.otherdomain.de/rest-ws/myservice/” + data,
 
error: errorcallback,
 
success: callback,
 
dataType: “jsonp”,
 
jsonp: “_jsonp”,
 
jsonpCallback: “ jsonpCallback “
 
});

Auf Client-Seite stellt JSON-P also kein Problem dar und wird von gängigen JavaScript-Bibliotheken unterstützt.

Auf dem Java Enterprise-Server wird für RESTful Services oft eine JAX-RS-Implementierung benutzt. Eine gängige JAX-RS-Implementierung ist Apache CXF. Allerdings stellt CXF im Moment noch kein JSON-P zur Verfügung (JIRA 3005). Daher muss man sich einen eigenen JSON-P-Provider schreiben. Dies ist glücklicherweise sehr einfach, denn man kann alle Funktionalitäten vom Default-JSONProvider erben:


@Produces("application/json")
 
public class JSONPProvider extends JSONProvider {
 
  @Override
 
  public void writeTo(
 
    Object obj, Class cls,
 
    Type genericType, Annotation[] anns,
 
    MediaType m, MultivaluedMap headers,
 
    OutputStream os
 
  ) throws IOException {
 
    final String prefix = request.getParameter("_jsonp"); // fix for demo
 
    final boolean hasPrefix = !StringUtils.isEmpty(prefix);
 
    if(hasPrefix) {
 
      // … check for injection first
 
      os.write(prefix); // simplified
 
      os.write('(');
 
      super.writeTo(obj, cls, genericType, anns, m, headers, os);
 
      os.write(')');
 
    } else {
 
      super.writeTo(obj, cls, genericType, anns, m, headers, os);
 
    }
 
  }
 
}

Dieser eigene JSON-P-Provider macht nichts, außer die vom JSON-Provider erzeugten JSON-Daten mit dem Aufruf einer Callback-Funktion zu umschließen, falls ein Request-Paramter „_jsonp“ übergeben wurde. Das abgedrucke Listing ist simplifiziert. Selbstverständlich muss man den Eingabeparameter „prefix“ prüfen, um eine Code-Injection auszuschließen.

Dieser selbst geschriebene JSON-P-Provider kann im Spring-Framework nun als JSON-P-Provider-Bean definiert werden. Letztere kann in einem JAX-RS-Server genutzt werden.



 
  
 
  
 
  
 
    
 
      
 
    
 
    
 
     
 
   
 
  
 


So lassen sich RESTful Services, die bisher nur JSON sprechen konnten, durch Konfiguration des JSON-P-Providers so erweitern, dass sie auch optional JSON-P sprechen können.

Dies ist ein Cross-Post vom Holisticon-Blog und von Ajaxer.

Thursday, March 03, 2011

Türstehen für Bohnen – Bean Validation mit domänenspezifischen Typen in der Praxis

Simon Zambrovski und Oliver Ochs, JavaMagazin Ausgabe 4.2011


Nachdem vor Kurzem Simon Zambrovski und Oliver Ochs bereits einen IT-Talk zum Thema Bean Validation gehalten haben, ist nun auch ein JavaMagazin-Artikel zum gleichen Thema erschienen.

In einer Java-Enterprise-Anwendung werden Daten erfasst und verarbeitet. Diese Daten müssen validiert werden. Die Validierungslogik ist meist eng an die Daten, die validiert werden, gekoppelt. Darum werden durch JSR-303 Bean Validation die Validierungsregeln direkt an die Daten annotiert. Der JSR-303 ist ein Teil der Java EE 6. Das heißt, man kann Bean Validation in Java EE 6 sowohl mit JSF als auch mit JPA einsetzen. Doch auch außerhalb der Java EE 6-Welt lässt sich Bean Validation z.B. mit Spring 3 verwenden.

Der Artikel bietet einem praxisnahen Überblick über den Einsatz von JSR-303 mit all diesen Frameworks. Zudem wird die Verwendung von domänenspezifischen Typen tiefer gehend erläutert.

Man findet den Artikel in der Rubrik "Enterprise".

Mehr Informationen findet man im Holisticon-Blog.

Friday, December 31, 2010

UKW-Sender in Hamburg

Hier eine Senderliste der in Hamburg empfangbaren UKW-Radiosender.

Die angegebenen Sendetürme sind die, die mir am wahrscheinlichsten vorkommen. Die Sender, die von Bergedorf aus abgestrahlt werden, kann ich leider selbst nicht empfangen.

No.SenderSendeturmFrequenz
1NDR 2Moorfleet87,6
2DeutschlandfunkMitte88,7
3DeutschlandRadio KulturMitte89,1
4NDR 1 Welle NordMoorfleet89,5
5NDR 90,3Moorfleet90,3
6917 xfmMitte91,7
7NDR InfoMoorfleet92,3
8FSK - Freies SenderkombinatMitte93,0
9Delta RadioMitte93,4
10NJOY RadioMitte94,2
11Oldie 95Mitte95,0
12Offener Kanal HamburgMitte96,0
13Energy 97,1Mitte97,1
14Klassik RadioMitte98,1
15NDR KulturMoorfleet99,2
16R.SHMitte100,0
17Radio ffnRosengarten100,6
18Radio NoraKaltenkirchen101,1
19R.SHKaltenkirchen102,9
20NDR 1 NiedersachsenRosengarten103,2
21Radio HamburgMoorfleet103,6
22Radio HamburgMitte104,0
23Hit-Radio AntenneRosengarten105,1
24NDR 1 Welle NordNeumünster106,4
25106!8 Alster Radio rock'n'popHöltigbaum106,8
26Delta RadioKaltenkirchen107,4




27Oldie 95Bergedorf88,1
28Energy 97,1 Bergedorf100,9
29R.SH Bergedorf102,0
30Delta Radio Bergedorf107,7

Monday, December 13, 2010

Nachteile funktionaler Vererbung in JavaScript

In meinem letzten Blog-Post hatte ich die funktionale Vererbung in JavaScript vorgestellt. Diese funktionale Vererbung hat allerdings einige Nachteile.

Jedes Mal, wenn ein neues Sub-Objekt erzeugt wird, werden zwei neue Funktionen erzeugt: einmal für das Sub-Objekt und einmal für das Super-Objekt. Diese Objekte sind nicht leichtgewichtig, denn das innere Super-Objekt wird als Closure im äußeren Sub-Objekt referenziert. Das Verwenden von vielen Closures kann zu Memory-Leaks führen.

Typen können nicht durch den Instanceof-Operator getestet werden. Sowohl das Super-Objekt "Square" als auch das Sub-Objekt "Box" sind einfache Funktionen. Eine Box-Objekt ist keine Instanz des Square-Objekts. Dies liegt daran, dass keine Konstruktorfunktion verwendet wird.

print(myBox instanceof square); // false


Typen lassen sich zudem nicht erweitern. Das Super-Objekt wird in einer Closure gehalten. Es ist von außen nicht sichtbar.

Der Syntax zum Erzeugen einer neuen Objekt-Instanz entspricht nicht den Konventionen von JavaScript.

var myBox = box(5);


Neue Objekt-Instanzen werden in JavaScript mit dem new-Operator auf einer Konstruktorfunktion erzeugt. Da das Entwurfsmuster der funktionalen Vererbung keine Konstrutkorfunktionen kennt, kann der new-Operator nicht verwendet werden. Dies kann zu Fehlern in der Verwendung des Codes führen.

new Box(5); // ReferenceError: Box is not defined

Funktionale Vererbung sollte also nur in Ausnahmefällen angewendet werden, in denen ein funktionales Paradigma am sinnvollsten erscheint.

Dies ist ein Cross-Post von Ajaxer.de.

Thursday, November 18, 2010

Friday, November 12, 2010

Funktionale Vererbung in JavaScript

Funktionale Vererbung ist ein Begriff, der durch Douglas Crockford geprägt wurde.

Funktionen sind Objekte. Wie Objekte können Funktionen auch selbst Eigenschaften (Properties) und Methoden (Funktionen) haben.

Funktionale Verberbung implementiert man, indem man eine Funktion erstellt, die Objekte erzeugt und diese zurückgibt. Innerhalb dieser Objekt-erzeugenden Funktion gibt es private Instanzvariablen. Auf diese kann das zurückgegebene Objekt als Closure zugreifen. Für die Nutzer des zurückgegebenen Objekts sind diese jedoch unsichtbar. Das zurückzugebende Objekt wird um Methoden erweitern. Diese Methoden haben ebenfalls Zugriff auf die privaten Variablen.



function square(width) {
  var squareObject = {};
  squareObject.getArea = function() {
    if (width > 0) {
      return width * width;
    }
   }
   return squareObject;
}

var mySquare = square(5);
print(mySquare.getArea()); // 25
print(mySquare.width); // undefined


Vererbung lässt sich in der funktionalen Vererbung durch das Dekorierer-Entwurfsmuster implementieren. Um einen Subtypen zu implementieren erweitert man den Supertypen um die benötigten Eigenschaften oder Methoden. Zu überschreibende Methoden speichert man in privaten Variablen, um diese auch dann noch verwenden zu können, wenn man die Methoden des Super-Objekts bereits überschrieben hat.



function box(width) {
  var boxObject = square(width);
  var getSquareArea = boxObject.getArea;
  boxObject.getVolume = function() {
    if (width > 0) {
      return getSquareArea() * width; 
    }
  }
  boxObject.getArea = function() {
    if (width > 0) {
      return getSquareArea() * 6;  
    }
  }
  return boxObject;
}

var myBox = box(5);
print(myBox.getVolume());  // 125
print(myBox.getArea()); // 150


Dieser Ansatz ist wohl der einfachste Ansatz zur Objekt-orientierten Programmierung in JavaScript, da er ohne Prototypen und Konstruktor-Funktionen auskommt.

Dies ist ein Cross-Post von Ajaxer.de.

Friday, September 10, 2010

Google V8 installieren

In den letzten Jahren hat sich der Webbrowser zu der wichtigsten Anwendung auf dem Desktop-Rechner und im Smartphone entwickelt. Er ist in die Domäne von ausgewachsenen Applikation wie Mail-Clients und Office-Suiten vorgestoßen und hat scheinbar allgegenwärtige Programme wie Microsoft Outlook und Word teilweise bereits verdrängt. Anwendungslogik wandert zunehmend vom Server zum Client, vom Backend in den Webbrowser.
Wenn immer mehr Anwendungslogik vom Server in den Client verlagert wird, stellt sich für einen Entwickler die Frage, ob der Rest der Anwendungslogik im Backend nicht in der gleichen Sprache entwickelt werden kann, die auch im Webbrowser verwendet wird. Es gibt keinen logischen Grund, warum JavaScript ausschließlich im Webbrowser laufen sollte. Es erscheint zudem wirtschaftlich, wenn man auf eine große Zahl an Entwicklern zurückgreifen kann, die in einer einzigen Sprache entwickeln. JavaScript auf dem Server könnte sicherlich nicht gewachsene SAP- oder SOA-Umgebungen, dafür aber Webframeworks wie ASP.net, Spring MVC / Webflow oder JSF ersetzen.
Inzwischen wird JavaScript also auf dem Server interessant. Sogar Datenbanken wie Couch-DB verwenden JavaScript als native Abfragesprache. Mit ECMAScript 5 gibt es zudem in der Sprache selbst interessante neue Features.
V8 ist die JavaScript-Laufzeitumgebung, die von Google für Googles Chome-Browser entwickelt wurde. V8 implementiert in der aktuellen Version 2.2 ECMA Script 3.
Google entwickelte mit V8 eine Laufzeitumgebung, die auf Mac OS X, Linux und Windows läuft. V8 ist komplett in C++ geschrieben und lässt sich eingebettet in C++-Applikationen verwenden. Außerdem lässt es sich natürlich auch allein stehend ausführen.
V8 gilt als sehr schnell. Verantwortlich für die Entwicklung war Lars Bak. Vor noch etwa zehn Jahren hatte Java den Ruf, langsam und hakelig zu sein. Ein kleines Start-Up um Lars Bak entwickelte jedoch eine neue Java Virtual Machine, die den Code zur Laufzeit kompilierte. Der Java JIT war geboren. Die von Lars Bak entwickelte Virtuelle Maschine ist der Ursprung von Hotspot, der aktuellen Java Virtual Machine von Sun Microsystems (jetzt Oracle). Erst durch Hotspot konnte Java die Popularität erreichen, die es heute hat. Genauso wie HotSpot Java beschleunigt hatte, beschleunigt V8 auch JavaScript.
V8 kompiliert JavaScript zu nativem Microcode anstatt es zu interpretieren. Weitere Beschleunigung erreicht V8, indem es die Rückgabewerte von Methoden cacht. Dieses Optimierungs-Technik wird inline caching genannt. Der Garbage Collector ist zwar ein Stop-the-World-Garbage Collector, allerdings ist er sehr schnell. Mit V8 läuft JavaScript fast so schnell wie ein kompiliertes, natives Programm.
Als V8 veröffentlicht wurde, war es etwa doppelt so schnell wie die Laufzeitumgebungen anderer Hersteller. Dies erst führte dazu, dass ein richtiges Wettrennen zwischen Browsern und deren JavaScript-Laufzeitumgebungen stattgefunden hat. Ohne V8 wären TraceMonkey, JägerMonkey oder SquirrelFish wahrscheinlich nicht so schnell entwickelt worden.
Google betrachtete JavaScript als einen der Treiber des Webs. Google ließ sich sogar dazu verleiten, ein reines Web-Betriebssystem Google Chrome OS anzukündigen, das sich ausschließlich durch Web-Technologien, also HTML und JavaScript, programmieren lässt.
V8 könnte eine - wenn nicht die - Grundlage für JavaScript auf dem Server oder in nativen Anwendungen bilden.
Um V8 zu installieren, benötigt man Subversion und SCons. Subversion ist ein Source-Code-Management-System, SCons ein Build-System. Unter MacOS verwendet man am besten Ports.
$ sudo port install scons subversion
Unter Ubuntu Linux verwendet man dazu den Package-Manger apt.
$ sudo apt-get install zip scons subversion
Unter der 64bit-Version von Ubuntu Linux könnte es notwendig sein, dass man zusätzlich noch die Multi-Lib-Packages installiert.
$ sudo apt-get install g++-multilib gcc-multilib
Anschließend kann man V8 aus dem Subversion-Repository auschecken und bauen.
$ svn checkout http://v8.googlecode.com/svn/trunk/ v8
$ cd v8
$ scons sample=shell
Nun kann man V8 über das Kommando „shell“ starten.
$ ./shell
V8 version 2.2.21
> print("Hello World");
Hello World
> quit();


Thursday, July 01, 2010

Javamagazin - Maskenball - Google Wave (Teil 3)

Maskenball - Clientseitige Erweiterung von Google Wave
Oliver Ochs und Jochen Jörg, JavaMagazin Ausgabe 8.2010

Im ersten Teil der Artikelserie haben wir die grundlegenden Konzepte von Google Wave vorgestellt und Wave ausführlich aus der Produktperspektive betrachtet. Im zweiten Artikel wurden die Funktionsweise sowie das Wave Protokoll näher beleuchtet. Ferner haben wir anhand eines Beispiels gezeigt, wie Wave mit Hilfe der Robot API erweitert werden kann. In diesem dritten Teil werden wir beschreiben, wie sich Wave unter Verwendung der Embed API in eine Website einbinden lässt und wie sich Gadgets - Miniprogramme, die im Client laufen - mit Hilfe der Gadgets API programmieren lassen.

Dies ist ein Cross-Post des Holisticon-Blogs.

Tuesday, June 01, 2010

Javamagazin - Föderierte Agenten - Google Wave (Teil 2)

Föderierte Agenten - Serverseitige Erweiterungen von Google Wave
Oliver Ochs und Jochen Jörg, JavaMagazin Ausgabe 7.2010

Im ersten Teil der Artikelserie haben wir die grundlegende Konzepte von Google Wave vorgestellt und Wave ausführlich aus der Produktperspektive betrachtet. Außerdem haben wir einen eigenen Wave Federation Server aufgesetzt. In diesem zweiten Artikel werden wir die Funktionsweise und das Wave Protokoll näher beleuchten. Ferner wird anhand eines Beispiels gezeigt, wie Wave mit Hilfe der Robot API erweitert werden kann.

Dies ist ein Cross-Post des Holisticon-Blogs.

Thursday, May 13, 2010

Rezept für Spuntenkäse (Spundekäse)

  • 500 g Quark
  • 250 g Butter
  • 2 Pck. Frischkäse, natur
  • 1 Pck. Schmelzkäse (rechteckig)
  • 1-2 Zwiebeln
  • 3 El. Paprikapulver, edelsüß
  • Pfeffer und Salz
  • zusätzlich Paprikapulver, edelsüß zum garnieren
Zutaten mit dem Handrührgerät verrühren, mit Paprikapulver garnieren.

Saturday, May 01, 2010

Javamagazin - Der Schockwellenreiter - Google Wave (Teil 1)

Der Schockwellenreiter - Google Wave
Oliver Ochs und Jochen Jörg, JavaMagazin Ausgabe 6.2010

Google Wave ist ein Werkzeug, mit dem die Kommunikation und Zusammenarbeit über das Internet revolutioniert werden sollte. Dieser radikale Ansatz könnte Wave auch scheitern lassen. In dieser dreiteiligen Artikelserie werden wir zeigen, was Google Wave ist, wie es funktioniert und welche Konzepte sich dahinter verbergen.

Dies ist ein Cross-Post des Holisticon-Blogs.