Traumschiff Enterprise
Enterprise Software, so würden manche sagen, ist Software mit einer Java-Version kleiner gleich 8 und einem Frontend-Stack, dessen Ursprünge mindestens 4 Jahre alt sein müssen. Weniger böse Zungen, wie Wikipedia, definieren Enterprise Software als eine, die den Anforderungen eines Unternehmens genügt, statt den Anforderungen einzelner User. Selbst bei nutzerorientierten Anwendungen, wie Web-Content-Management-Systemen, werden die Anforderungen der NutzerInnen im Enterprise Kontext selten gesammelt und vereinheitlicht. Viel eher werden verschiedene Sichtweisen für verschiedene Nutzergruppen von verschiedenen Verantwortlichen gleichermaßen eingebracht und umgesetzt, ohne dass die gleiche Sprache, oder gar miteinander gesprochen wird. Die, in Großkonzernen üblichen, hierarchischen Strukturen und Dinge, die “aus firmenpolitischen Gründen” passieren, tragen ihr Übriges dazu bei. Und so machen dann doch häufiger die verschiedenen Abteilungen “ihr Ding” und sorgen lieber dafür, dass “fristgerecht geliefert” wird, bevor sie ins Hintertreffen gegenüber Anderen geraten.
Doch die Fakten, dass ein Softwareprojekt auf viele Jahre angelegt ist und die sich aus den Strukturen der Personalverwaltung und der politischen Organisation großer Firmen ergebenden weiteren Implikationen sind nicht die einzigen Gründe, dass die Performance eines Softwareprojekts mit der Zeit nachlässt. Klar, veraltete Technologien können ein Problem sein. Aber, so mag man denken, wenn all die ProgrammiererInnen doch so talentiert und tüchtig sind, wieso ist dann nicht jeder Lieferungsbestandteil für sich großartig und gut? Wieso sind diese verschiedenen erfüllten Anforderungen nicht alle gleichermaßen wartbar, schick und vor allem performant?
programmers_are_evil() { /* curse their frozen hearts */ };
Nun, nicht nur die bösen, hierarchischen Großkonzerne, sondern auch die EntwicklerInnen und die DesignerInnen tragen ihren Teil zum Chaos bei. Wenn wir schon über die gleiche Sprache reden, sollten wir vielleicht auch das Sprechen an sich behandeln – ein, in der Community der ProgrammiererInnen viel zu selten gepflegtes Hobby. Möchte man sich nicht regelmäßig miteinander austauschen, kann man noch so viele Weeklies, Meta-Dailies, Architectural Meetups oder Workshops einberufen. Am Ende machen halt alle, was sie wollen.
Der soeben genannte Faktor ließe sich kontrollieren. Man stelle sich vor, man habe irgendeine moderne Form der Projektorganisation, in der manche sich vielleicht mehr auf den Job des Entwickelns, manche auf den des Koordinierens und manche auf den des Kommunizierens konzentrieren könnten. Kommt aber eine weitere Eigenschaft der ProgrammiererInnen hinzu, die gleichermaßen typisch, wie schizophren ist, so multiplizieren sich die beiden oben genannten Faktoren. Diese Eigenschaft lässt sich vielleicht als “Coding Borderline Syndrom” bezeichnen. Wir finden entweder unseren Code soooo toll, dass wir fest davon überzeugt sind, es darf keinen neben ihm geben – oder es ist uns so peinlich, was wir “damals” (das kann auch nur 3 Wochen her gewesen sein) gemacht haben, dass wir es in letzter Konsequenz aus unserem Gedächtnis verdrängen.
Der dritte Faktor, der bei der Implementierung der verschiedenen Programmbestandteile das Chaos auslöst, dass letztendlich viel zu oft zu Performance Problemen führt, ist ein klassisches Henne-Ei-Problem. Das Tolle am Entwickeln ist ja, dass man ganz plötzlich Dinge, für die man vorher stundenlange Arbeit und unzählige Werkzeuge – Rechenschieber, Stift, Papier, Zirkel, Stoppuhr und was sonst noch eben alles – benötigt hat, in wenigen Zeilen Code lösen kann. Und wer fühlt sich dementsprechend motiviert, Code zu schreiben? Klar, die Faulen unter uns. Zugegeben, nicht alle ProgrammiererInnen sind faule Zocker, die nur daheim rumhängen und sich ihre Pizza zusammen coden. Aber ein gewisses Maß Gemütlichkeit, gehört - glaube ich - schon dazu, sich zu entscheiden, das Programmieren lernen zu wollen.
Buzzword Driven Development
Machen wir uns nichts vor: wir sind in einer Zeit, in der Marketing unseren Alltag und die Wirtschaft dominiert. Wir kaufen Brause in hohen Dosen für 2€ - oder, wenn wir ein bisschen anders sein wollen, gesprudelten, bitteren Tee. Banken brauchen provokante Werbung, eine coole CI und schicke Kreditkarten, um Investoren anzulocken - und Arbeitsämter nennt man jetzt lieber Jobcenter.
Auch in der Entwicklung ist man hiervor nicht gefeit. Eine Flut von neuen, coolen, JavaScript Libraries, Designkonzepten, Datenbanktechnologien, Continuous Integration Tools und was auch immer, buhlt tagtäglich um das Interesse und die Gunst der ProgramiererInnen - mit coolen Logos, coolen Namen und zur Konkurrenz die Faust herumfuchtelnd: GraphQL und Angular (REST ist tot!), React und Redux (Vergesst jQuery!), Vue (vergesst React!), und so weiter. Hinzu kommen populäre Pattern und Technologien: SPAs, PWAs, Microservices, KI, Virtualisierung. Wer hier nicht klare Grenzen setzt, sondern “von Allem ein bisschen” ausprobiert, wird am Ende neben den Vorteilen all dieser Technologien eben auch gleichzeitig alle Nachteile der jeweiligen Technologien bekommen.
Performance als Allmende
Zu guter Letzt ein kleiner Exkurs: eine Allmende ist eine Form gemeinschaftlichen Eigentums. In der Landwirtschaft ist es bspw. Genossenschaftsbesitz abseits der parzellierten Nutzflächen. Ein weiteres Beispiel für Allmendegüter sind Straßen oder Fischbestände.
Es macht durchaus Sinn, die Performance, so wie, beispielsweise auch die Wartbarkeit einer Enterprise Applikation, als Allmende zu betrachten. In der Regel werden nämlich diese beiden Bereiche als Verantwortung der Feature Teams angesehen. Wird ein Feature von einem Team entwickelt, so übernimmt dieses auch die Wartung. Oftmals fehlt hier aber auch der Blick auf das Zusammenspiel der verschiedenen Parteien und Technologien im Gesamtkontext. Während eine Komponente, ein CSS-Pattern oder eine JS-Library alleinstehend performant und gut wartbar sein kann, kann sie, wenn die sie umgebenden Ansätze bloß gegensätzlich genug sind, genau das Gegenteil bewirken. Und so kann sich aus dem Allmendegut “Performance” auch die “Tragik der Allmende” ergeben: wenn zu viele Eigner das (faktische) Recht haben, die Ressource zu nutzen, keine wirksamen Nutzungsregeln bestehen und keiner das (faktische) Recht hat, andere von der Nutzung auszuschließen, wird die Ressource übergenutzt.
Was nun?
Das Thema Performance kommt wohl zumeist erst dann auf den Tisch, wenn die oben beschriebenen Prozesse schon weit voran geschritten sind: Dienstleister wurden mehrmals ausgetauscht und haben Architekturen, Pattern und Technologien wild vermischt - der Druck von und auf Enterprise POs und PMs haben ihr Übriges dazu beigetragen. Entwickler werden sich nicht einig, welches CSS Pattern benutzt werden soll – und benutzen am Ende drei verschiedene. Und die Verantwortung für die Performance Probleme wird bei jedem Team einzeln gesucht – vergebens.
Dabei wäre es gar nicht so schwer gewesen: gibt man den EntwicklerInnen, POs, PMs und QAs ein Nachschlagewerk, ein gemeinsames Manifest, zu dem sie sich bekennen müssen, so ließen sich die Teams auf ihre Verantwortung festnageln. Die Entwicklerin, die bei dem Code Review die Augen zu gedrückt hat, oder der PM, der gesagt hat, "das muss heute noch gemerged werden, im Zweifel liefern wir nen Hotfix", ließen sich auf Performance Guidelines, strenge Regeln für CSS-Selektoren, 3rd Party JS Library Blacklists oder Whitelists festnageln. Und im Optimalfall, hätten linting von Frontend und Backend die gröbsten Böcke von Anfang an verhindert. Ob dies aufgrund der oben beschriebenen Umstände in Enterprise Projekten überhaupt möglich ist, kann ich nicht sagen. Es ist zumindest so ambitioniert wie es erstrebenswert ist.
Performance als Querschnittsfeature
Fehlen solche verpflichtenden Faktoren allerdings in der Entwicklung, so muss man von architektonischen Versäumnissen der ersten Stunde sprechen, die sich nur lösen lassen, indem man die Performance einer Applikation umdeutet: von einem Allmendegut an dem sich alle bei Bedarf bedienen zu einem “Feature”, das von allen gleichermaßen geachtet und von einem dedizierten Team gepflegt wird. Nur indem man einen großen Aufwand betreibt, um zunächst die Versäumnisse zu beheben, kleine Quick Wins und groß angelegte Refactorings unternimmt, und danach laufend die Performance beobachtet, schnell reagiert und ständig kommuniziert kann man dieses Feature unter Kontrolle halten.
In Teil 2 soll beschrieben werden, wie das Thema Performance zu einem Messbaren Faktor umgedeutet werden kann: wie sieht das Monitoring aus? Was und wen wollen wir betrachten? Welche KPIs eignen sich zur Analyse? Was sind unsere Grundlagen, um spätere Erfolge zu messen?
Teil 3 widmet sich, dem anschließend, den Tools die wir verwenden können um Probleme, Wettbewerb und Erfolg zu messen. Welche Tools benutzen wir für die Analyse? Wie identifizieren wir konkrete Probleme und Lösungsansätze? Welche Bestandteile der Analysen sind überhaupt relevant? Und wie kommuniziert man die Erfolge?
In weiteren Artikeln werden dann die konkreten Maßnahmen, die auf technischer Ebene ergriffen werden können, um die ersten Erfolge zu feiern diskutiert: Wo sind in der Regel die meisten Maßnahmen zu ergreifen? Wie kann das komplexe und wichtige Thema Caching optimiert werden? Wie kann man die Last verringern? Und wie kann man die Erfolge persistieren?