Dirk Ginader | Yahoo! Inc.
Javascript done right
@ginader
Kriterien für “gutes” Javascript
• Aus Benutzersicht:– macht die Page-Handhabung leichter– sofort/immer benutzbar (blockt nicht)
– ist Barrierefrei– bereichert die Webseite
– “stört nicht”
– ist nicht zum Selbstzweck– beschleunigt Abläufe
– in meiner Sprache
Kriterien für “gutes” Javascript
• Aus Entwicklersicht:– verständlich, wartbar,
wiederverwendbar, erweiterbar, dokumentiert, optimiert, sicher, performant, sauber getrennt, optional, international, barrierefrei
verständlich
• vermeide “zu clevere” Konstrukte
verständlich
• nicht jeder versteht:– Ternary:
• var d = (x < m) ? 'l' : 'r';
verständlich
• nicht jeder versteht:– Regex:
• ^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$
verständlich
• nicht jeder versteht:– Shakespeare:
• /(bb|[^b]{2})/
verständlich
• wenn doch notwendig/sinnvoll dann gute Variablen Namen + Doku!
mehr WTF auf
• http://wtfjs.com
Gut Wartbar
• Wie schreibst Du Javascript?– jQuery, YUI und Konsorten?– alles von Hand?
Gut Wartbar
• Du verwendest und verstehst nur ein Javascript Framework?– Du solltest Javascript lernen!– Verstehe was hinter den Kulissen
passiert!
– Lerne Fehlermeldungen zu verstehen!– Viele Fehler werden offensichtlich
Gut Wartbar
• Du verwendest aus Prinzip keine Javascript Frameworks?– Du solltest!
Gut Wartbar
• Javascript Frameworks/Libraries helfen– nicht immer das Rad neu zu erfinden– Code aktuell zu halten
– Qualität zu sichern– Modulare Applikationen zu entwerfen
anstatt Scripts zu schreiben
Gut Wartbar
•“Standing on the Shoulders of Giants”
•“Zwerge auf den Schultern von Riesen”
•“nanos gigantium humeris insidentes”
Wiederverwendbar
• finde patterns
• “grösste” gemeinsame Nenner• wenn Du jeden Monat ein neues
Dropdown Menü schreibst ist etwas sehr falsch
• schreibe EIN Dropdown Menü und entwickele es weiter
• mit einheitlichen Schnittstellen
Wiederverwendbar
• Open Source != “ich gebe meine kostbaren Ideen umsonst weg”
• Open Source == “ich kriege kostenlose Tester, Entwickler,Ruhm und Ehre!”
• github ist voll mit großartigem Code
• “FORK OFF” - mach es besser!
• Ein Plugin für eine Library ist ein super start!
Erweiterbar
•Was ist das populärste an jQuery?- DIE PLUGINS!
$.fn.extend({ accessibleTabs: function(config) { return this.each(function() { //... } }});
$(".tabs").accessibleTabs();
Erweiterbar
•Jedes Modul kann plugins haben!
•Formular ValidierungaddValidator : function(name,func){ this.validators[name] = func;}
this.addValidator('isText',function(el){ var filter = /^[a-zA-Z\ ]+$/; return filter.test(el.get('value'));});
if( !this.validators['isText'](el) ){ //error!}
Erweiterbar
•Bestehendes Erweitern anstatt alles noch mal neu schreiben!
•Für noch unbekannte Ansprüche gewappnet sein
Dokumentiert
• Dokumentation schreiben macht nicht Spass
• Code lesen den man vor 5 Jahren geschrieben und nicht dokumentiert hat noch weniger...
• Undokumentierten Code lesen den andere geschrieben haben am allerwenigsten...
Dokumentiert
• Klare Variablen und Funktionsnamen nutzen:– a = b(c) // Hä?– user = getUserOfProduct(productId) // Ah!
• Gute Kommentare– // IE seems to break here...– // dirty hack. This must never go live!– // this works. No idea why. Better don’t touch.
Dokumentiert
• Besonders gute Kommentare!– YUI Doc: http://developer.yahoo.com/
yui/yuidoc/– erzeugt die YUI API Doku automatisch
– Einfache Javadoc syntax/*** Kurzer Beschreibungstext* @method methodName* @param {bool}* @returm {type}*/
Dokumentiert
• YUI Doc jetzt noch schönerdank Carlo & Dana:http://www.yuiblog.com/blog/2010/10/01/yuidoc-dana-theme/
Optimiert
• Guter Development Code != guter Production Code
• Gut für Development:– Code granular auf viele Dateien Verteilt
•Modul / config / i18n / init / etc
– Viele Kommentare
– Beispiele
Optimiert
• Guter Development Code != guter Production Code
• Gut für Production:– Code kombiniert in wenige bis eine
Datei
– Kommentare & Whitespace weg– optionale Code-Minification
Optimiert
• YUI Compressorhttp://developer.yahoo.com/yui/compressor/
• Google Closure Compilerhttp://code.google.com/closure/compiler/
Sicher
• XSS ist das grösste Sicherheitsproblem
• Keine User Eingaben direkt wieder ausgeben
• Eingaben filtern!whitelisting nicht blacklisting
• Datentypen definieren
• traue nichts und niemanden• Sei Paranoid...
Sicher
• Cajahttp://en.wikipedia.org/wiki/Caja_project
• “virtuelle iFrames”• keine direkten Zugriffe auf native
Objekte
• Übersetzer auf dem Server
• YUI3 erste Javascript Library die kompatibel ist
Performant
• Caching von DOM-Zugriffenvar el = document.getElementById('bla');
• CSS ist viel schneller als Javascript wenn es darum geht den DOM zu ändernel.addClass('bla');
stattel.css({ width:'20px', height:'20px', ...
});
Performant
• “reflows” vermeidenBei jeder DOM-Manipulation muss der Browser neu rendern!
• Bei Style Änderung von grossen Mengen von Elementen ist CSS Modifikation sogar noch schneller!
$('<style type="text/css"> a { color: red; } </style>').appendTo('head');
Performant
• DOM ändern mit:– klassischen DOM Methoden:
el = document.getElementById('list');l1 = document.createElement('li');t1 = document.createTextNode('hallo 1');l2 = document.createElement('li');t2 = document.createTextNode('hallo 2');l3 = document.createElement('li');t3 = document.createTextNode('hallo 3');l1.appendChild(t1);l2.appendChild(t2);l3.appendChild(t3);el.appendChild(t1).appendChild(t2).appendChild(t3);
Performant
• DOM ändern mit:– innerHTML:el = document.getElementById('list');li = '<li>hallo 1</li>';li += '<li>hallo 2</li>';li += '<li>hallo 3</li>';el.innerHTML = li;
– Schneller als DOM-Methoden (wegen IE)
Performant
• DOM ändern mit:– innerHTML:el = document.getElementById('list');li = [];li.push('<li>hallo 1</li>');li.push('<li>hallo 2</li>');li.push('<li>hallo 3</li>');el.appendChild(li.join());
– noch schneller weil string concatenation in IE langsam ist
Performant
• DOM ändern mit:– innerHTML:el = document.getElementById('list');li = [];li[0] = '<li>hallo 1</li>';li[1] = '<li>hallo 2</li>';li[2] = '<li>hallo 3</li>';el.appendChild(li.join());
– noch schneller weil auch array.push in IE langsam ist
Performant
• DOM ändern mit:– DOM Fragment:l = document.getElementById('list');f = document.createDocumentFragment();l1 = document.createElement('li');t1 = document.createTextNode('hallo 1');...l1.appendChild(t1);l2.appendChild(t2);l3.appendChild(t3);f.appendChild(l1).appendChild(l2).appendChild(l3);el.appendChild(f);
– Noch schneller! Nur ein DOM-Zugriff!
Sauber getrennt
• HTML– Markup
• CSS– Design
• Javascript– Interaktion
Sauber getrennt
• CSS für Javascript– <script> document.documentElement.className += ' js';</script>
– <style>.module{ /* ohne JS */}.js .module{ /* mit JS */}</style>
Sauber getrennt
• HTML für Javascript– Partials mit Mustache Templating
für Ajax content– /partials/login_success.html– Hallo {{user_name}}Sie haben sich erfolgreich angemeldet.Ihr Punkte Stand ist {{user_points}}
– { user_name : “Spundekäs”, user_points : 123}
– http://mustache.github.com/
Optional
• Progressive Enhancement– Basis Funktionalität der Webseite/
Webbapp muss gewährleistet sein auch wenn der Useragent kein Javascript spricht!•Mobile != iPhone (Opera Mini ist No.1!)•Suchmaschinen•Paranoide Sysadmins•Yahoo hat ~1% non-js User•...
Optional
• Basis Seite hat Interaktion dank:– Links– Formulare
– Alles wichtige ist sichtbar
• Mit Javascript:– Links die die Seite ändern werden zu
Buttons
– Formulare werden direkt verarbeitet– Info kann versteckt/gezeigt werden
International/Multilingual
• UTF-8
• RTL• Wenn möglich Strings aus der
HTML-Seite übernehmen
• Übersetzungsstandards nutzen– Text {0} mehr text {1} noch mehr text {2}Text {0:currency} mehr text {1:symbol} noch mehr text {2:amount} // {variable:comment}
International/Multilingual
• Variabler Satzbau = mehrstufige Übersetzung– T_WELCOME : { en_US:”We welcome {0:user}” de_DE:”Wir heissen {0:user} willkommen”}
– getText(‘de_DE’,‘T_WELCOME’,{user:Schoppekopp})
• ISO Standards beachten
• HTML in Strings ist nicht ideal aber besser als pseudo code
• bold macht Asia Schriften unlesbar
International/Multilingual
TRANSLATIONS = { // siehe http://internationalisationtips.com! O: "{market} open",! OT: "{market} open in {timePeriod}",! OE: "{market} open early",! OET: "{market} open early in {timePeriod}",! OER: "{market} open early for {reason}",! OERT: "{market} open early for {reason} in {timePeriod}",! OL: "{market} open late",! OLT: "{market} open late in {timePeriod}",! OLR: "{market} open late for {reason}",! OLRT: "{market} open late for {reason} in {timePeriod}",! C: "{market} close",! CT: "{market} close in {timePeriod}",! CE: "{market} close early",! CET: "{market} close early in {timePeriod}",! CER: "{market} close early for {reason}",! CERT: "{market} close early for {reason} in {timePeriod}",! CL: "{market} close late",! CLT: "{market} close late in {timePeriod}",! CLR: "{market} close late for {reason}",! CLRT: "{market} close late for {reason} in {timePeriod}",! X: "{market} closed"};
Barrierefrei
• Tab Reihenfolge ist entscheidend
• mit focus() kann der Nutzer geführt werden
• tabindex=-1 macht alles fokussierbar (für Javascript)
• Ajax funktioniert aber die Ladezeit muss erklärt werden
• Virtual Buffer aktualisieren
Barrierefrei
• manche Effekte können die Javascript Version verständlicher/Barrierefreier machen als ohne– highlight() // yellow fade zur
temporären Hervorhebung eines geänderten Bereiches
– auf-/zuklappen // mit guter Animation leichter verständlich als hart auf/zu
Barrierefrei
• WAI-ARIA– bringt bekannte Desktop-
Bedienkonzepte barrierefrei in den Browser
– Bringt unsemantischem Markup Semantik bei
Barrierefrei
• WAI-ARIA– echte realtime updates
•Live Regions
– echter Formular Validierungsstatus•aria-required="true"•aria-invalid="true"
– echte Dialoge•role="alert"
Danke :-)
• http://ginader.de
• http://twitter.com/ginader• http://github.com/ginader/
• http://www.slideshare.net/ginader
• http://speakerrate.com/speakers/225-ginader
Top Related