Seite wählen

NETWAYS Blog

JavaScript Memory Leaks mit Chrome lokalisieren

JavaScript ist ja bekanntlich eine Sprache, die ihre Speicherverwaltung an einen Garbage Collector übergibt und dem Programmierer hier ein weitgehend unbeschwertes Leben verschafft. Meistens.
Wer bereits in anderen GC-basierten Laufzeitumgebungen wie Java programmiert hat, der weiß sicher dass auch ein Garbage Collector Memory Leaks in manchen Fällen nicht verhindern kann wenn der Programmierer unachtsam ist. Sobald ein Objekt nämlich noch in einem aktiven Bereich referenziert wird, bleibt er bis zum entfernen dieser Referenz im Heap (immerhin besteht die Möglichkeit, dass man das Objekt noch verwendet). Das Gute: Die meisten Memory Leaks sind so unbedeutend, dass man sie getrost ignorieren kann. Kritisch wird es erst, wenn man viele größere Objekte (z.B. DOM Knoten) über einen langen Zeitraum erstellt und entfernt, auf die aber noch in irgendwelchen Codeecken verwiesen wird (z.B. in einem Array). Dann gibt es auch in JavaScript irgendwann eine OutOfMemoryException – und ohne die richtigen Tools ist deren Ursache schwer aufzufinden (immerhin kann der Bereich z.b. in einem Closure liegen).
mehr lesen…

Effiziente Codeorganisation in JavaScript: require.js

Dilemma:

Codeorganisation in JavaScript geht mir schon seit je her etwas auf die Nüsse. Wegen der Natur von JavaScript muss man entweder alle Skripte von Anfang an laden (= viel JavaScript parsen bei Seitenaufbau) oder man verwendet XHR/JSONP (JSONP ist in diesem Falle einfach ein dynamisches Einfügen von script Tags), was wiederum aufwendig ist, da asynchron. Eine include/import Direktive wie in anderen Sprachen existiert nicht.

Lösungsmöglichkeiten:

Netterweise haben sich viele (hauptsächlich Framework-) Entwickler ebenfalls schon Gedanken über Codeorganisation und dieses Problem gemacht und verschiedene Ansätze, teils recht ähnliche Ansätze entwickelt :

  • ExtJS hat eine recht feste Ordnervorgabe, an der sich die Anwendung orientiert. Dependencies müssen aber in den Klassen angegeben sein
  • Qooxdoo erkennt Abhängigkeiten automatisch, dafür muss man allerdings das Generator Skript bei Änderungen ausführen (entspricht daher in etwa dem klassischen Kompilieren/Linken)
  • CommonJS spezifiziert einen Standard für Modularisierung, der recht verbreitet bei Serveranwendungen ist (z.b. NodeJS, CouchDB)
  • Und last but not least (es gibt natürlich noch mehr) hat Dojo ihren Modularisierungsmechanismus AMD (Asynchronous Module Definition) getauft und mit require.jseine Implementierung zur Verfügung gestellt

Ich fand require.js den schönsten Ansatz wenn man gerade kein großes Framework verwenden will. Einerseits ist es recht schlank, benötigt wenig Setup und reduziert vor allem die Anzahl der globalen Browser-Objekte. Letzteres ist vor allem wichtig, wenn man Gefahr läuft zwei Versionen der gleichen Bibliothek verwenden zu müssen (weil man z.B. JQuery verwendet und ein Tool in die Applikation einbindet, das seine eigene JQuery Version mitliefert). Ausserdem ist AMD keine Insellösung, sondern basiert in weiten Teilen auch auf CommonJS.

Require.js – How To:

Die Einbindung von require.js ist recht einfach, man bindet einfach require.js ein und gibt optional an, welches Skript die Startlogik für die Applikation beinhaltet:

<script data-main="include/app.js" src="scripts/require.js"></script>

Jetzt wird beim Start direkt die Datei include/app.js eingebunden und ausgeführt.
(Man kann sehr einfach programmatisch auch noch extra Regeln für die Auflösung von Skripten, Grundpfade, etc. angeben, da verweise ich mal auf die gute Dokumentation)
AMD definiert jetzt zwei wichtige Funktionen: require() und define():

  • require() fordert require.js auf, erst die Module zu laden und mir danach bereitzustellen. Das kann z.B. so aussehen:

    require(["mein/modul1","mein/modul2"], function(modul1,modul2) {
    //hier kann jetzt mit modul1 und modul2 aus dem 'mein' Ordner (= Namespace) gearbeitet werden
        modul1.process(document.body);
    });

    So könnte jetzt unsere app.js aussehen und schonmal alle Module laden, die sie direkt benötigt. Nützlich ist das auch wenn man nur in speziellen Fällen eine Abhängigkeit braucht und diese nur bei Bedarf on-the-fly nachladen will. Ansonsten findet man sich häufiger dabei define() zu Verwenden:
  • define() definiert ein neues Modul und deren Abhängigkeiten. Die mein/modul1.js könnte jetzt so aussehen und z.B. JQuery und ein weiteres Modul benötigen (Achtung: $ ist nur eine Variable die auf JQuery zeigt, nichts besonderes.) :
     define(['lib/jquery','mein/modul3'],function($,modul3) {
        // Schnittstelle für modul1 wird zurückgegeben, hier z.B. ein Schnittstellenobjekt
        return {
           funktion1: function(el) { return modul3.process($(el)); } //tue irgendetwas mit dem element
        }   
    });

Für einfache Projekte braucht man oft auch gar nicht mehr – das Problem mit der Codeorganisation ist gelöst! Allerdings lohnt ein Blick in die Dokumentation, die ist wirklich sehr gut und bietet Anreize und Lösungen für viele Probleme, die im Alltag auftreten könnten.
Ein Nachteil an require.js ist natürlich, dass man sein Programmiermodell ein wenig Umstellen muss. Da der Aufwand jedoch nicht wirklich groß, der Nutzen jedoch schon ist, kann man das meiner Meinung nach verkraften.

Weekly Snap: HWg-STE, DYI USBs, JavaScript tools & Wild Duck

14 – 18 May looked ahead to warmer weather with environmental monitoring, JavaScript tools, DYI flash drives, a presentation here and a fun run there – not to mention the odd Wild Duck.
Bernd began by sharing his presentation slides from the Open Source Systems Management Conference and Sebastian took a look at OpenNebula’s latest version, 3.4 Wild Duck.
Ready for summer, Georg then introduced HW Group’s HWg-STE environmental monitoring system just as Markus got excited about the upcoming B2RUN, company fun run round Nuremberg.
In time for the weekend, Jannis jostled JavaScript tips to fill much free time, while Markus gave a thorough step-by-step guide to making your own USB boot flash drive.

Urlaub mit JavaScript

Der Mai ist schon furchtbar Neben andauernden Wechsel zwischen Kalt und Warm, Blütenstaub (gefürchtet bei Allergikern und Autobesitzern ohne Garage) und Baumarktwerbungen bringt er uns vor allem eins –  Feiertage und freie Zeit.
Wer kennt die Situation nicht: Im Haushalt gibt es nichts zu tun, die Fussballstadien sind abgebrannt und bei dem sonnigen Wetter hat man gar keine Lust zu Grillen, Sport zu treiben oder einfach nur das Leben fernab der Arbeit zu genießen. Doch JavaScript kann da helfen, nicht in ein tiefes Loch zu fallen.
Denn hier gibt es einiges, dass man sich mal anschauen sollte. Mein heutiger Blogpost ist daher eine kleine Auflistung interessanter Bibliotheken und bemerkenswerter Entwicklungen rund um JavaScript. Auf Details gehe ich dabei heute nicht ein, man kann das eher als eine Art Linkliste betrachten.

1. RaphaëlJS

RaphaelJS ist eine Bibliothek, die einem Entwickler erlaubt, browserübergreifend Vektorgrafiken und Visualisierungen umzusetzen. Je nach Browser wird dabei SVG (alle guten Browser) oder VML (Internet Explorer bis Version 8) verwendet. Die Api ist schön, einfach und mit 90 KB  sehr schlank. Dank der MIT Lizenz kann es auch in kommerziellen Projekten eingesetzt werden.
Will man ein paar kleine Graphen einbauen, gibt es gRaphael, das mit winzigen 10 KB Kuchen-, Linien- und Balkendiagramme zeichnen kann.

2. JavaScript Deluxe: CoffeeScript

CoffeeScript ist eine Programmiersprache von JavaScript Entwicklern, die zwar begeistert von der Sprache aber frustriert von dessen Syntax waren. CoffeeScript wird zu (lesbaren und JSLint kompatiblen) JavaScript interpretiert, welches dann im Browser ausgeführt werden kann. Dadurch kann es mit existierenden Bibliotheken verwendet werden und benötigt keine Plugins oder bestimmte Browser.
Die Sprache an sich erinnert ein wenig an Python, es gibt z.B. keine Klammern und keine Semicolons, dafür aber viele nützliche Sprachelemente. Sollte man sich auf jeden Fall mal anschauen, gerade wenn man mit JavaScript bisher nichts anfangen konnte oder aus der Python/Perl Ecke kommt.

3. HTML5Boilerplate

Das HTML5Boilerplate Projekt bietet ein (konfigurierbares) Standardtemplate für Webprojekte. Hauptziel ist es, eine solide, browserunabhängige Basis für neue Projekte zu schaffen. Das ganze ist also ausnahmsweise kein Framework oder irgendeine Bibliothek, sondern ’nur‘ eine Vorlage, die einem einen guten Projektstart ermöglicht, ohne in irgendeine Richtung zu zwingen.
Klingt lapidar, ist aber irre Praktisch und Zeitsparend. Jeder, der durch ein vergessenes „console.log“ schonmal eine komplette Webanwendung im Internet Explorer abgeschossen hat, weiß was ich meine.

4. Abgefahrenes: pdf.js und jsmad

Hier kommt jetzt einfach nur interessantes, dass einem vor Augen führt zu was die aktuellen JavaScript Interpreter in der Lage sind: Pdf.js is ein komplett in JavaScript geschriebener PDF Viewer. Das Projekt ist zwar noch recht jung, funktioniert aber im Firefox und Chrome bemerkenswert gut. JSMad ist ein MP3 Player, der komplett in JavaScript geschrieben wurde, alac.js ist da gleiche, nur für das AAC Format (zum Teil in CoffeeScript geschrieben).
Wirkliche Geheimtipps sind da jetzt nicht dabei, aber vielleicht kennt jemand das ein oder andere ja noch nicht.

Weekly Snap: XEN PV, Mounting via SSH & JavaScript APIs

9 – 13 April brought a little something from every corner of the office, including tips for XEN, file APIs and file systems.
Managed Services’ Martin fiddled with XEN PV drivers on Windows, while one of our consultants – Tobias, showed how to mount a file system over SSH with sshfs.
From the development team, Jannis shared his tip for JavaScript file APIs and large files and Eva of Events announced this year’s OSDC dinner and drinks at California. Join us for good food, drink and discussions once again!