webfactory Neuigkeiten https://www.webfactory.de/assets-version-1539163935/bundles/webfactorywebsite/img/inside-logo.png Logo Webfactory http://www.webfactory.de Zend_Feed_Writer 2 (http://framework.zend.com) https://www.webfactory.de/blog/ © 2018 webfactory GmbH Mein Praktikum bei der webfactory Wie kam es dazu?

Zuallererst muss man wissen, dass ich zwar in Bonn geboren, aber in Ostbüren, einem kleinen Dorf in der Nähe von Unna, aufgewachsen bin. Wie ich trotzdem zu einem Praktikum in Bonn gekommen bin? Das geschah über mehrere Ecken und eher zufällig. Ein Freund meines Vaters hatte erfahren, dass mein zukünftiger Berufswunsch in die Richtung der Mediengestaltung ging. Da er gut mit Stefan befreundet ist, konnte ich so den Kontakt zur webfactory herstellen und nach einem kleinen „Praktikums-Bewerbungsgespräch“ stand fest, dass ich im Februar 2018 mein Praktikum bei der webfactory in Bonn bestreiten durfte. Nachdem sich der Januar 2018 dem Ende neigte, wuchs meine Vorfreude immer mehr, das Team und die Arbeitsatmosphäre kennenzulernen.

Was ist eigentlich Webentwicklung?

Da ich zuvor nicht wirklich mit Webentwicklung in Kontakt gekommen war, ging ich naiverweise davon aus, dass man eine Website folgendermaßen erstellt: einfach ein paar Blöcke in eine leere Website ziehen, diese mit einer benutzerfreundlichen Oberfläche nach Lust und Laune gestalten, sie anschließend mit Inhalt bestücken und sie dann einfach „im Internet“ speichern. Eben so, wie es die tollen Werbungen von diversen Homepage-Baukasten Websites versprechen. Ich sah also nicht gerade eine Herausforderung darin, eine Internetpräsenz zu erstellen. Jedoch sollte ich feststellen, dass diese einfache Welt so nicht existiert… 

Jeder, der sich mit meiner naiven Ansicht identifizieren kann, darf nun einen kleinen Einblick in die Komplexität der Webentwicklung werfen: Hier ist ein kleiner Ausschnitt von unserer Website.  

Ausschnitt von unserer Website webfactory.de. Zusehen sind Überschriften und mehrere Textelemente

Codeausschnitt von dem Quelltext aus dem Bild zuvor

Wer sich nun fragt, was der ganze Text im Bild 2 zu bedeuten hat: So sieht ein recht simpler Code-Ausschnitt aus, welcher später vom Browser gelesen und, wie im Bild 1 zu sehen dargestellt wird.

Laufen lernen

Da das Thema Webentwicklung für mich etwas grundlegend Neues war, musste ich zunächst die Basics kennenlernen, weshalb mir CodePen und ein paar Bücher zum Thema ans Herz gelegt wurden. CodePen ist eine Online-Community zum Testen und Zeigen von HTML-, CSS- und JS-Codeschnipseln. Man kann direkt im Browser in einem Editor Code schreiben, welcher in einem zweiten Fenster daneben vom Browser interpretiert wird. Man bekommt also sofort ein Feedback und kann somit lernen, wie sich der Code verhält. Durch CodePen bekam ich einen seichten Einstieg in das Thema Webentwicklung und konnte ein rudimentäres „Verständnis“ (falls man das so nennen darf) aufbauen, wie HTML und CSS zusammen spielen, um eine Website zu strukturieren und zu gestalten. Somit habe ich zunächst Tags wie <html><body><header><div><h1><p><ul> und <li> kennengelernt. Meine erster Versuch sah so aus: 

Mein erster Website-Entwurf mit einfachen HTML-Elementen

Es war genau an diesem Punkt, wo ich mental zwischen

und

stand. Es überwog dann aber doch letzteres.

Anschließend nahm ich mir das Buch „Resilient Web Design“ von Jeremy Keith vor, in dem es um die Entstehungsgeschichte des Internets und um grundlegende Herangehensweisen, wie man Webseiten flexibler und widerstandsfähiger machen kann, geht. Doch was mir am meisten im Kopf hängen geblieben ist, ist ein Zitat von Sir Isaac Newton: „If we have seen further it is by standing on the shoulders of giants.“ In anderen Worten: wenn unser Wissen durch Generationen weitergegeben wird, werden Theorien verfeinert, Maßeinheiten standardisiert und präzisere Experimente durchgeführt. Wir wären heute nicht an dem selben Punkt, wenn nicht das Wissen von früheren Generationen weitergegeben worden wäre. Diese Denkweise kann man auch auf die Webentwicklung übertragen. Das Web ist in einem ständigen Wandel und wird, solange wir unser Wissen weitergeben, auch in diesem Wandel bleiben.

Da in der webfactory mit GitHub gearbeitet wird, konnte ich mir mit TryGitHub einen guten Einblick in ein sogenanntes „Version Control System“ (VCS) verschaffen. Da die interaktive Webanwendung einem die Schritte spielerisch beibringt, sind die Basics leicht zu verstehen. 

Ein VCS bringt viele Vorteile mit sich. Es dient zur Erfassung von Änderungen an z.B. Dokumenten oder Dateien. Jede Veränderung wird mit einem eigenen Versionsstempel versehen und in einem Archiv gespeichert. Somit kann man zu jedem Zeitpunkt auf eine ältere Version zugreifen, um z.B. Fehler, welche bei einer Änderung aufgetreten sind, zu beheben. Gerade aus dem Bereich der Webentwicklung ist ein VCS nicht mehr wegzudenken. 

Da ich nun ein wenig mehr mit dem Thema Webentwicklung vertraut war, wurde mir das Buch „Responsive Webdesign“ von Christoph Zillgens an die Hand gegeben. Wie der Titel schon verrät, geht es um responsives Webdesign. Aber was ist das?

„Responsive Webdesign“ ist eine gestalterische und technische Denkweise zur Erstellung von Websites. Grundsätzlich geht es darum, eine Website für jedes nur mögliche Endgerät optimal darzustellen. Früher war es üblich, eine Website einfach für zwei bis drei verschiedene Bildschirmgrößen zu erstellen. Jedoch gibt es mittlerweile unfassbar viele Größenvarianten, weshalb man eine Website nicht mehr mit festen Breitenangaben, sondern mit flexiblen Variablen designed.

Wenn man mit Responsive Webdesign arbeitet, wird man schnell über Begriffe wie „Mobile First“ oder „Desktop First“ stolpern. Beides sind Methoden, wie man eine Website gestalten kann. Im Fall von „Mobile First“ beginnt man, seine Website von der mobilen Ansicht aus zu gestalten. Dafür gibt es viele verschiedene Gründe. Ich habe hier drei Gründe aufgelistet, welche mir am wichtigsten erscheinen:

  1. Durch den mangelnden Platz ist man daran gebunden, nur den wichtigsten Inhalt auf seiner Website darzustellen – somit vermeidet man schon in der Konzeptionsphase überflüssige Nebeninformationen. 
  2. Zur Zeit gibt es 4,12 Milliarden Internet Nutzer. Davon sind 3,8 Milliarden Nutzer mit dem Smartphone im Internet. Das sind ~ 93% der User (Stand July 2018). Somit macht es mehr als Sinn, seine Website zunächst für eine mobile Ansicht zu gestalten.
  3. Progressive Enhancement (auf deutsch „fortschreitende Verbesserung“) beschreibt die Vorgehensweise, eine Website so zu gestalten, dass sie auch unter erschwerten Bedingungen, wie z.B. auf alten Smartphones (mit wenig Leistung), in veralteten Browsern, trotz schlechtem Netzempfang etc. so funktioniert, dass User ihre Bedürfnisse befriedigen können (Zeitungsartikel lesen, Formular abschicken, …). Danach verbessert man die UX (User Experience) dieser „Basisversion“ für Geräte, Browser und Situationen, die mehr Möglichkeiten unterstützen und erlauben. 

Beim „Desktop First“ läuft es genau andersherum. Hier beginnt man aus der Desktop Ansicht heraus, seine Website zu gestalten. Obwohl auch sinnvolle Argumente für „Desktop First“ sprechen, ist meine persönliche Vorliebe der „Mobile First“ Ansatz.

Meine Portfolio Website

Wireframes

Da ich nun einen Grundschatz an Informationen zum Thema Webentwicklung besaß, konnte ich endlich mit der Entwicklung meiner eigenen Website beginnen. Zunächst musste die Frage geklärt werden, was meine Website beinhalten sollte. Da ich in meiner Freizeit gerne zeichne und mit Photoshop experimentiere, stand schnell fest, dass es in die Richtung einer Portfolio-Website gehen sollte. Nachdem diese Entscheidung feststand, fing ich damit an, s.g. Wireframes anzufertigen. Wireframes sollen dazu dienen, eine Struktur für eine Seite festzulegen, ohne sich dabei von Designelementen wie Farben und Bildern ablenken zu lassen. Jedoch waren in meinem Kopf tausend Ideen von tollen animierten Diagrammen und außergewöhnlichen Formen, die mit Funktionen belegt werden könnten, sodass ich nicht bei dem Erstellen einer Struktur blieb, sondern sofort begann, mir Gedanken über Dinge zu machen, welche noch weit entfernt lagen. Doch mit Hilfe von Stefan konnte ich drei Wireframes zu Papier bringen, welche mir im späteren Erstellungsprozess meiner Website sehr halfen. 

Im nächsten Schritt begann ich zunächst, ein Logo und Icons für meine Website zu erstellen. Dabei half mir ein Artikel namens „The Ultimate Guide to a Flat Icon Set“. Muzli ist ein Blog, der viele nützliche Tipps zu digitalem Design und UX veröffentlicht. Mit Hilfe von Stefan und dem Artikel konnte ich mein erstes Icon Set erstellen, welches sich aber im Laufe des Designprozesses meiner Website noch mehrere Male verändert hat. 

Responsive

In dem zuvor erwähnten Buch „Responsive Webdesign“ ging es um den responsiven Aspekt einer Website. Dieser durfte natürlich auch in meiner Website nicht fehlen. Deshalb sollte ich mich noch eingehender in das Thema Media Querys einlesen. Nach kurzem Durchstöbern des Internets konnte ich damit beginnen, meine Website mit Media Querys für mehrere Endgeräte zu optimieren.

Inhalte integrieren

Nachdem ich meine Website für verschiedene Endgerätgrößen optimiert hatte, war es an der Zeit, meine Inhalte einzufügen. Mit Hilfe des so genannten „Masonry Layout PlugIns“ konnte ich meine Bilder auf eine schöne Art und Weise darstellen. Dieses Layout findet man z.B. bei Pinterest oder folgenden Seiten: Kristian HammerstadLoading Effects for Grid Items. Masonry sortiert Objekte wie Bilder nach ihrer Größe, sodass möglichst keine Lücken entstehen. Außerdem bringt dieses PlugIn großartige Lade-Effekte mit sich, wie man im letzten Beispiel sehen kann. 

Farbpalette

Der nächste Schritt auf meiner Liste sollte mir noch schlaflose Nächte bereiten… 

Die große Frage der Farbpalette stand im Raum. Mit Hilfe von verschiedenen Seiten, wie z.B. Pigment und Coolors konnte ich sehr schnell Farbkombinationen finden, was sich sowohl Segen als auch Fluch herausstellte, da ich nicht mehr aufhören konnte, neue Farbpaletten zu generieren. Ich hatte schnell ungefähr 16 verschiedene Farbkombinationen, welche mir alle gefielen. 

Mein typischer Arbeitsablauf bestand daraus, dass ich mich vormittags mit Stefan oder Søren zusammensetzte und überlegte, welche Features oder Verbesserungen ich im Laufe des Tages umsetzen wollte. Häufig bekam ich hilfreiche Tipps zur Hand und konnte bei Fragen immer einen Ansprechpartner finden. 

So stand ich nun da mit meinen 16 verschiedenen Farbpaletten, und jedes Mal, wenn ich mit Fragen zu den beiden kam, hatte ich eine andere Farbpalette auf der Seite implementiert, was die beiden sichtlich zur Verzweiflung brachte!

Natürlich konnten sie mir auch bei diesem Problem weiter helfen. Ich bekam den Blogartikel „V6-Color“ an die Hand, in dem Rob Weychert (ein Künstler und Designer aus Brooklyn, NY) beschreibt, wie man das Problem mit der Farbauswahl lösen kann. Seine Idee ist es, die Website zunächst einmal nur mit Grauabstufungen zu designen, um so zu erkennen, welche Bereiche akzentuiert werden sollen. Anschließend kann man dann eine Farbpalette darüberlegen, welche die selbe Priorisierung von Farben hat. Man verhindert so, dass zu viele Objekte auf der Website durch Farben hervorgehoben werden und miteinander in Konkurrenz treten.

Typografie

Nun war es an der Zeit, sich mit dem Thema Typografie zu beschäftigen. Noch nicht ganz ausgesprochen, lag auch schon ein 400 Seiten schweres Buch vor mir, mit dem Titel „Detailtypografie“ von Friedrich Forssman. Zuvor hätte ich nie gedacht, dass man sich so viele Gedanken zu Schrift machen kann. Zugegeben war ich damit auch dezent überfordert, weshalb ich mir mit der Hilfe von Google Fonts ein schönes Schriftarten-Pärchen (zwei aufeinander abgestimmte Schriftarten) aussuchte und es anschließend in meine Seite einband.

Veröffentlichung

Da sich meine Praktikumszeit langsam dem Ende neigte, durfte einer der wichtigsten Schritte natürlich nicht fehlen: Das Veröffentlichen! 

Mittlerweile konnte sich meine Website sehen lassen. Ich war selber von dem Resultat begeistert und erstaunt, was man in vier Wochen ohne Anfangswissen auf die Beine stellen kann. Somit war es an der Zeit, meine Website über GitHub Pages im Internet zu veröffentlichen. GitHub Pages ist ein kostenloser Dienst, um statische Websites zu hosten. Nachdem dieser Schritt ebenfalls abgehakt war, musste ich natürlich meine Website sofort mit dem Smartphone aufrufen! 

Es war ein magischer Moment für mich, meine Arbeit von über vier Wochen endlich, im wahrsten Sinne des Wortes, in den Händen halten zu können. Die eigene Website über sein Smartphone aufzurufen fühlt sich einfach großartig an. 

Parallel zu meiner Freude tauchten noch die ein oder anderen Schönheitsfehler auf, welche zuvor von mir nicht abzusehen waren. Diese wurden natürlich dann noch schnell behoben.

Und so sieht meine Website nun aus: https://dermeier.github.io/portfolio-website/ 

Die Überraschung

Schon zu Beginn des Praktikums war ich gefragt worden, wie meine zukünftigen Pläne aussähen. Tatsächlich war ich auf der Suche nach einem Ausbildungsplatz im Bereich Mediengestaltung. Zufälligerweise suchte die webfactory noch einen Auszubildenden für das Jahr 2018. Daher wurde mir der Vorschlag gemacht, dass man nach dem Praktikum einmal schauen könnte, ob sowohl die webfactory als auch ich mir eine Ausbildungsverhältnis vorstellen könnte. An meinem vorletzten Tag wurde ich dann zu einem kleinen Gespräch gebeten. Mit einem Kaffee in der Hand erwarteten mich Stefan und Søren, um mit mir das Praktikum zu rekapitulieren. Doch wir kamen recht schnell zu dem Punkt, an dem Søren sagte: „Ich habe ein gute und eine schlechte Nachricht! Die gute Nachricht ist: du darfst gerne deine Ausbildung bei uns anfangen! Die schlechte Nachricht ist, dass du dann auch im alltäglichen Wahnsinn der Webentwicklung steckst.“ Ich denke, es ist nicht nötig zu erwähnen, wie sehr ich mich über diese Nachricht gefreut habe! 

Am liebsten hätte ich noch am selben Tag den Vertrag unterschrieben, zuvor mussten aber noch ein paar organisatorische Dinge geklärt werden. Wie anfangs schon erwähnt wohnte ich nicht in Bonn und ein tägliches Pendeln von insgesamt fünf Stunden wäre nicht möglich gewesen. Doch nach ausgiebiger Absprache mit meinen Eltern stand fest, dass ich nach Bonn ziehen würde. Infolgedessen konnte ich meinen Vertrag einige Woche später unterschreiben! 

Mein letzter Tag

Am letzten Tag des Praktikums erstellte ich eine Präsentation, welche ich dann nach dem Mittagessen dem ganzen Team präsentierte. Zu meiner Überraschung wurde mir als Abschiedsgeschenk ein Buch über die Geometrie des Designs überreicht. 

Schneller als ich es erwartet hätte, hieß es nun, im wahrsten Sinne „Auf Wiedersehen“ zu sagen.

Fazit

Abschließend kann ich sagen, dass die Zeit bei der webfactory großartig, herzlich und informativ war. Ich habe in den vier Wochen so viele neue Sachen gelernt ohne überhaupt zu bemerken, dass ich sie lerne. Ebenso hat der Aufenthalt meine Interessen so erweitert, dass ich das neu entdeckte Interessenfeld nun zu meinem Beruf machen möchte/werde. Bei der webfactory fühlt man sich einfach wie Zuhause!

]]>
Thu, 11 Oct 2018 14:31:56 +0200 https://www.webfactory.de/blog/mein-praktikum-bei-der-webfactory https://www.webfactory.de/blog/mein-praktikum-bei-der-webfactory webfactory GmbH webfactory GmbH 0
Unser Bürohund-Experiment Auf den Hund gekommen 

Ich habe wirklich keine Ahnung mehr, wie ich eigentlich ursprünglich auf die Idee gekommen bin, dass ein Hund eine tolle Sache wäre. Vielleicht war es auch eher so herum, dass es mir vorher schlichtweg nicht in den Sinn gekommen ist, weil es unmöglich gewesen wäre, einen Hund an meinem alten Arbeitsplatz (ein Forschungslabor) zu integrieren. Ein Bürohund hingegen gehört ja mittlerweile fast schon zum guten Ton – und während ich so gedanklich an meiner Idee feilte (Hundebilder anschauen, Hundevideos gucken, Hundebücher lesen… man steigert sich da ja so rein mit der Zeit…), reifte in mir auch die Überzeugung, dass die webfactory die perfekte Bürohundefirma wäre. Allein schon, weil uns Mitarbeiter*innen ja doch eher selten ein (realistisch umsetzbarer) Herzenswunsch abgeschlagen wird. Ich war mir dann auch einigermaßen sicher, dass meinem Vorschlag kaum jemand würde widersprechen können, denn ich hatte mir einen sehr guten Plan zurechtgelegt: Es würde kein so richtiger Hund werden, sondern nur ein Pflegehund. Ein Bürohund auf Zeit also. Das hielt ich auch privat für eine gute Idee, denn ich wollte mich auch nicht so gerne direkt ein ganzes Hundeleben lang verpflichten, ohne zu wissen, ob mir das mit dem Vierbeiner überhaupt so gut gefallen würde und ob meine Lebensumstände über Jahre hinweg die Betreuung eines Hundes zulassen würden. Ein Pflegehund hingegen schien mir die win-win-win-situation zu sein: Win-1 und 2 für die Firma und mich, die keine Entscheidung für immer treffen müssten, sondern in Ruhe ausprobieren könnten, und win-3 für den Hund, der bei mir würde leben dürfen, bis er seine Adoptivfamilie gefunden hätte, anstatt im Tierheim auf sie warten zu müssen. 

Die Entscheidungsphase

Als die Idee also lange genug gereift war (und ich das Gefühl hatte, dass mein Jobstart ausreichend lange zurücklag um nicht zu sehr mit der Tür ins Haus zu fallen...), habe ich schließlich eine Mail ans Team geschrieben und meinen Wunsch erklärt. Ich wollte, dass sich alle ganz in Ruhe und in ihrem eigenen Tempo Gedanken zu dem Thema machen konnten, bevor wir in der großen Runde darüber reden. Und natürlich bot so eine Mail auch ausreichend Raum, um auf sämtliche Studien zu verlinken, die zeigen, wie gut sich die Anwesenheit von Hunden am Arbeitsplatz auf die Mitarbeiter*innen auswirkt. ;-)

Der in den nächsten Wochen folgende "Kampf" war kein großer, aber es mussten schon einige Gespräche geführt werden. Einige Mitarbeiter reagierten vollkommen begeistert, anderen war es relativ egal. Ein Mitarbeiter machte sich Sorgen um seine schwelende Hundeallergie, ein anderer machte sich große Sorgen um alles Mögliche (Haare auf dem Teppich, unangenehmer Geruch, Postboten verbellen, „Den gibst du doch nie wieder ab“ etc.). Auch die Unabsehbarkeit der Länge des Experiments war ein Thema. Zu meiner großen Freude erhielt ich auf meinem Weg allerdings auch Unterstützung von der hundebegeisterten Fraktion im Team: Somit tummelten sich plötzlich auf mysteriöse Art und Weise eine große Anzahl an niedlichen Hundebildern in unseren Testfotos oder es wurden ganz unauffällig Tüten voller Hunderleckerlis im Sichtbereich der Skeptiker deponiert. Ich gab mir unterdessen Mühe, allen genannten Sorgen einen passenden Lösungsvorschlag entgegenzusetzen. So versprach ich beispielsweise, mit dem Vierbeiner für die Dauer seines Besuchs in unseren Meetingraum auf der anderen Straßenseite umzuziehen, falls er sehr stören würde oder irgendjemand wirklich schlimme Allergieschübe hätte. Es hat ein Weilchen gedauert, doch letzten Endes waren alle Fragen geklärt, alle Hürden überwunden und so zog im Februar schließlich die weiße Wuschel-Hündin Blanca bei uns ein.

Blanca liegt beim Teammeeting auf einem Zettelstapel

Ein Hund zieht ein

Ich glaube, die Zeit mit Blanca war für mich privat deutlich aufregender als für die Kollegen auf der Arbeit. Blanca war eine liebe Hündin, die auf der Arbeit meistens brav auf ihrem Platz lag, gerne Stofftiere zerkaute, und deren einzige offensichtliche Macke darin bestand, mir auf Schritt und Tritt nachzulaufen. Angst und Bange wurde mir kurz, als sie den Serverraum mit der Hundewiese verwechselte und eine nasse Pfütze auf dem Teppichboden hinterließ – und als sie dann auch noch Durchfall bekam, der auf selbigem landete. Doch zu meiner großen Überraschung lösten die Teppichunfälle keine Krise in der Firma aus und letzten Endes hatte ich sogar das Gefühl, die einzige zu sein, die das richtig schlimm fand. Auch die restlichen der zuvor geäußerten Sorgen lösten sich in Luft auf: Blanca bellte nicht, zerkaute keine Möbel, stank auch nicht unangenehm (Profitipp: Hund baden!) und niemand erlag einem Allergieschock. Insgesamt blieb Blanca bloß für zwei Wochen und dann zog sie auch schon wieder aus. Das darauf folgende Teamfazit zum ersten Hunde-Experiment fiel insgesamt positiv aus. Das wichtigste: Die Skeptiker hatten ihre Meinung geändert und fanden das Büroleben mit Hund doch gar nicht so schlimm. Ganz ohne lange Umschweife stimmten dann auch direkt alle zu, dass ich noch einmal einen Pflegehund mit zur Arbeit nehmen dürfte – immerhin war ich ja auch fast ein bisschen traurig, dass Blanca uns so schnell wieder verlassen hatte. Und so zog nur kurze Zeit später Nico bei uns ein. 

Noch ein Hund zieht ein

Auch wenn Blanca schon brav war, übertraf Nico sie sogar noch. Auf der Arbeit tapste er ab und an friedlich durch die Räume, schlief die meiste Zeit des Tages in irgendeiner Ecke, war — selbst mit Durchfall (warum haben Hunde eigentlich ständig Durchfall???) — vorbildlich stubenrein und eigentlich nahm man ihn nur so richtig wahr, wenn er ab und an empört herumwuffte, weil er etwas zu essen haben wollte. Es sah fast so aus, als würde auch Nico nach kurzer Zeit adoptiert werden, doch dann stellte sich heraus, dass er einen Herzfehler hat und deswegen wohl kaum noch Chancen, eine Familie zu finden. Und somit blieb Nico. Bis heute. Besonders schön fand ich es zu sehen, wie die Gespräche über sein für-immer-bleiben im Vergleich zu den ersten Hundegesprächen abgelaufen sind: Während wir am Anfang über mehrere Wochen Unterhaltungen geführt haben, war die Entscheidung darüber, dass er bleiben darf, nach einer Weile des Austestens dann blitzschnell gefallen: Eine Runde, jeder durfte seine Meinung sagen und nach einer Minute war das Ding durch. 

Nico auf seiner Decke im Büro

Status heute

In der Firma hat Nico mittlerweile etliche Fans gefunden und dreht tagsüber seine Runden durch die Büros, um sich von einem nach dem anderen durchkraulen zu lassen. Als ich über das Wochenende verreist war, durfte er sogar schon einmal bei einem Kollegen übernachten, ein anderer war schon mit auf der Hundewiese und immer mal wieder fallen Sätze wie: „Ich finde es einfach schön, wenn wir ein Teammeeting haben und Nico legt sich zu uns.“ Unter seinem Pseudonym „Obi-Wau Kenobi“ hat Nico sogar mittlerweile seinen eigenen Teamavatar und einen Eintrag in der Mitarbeiter-Sektion unserer Website. Während die Hundeallergiker sich eingangs noch eher von ihm ferngehalten und nach jedem Kraulen die Hände gewaschen haben, ist auch das mittlerweile passé und selbst die Hundeskeptiker haben hier und da mal ein paar Streicheleinheiten übrig. Soweit ich das beurteilen kann, haben sich alle Sorgen des Teams mittlerweile in Luft aufgelöst und ich kann jeder anderen Bürogemeinschaft somit nur ans Herz legen, das Experiment einfach mal selbst zu wagen, statt sich zu sehr in was-wäre-wenn-Gedanken und Ängsten zu verstricken.

Und über die Arbeit hinaus? Nun, der arme Nico hat wirklich ganz laut „Hier“ gebellt, als die Hundekrankheiten verteilt wurden. Zu dem Herzfehler kamen mit der Zeit immer mehr Diagnosen und Behandlungen dazu. Glücklicherweise geht es Nico dank medizinischer Betreuung mittlerweile richtig gut. Zugegebenermaßen: Hätte ich mich anfangs direkt für einen eigenen Hund entschieden, wäre es wohl kaum ein alter, kranker Hund aus dem Tierheim geworden, sondern vermutlich ein Welpe vom Züchter – aber jetzt bin ich sehr froh darüber, dass es eben Nico geworden ist und glaube wirklich nicht, dass ich mit einem anderen Hund glücklicher wäre. Wie eingangs angedeutet, hätte ich mich auch von selbst vermutlich nicht so bald getraut, einen Hund für immer zu mir zu nehmen und bin ganz froh, dass das Schicksal mir da einen kleinen Schubs gegeben hat.

Nico rollt sich vor dem Lab auf der Straße

Noch ein Hund zieht ein?

„Wir sollten mehr Bürohunde haben“, sagte vor einiger Zeit ein Kollege ganz unbedarft, beim Mittagessen. Im Nachhinein könnte man meinen, dass diese Aussage vielleicht prophetischer Natur war, denn seit kurzem liebäugelt der nächste im Team mit der Adoption eines Vierbeiners. Wie es ausschaut, sind unsere Fellknäule also bald zu zweit und beim Mittagessen kann es nun schon einmal vorkommen, dass wir über Hunderassen und Welpenerziehung diskutieren. 

Ist dies also die Geschichte einer Firma, in der plötzlich nur noch Hundefans arbeiten und in der selbst der letzte Hundeskeptiker sein Herz an die Vierbeiner verloren hat? Keinesfalls! Nach wie vor gibt es unter uns hundebegeisterte und weniger hundebegeisterte Teammitglieder. Was unser Experiment aber gezeigt hat ist, dass wir eine Firma sind, in der die Bedürfnisse und Wünsche einzelner ernst genommen werden, in der wir miteinander reden, uns auf Experimente einlassen und bereit sind, unsere Meinung zu ändern. Zwar mögen nicht alle von uns ganz persönlich Lebensfreude daraus ziehen, dass es Nico gibt, doch haben alle mal mindestens festgestellt, dass er sie nicht stört und waren bereit, von ihrer ablehnenden Haltung Abstand zu nehmen. Und das ist auf jeden Fall einer der Gründe, warum ich sehr froh darüber bin, in diesem Team zu arbeiten. ♡

Falls jemand von euch lieben Leser*innen auch gerne einen Hund mit ins Büro nehmen möchte und Fragen hat oder sich einfach so für das Thema interessiert, wendet euch doch einfach an mich via: info@webfactory.de

Nico vor einer Landschaft

]]>
Mon, 08 Oct 2018 17:02:22 +0200 https://www.webfactory.de/blog/unser-buerohund-experiment https://www.webfactory.de/blog/unser-buerohund-experiment webfactory GmbH webfactory GmbH 0
Warum wir ungerne an Ausschreibungen teilnehmen Das Wort „Ausschreibung“ ist mit der Webbranche in etwa so fest verbunden wie die Wörter  „Sprint“, „Serverausfall“ und „Kaffee“. Man munkelt, dass es dort draußen Agenturen gibt, in denen ganze Teams nichts anderes tun, als an einer Ausschreibung nach der nächsten teilzunehmen. Auf der anderen Seite der Macht – nämlich seitens der Auftraggeber – besteht oft sogar die rechtliche Verpflichtung, ein Projektvorhaben dem breiten Wettbewerb zur Verfügung zu stellen, insbesondere, wenn es sich dabei um Projekte der öffentlichen Hand handelt. Dass den Kunden also oft gar nichts anderes übrig bleibt als ihr Projekt auszuschreiben und dass sie sich dabei an gewisse Vorgaben halten müssen, ist uns somit natürlich bewusst. Dennoch sind wir in der webfactory bekennende Ausschreibungs-Skeptiker. Nur in Ausnahmefällen nehmen wir an einer teil, etwa dann, wenn das Vorhaben besonders gut zu unseren Anforderungen passt und ein Projekt uns sehr reizt. Warum das so ist, möchten wir in diesem Blogbeitrag erzählen.

1. Wir möchten mit potenziellen Kunden in den Dialog treten, statt anonyme Bewerbungen zu versenden

Wir haben das große Glück, dass die meisten unserer Kunden ihren Weg ganz ohne komplizierten Ausschreibungsprozess zu uns gefunden haben. Im Normalfall läuft das so ab: Ein*e Interessent*in meldet sich bei uns, man telefoniert ein paar Mal miteinander und steckt dabei ab, ob Projektwünsche und Expertise zusammenpassen und man sich vorstellen kann, miteinander zu arbeiten. Vielleicht trifft man sich dann noch einmal zu einem persönlichen Gespräch um weitere Details zu klären, zeigt das ein oder andere Vergleichsprojekt und brainstormt eventuell auch schon einmal los, in welche Richtung das Vorhaben gehen könnte. Das Angebot für das Projekt und die Auftragsbestätigung erfolgen dann oft ganz zwanglos via E-Mail. Der zentrale Aspekt, der hier betont werden soll, ist, dass diese gesamte Akquisephase in Form eines beidseitigen Austauschs stattfindet. Man spricht miteinander, kann sich erklären, eventuelle Missverständnisse schnell aus dem Weg räumen, alternative Vorschläge anbieten und letztlich auch schauen, ob man sich sympathisch ist. Bei einer Ausschreibung fällt genau dieser persönliche Aspekt in weiten Teilen weg. Stattdessen müssen hier seitenweise Unterlagen gelesen und Fragebögen ausgefüllt werden. Rückfragen sind nur eingeschränkt und oft nur über den schriftlichen Weg möglich. Das System kostet viel Zeit, Nerven und Ressourcen und ist unserer Ansicht nach dabei auch noch deutlich ineffizienter als die persönlichen Beratungsgespräche, die wir demgegenüber vorziehen. Gewisse Aspekte einer Ausschreibung nehmen dabei nahezu absurde Züge an: zum Beispiel, wenn man nach seitenlanger Lektüre der Projektanforderungen aufgefordert wird, diese in eigenen Worten wiederzugeben. Dahinter mag das Bedürfnis stehen, irgendwie zu verifizieren, ob die sich bewerbende Agentur das Projekt auch wirklich verstanden hat. Man kommt sich dabei allerdings ein bisschen vor wie bei einer Schulprüfung. Würde man einfach miteinander sprechen, wäre doch direkt klar, dass wir die Aufgabenstellung verstanden haben.

2. Wir finden Ausschreibungen zu teuer

Natürlich rechnen auch wir erste Beratungsgespräche, die wir mit potenziellen Neukunden führen, in der Regel nicht ab. Das Problem ist, dass die Akquisekosten bei einer Ausschreibung dieses normale Maß überschreiten. Ganze Berge an Unterlagen müssen gewälzt werden, darunter seitenlange Bedingungen und Verträge. Neben der Wiedergabe des Projektvorhabens in eigenen Worten müssen Mitarbeiterprofile versendet und eine meist festgelegte Anzahl an Referenzprojekten vorgestellt werden, der eigene Projektmanagementprozess muss erläutert und Standardfragen („Welche Gefahren sehen Sie in dem Projekt?“, „Wie gewährleisten Sie die Erreichbarkeit im Notfall?“) beantwortet werden. All dies kostet Zeit — und zwar so viel, dass gerne mal zwei Mitarbeiter einige Tage bis Wochen damit beschäftigt sind, die Unterlagen zusammenzustellen. Bei hohem Zeitdruck versteht sich, denn die Deadlines sind meist eng gesteckt. Das bedeutet für uns schon einmal, dass wir ziemlich spontan das stehen und liegen lassen müssen, was wir gerade eigentlich tun wollten – und das obwohl wir uns eigentlich gar nicht wohl dabei fühlen, die Projekte unser Bestandskunden nach hinten zu schieben, um uns um die Akquise neuer Kunden zu kümmern. Doch zurück zur Kostenfrage: Bei der letzten Ausschreibung, an der wir teilgenommen haben (und bei der wir als Zweitplatzierte ausgeschieden sind) haben wir ca. 15000 Euro in unsere Teilnahme gesteckt, wenn man den Verdienstausfall eins zu eins umrechnet. Betrachtet man hingegen die Akquisekosten unserer „normalen“ Kundenanfragen, so liegen diese i. d. R. deutlich unter diesem Wert. Bei einem unserer letzten Neukunden lagen die Akquisekosten beispielsweise bei ca. 3000 Euro (auch hier wieder der umgerechnete Verdienstausfall). Man kann hier anmerken, dass Ausschreibungen mit der Zeit insofern günstiger werden, als dass sich einige der erstellten Unterlagen (z. B. Mitarbeiterprofile) wiederverwenden lassen. Insgesamt bleibt aber bestehen, dass die Teilnahme an einer Ausschreibung deutlich zeitaufwändiger als eine ausschreibungsunabhängige Neukundengewinnung ist.

3. Wir glauben nicht, dass man auf Basis einer Ausschreibung ein seriöses Angebot abgeben kann

Wie soll das auch funktionieren, wenn man nicht miteinander sprechen kann? Wir haben in letzter Zeit einige gute Ausschreibungen mit wirklich detaillierten Anforderungen gesehen, aber auch hier ergeben sich einfach noch unglaublich viele Fragezeichen. Ohne zu wissen, welches Feature dem Kunden besonders am Herzen liegt, bei welchen Features die simpelste und preisgünstigste Lösung vollkommen ausreichend ist und vor allem auch ohne einen Einblick in die Datenstruktur zu bekommen, die später verwaltet werden soll, kann man ein Angebot eigentlich nur würfeln. 

4. Wir finden Geiz nicht geil

Die Unterlagen, die eine Agentur bei einem Ausschreibungswettbewerb einreicht, werden letzten Endes anhand eines Punkteschemas bewertet. Der Preis spielt bei der Bewertung natürlich eine ausschlaggebende Rolle. Wir glauben, dass jede teilnehmende Agentur in ihren Bewerbungsunterlagen versprechen wird, alle geforderten Features umzusetzen (sonst würde sie ja Punkte verlieren) und dann versucht, darunter einen möglichst kleinen Preis zu setzen. Wir denken aber, dass der Kunde letzten Endes nicht glücklich werden wird, wenn man jedes Feature mit der am billigsten denkbaren Variante kalkuliert. Wir als Agentur können es nicht mit unserem Gewissen vereinbaren, ein Angebot auf Basis von „möglichst schnell und möglichst billig“ zu erstellen. Wir schätzen die Gefahr, dass bei Ausschreibungen der Kampfpreis gewinnt, als relativ hoch ein. Und es gibt hier noch einen weiteren Aspekt, der es uns als Agentur sehr schwer macht, einen niedrigen Preis anzubieten: Da wir nicht jede Ausschreibung gewinnen können, müssten wir die angefallenen Kosten einer verlorenen Ausschreibung eigentlich auf den Angebotspreis der nächsten aufschlagen. Ein Kunde, der via Ausschreibung nach einer Agentur sucht, wählt das für uns teuerste System. Die angefallenen Kosten verlorener Ausschreibungen müssten wir also genau den Kunden in Rechnung stellen, die dieses System nutzen, um unsere eigene Wirtschaftlichkeit zu gewährleisten – wodurch die Angebote entsprechend teurer ausfallen müssten. 

5. Wir arbeiten nicht mit Festpreis

In der Branche ist hinlänglich bekannt, dass sich die Aufwände eines Projekts nur sehr grob abschätzen lassen und Anforderungen sich außerdem im Prozess stetig ändern (Stichwort: agil). Genau aus diesen Gründen arbeiten wir selbst bei unseren Schätzungen mit T-Shirt-Größen und weigern uns, wo es nur irgendwie geht, mit Festpreisen zu agieren. Die Erfahrung zeigt, dass Features immer mal wieder größer werden, als ursprünglich geschätzt, zum Beispiel weil sich die Anforderungen im laufenden Projekt ändern. Wenn wir einen Festpreis anbieten wollen, müssen wir eigentlich einen ordentlichen „Gefahren-Puffer“ einplanen. Und das umso mehr bei einer Ausschreibung, bei der sich die genauen Anforderungen im Vorfeld nur erahnen lassen (siehe Punkt 3). Ein Festpreis mit ordentlichem Puffer wiederum steht im direkten Widerspruch zur Nennung eines möglichst geringen Preises (siehe Punkt 4.)

6. Wir finden, dass Ausschreibungen Nebensächlichkeiten zu viel Gewicht einräumen

Bei unserer letzten Ausschreibung hat uns (unter anderem) der Teilaspekt „Wiederherstellungszeiten“ bei auftretenden Mängeln einen Punktabzug beschert. Dabei sind wir während unserer Geschäftszeiten von Montag bis Freitag telefonisch erreichbar, sichten laufend unseren zentralen E-Mail-Eingang und stehen bei Bedarf auch über unsere Geschäftszeiten hinaus über eine Notfallnummer zur Verfügung. Wenn wirklich einmal etwas brennt, haben wir noch immer sofort alles stehen und liegen gelassen und uns mit Hochdruck um das Problem gekümmert. Wie lange es im Einzelfall dauert, auf ein Problem zu reagieren und es zu lösen, lässt sich natürlich nur schwer vorhersagen und ist sicherlich anhängig vom Zeitpunkt der Kontaktaufnahme, davon wie kritisch eine schnelle Behebung auf Kundenseite ist und letztlich natürlich von der Komplexität des Problems. Somit ist es insgesamt gar nicht so leicht, sich hier auf bestimmte Werte festzulegen, die man kommunizieren kann. Letzten Endes hat jedenfalls eine andere Agentur im Punkt „Wiederherstellungszeiten“ durch ihre Angaben einen besseren Punktwert erzielt als wir. Unsere These: Um hier zu gewinnen, muss man nicht nur mit Kampfpreisen, sondern im Zweifelsfall eben auch mit Kampf-Reaktionszeiten bzw. -Wiederherstellungszeiten argumentieren. 

7. Wir wollen unsere Dienstleistungen nicht verschenken

Dass Ausschreibungen per se ein kostspieliges Unterfangen sind, haben wir bereits ausführlich dargestellt. Noch problematischer wird dies, wenn man für einen Ausschreibungswettbewerb einen Designvorschlag erstellt. Ein gutes Design braucht nun einmal seine Zeit, ein möglichst tiefgehendes Verständnis des Projekts und der Vorstellungen und Wünsche des Kunden. In der Realität zeigt sich: Selbst wenn eine Ausschreibung nicht explizit einen Designvorschlag einfordert, scheinen Agenturen, die „einfach mal eins mitschicken“, die Nase vorn zu haben gegenüber Agenturen, die darauf verzichten. Menschlich ist das sicherlich nachvollziehbar. Dennoch halten wir nichts davon, ein Design zu entwerfen, ohne dass wir dafür entlohnt werden. Immerhin gehört die Entwicklung eines Designs zu unseren Kerndienstleistungen und spielt damit auf einer ganz anderen Ebene, als das Erstellen von Mitarbeiterprofilen oder die Auflistung von Referenzprojekten. Wir finden: Gute Arbeit und Qualität darf auch ihren Preis haben.

Abschließend lässt sich sagen, dass wir uns natürlich darüber freuen, wenn wir auf eine Ausschreibung aufmerksam gemacht werden. Dennoch bleibt für uns als Fazit bestehen, dass wir auch zukünftig nur in seltenen Ausnahmefällen teilnehmen werden. Durch die anfallenden Kosten, den aus unserer Sicht ineffizienten Prozess und die mit einer Ausschreibung verbundenen Risiken für unsere Agentur werden wir vermutlich auch dann wieder Bauschmerzen dabei haben. 

]]>
Wed, 15 Aug 2018 13:06:19 +0200 https://www.webfactory.de/blog/warum-wir-ungerne-an-ausschreibungen-teilnehmen https://www.webfactory.de/blog/warum-wir-ungerne-an-ausschreibungen-teilnehmen webfactory GmbH webfactory GmbH 0
enterJS Darmstadt 2018 - Eine Zusammenfassung weiterer Talks Übersicht

Battle of the Frameworks

Lora Vardarova, Zalando GmbH

Von Angular, React und Vue hat jeder, der sich für Javascript interessiert, zumindest schon einmal gehört – doch gerade, wer am Anfang seiner Karriere als JavaScript-Entwickler steht, fragt sich vermutlich: für welches dieser Frameworks, die alle mehr oder minder den gleichen Zweck erfüllen, sollte man sich entscheiden? Welches Framework ist das beste?

Überblick

Der Vortrag beginnt nach einer kurzen Einführung mit einer Geschichtsstunde, die Aufschluss über die Entstehung der heutigen Framework-Landschaft bietet und unter anderem aufzeigt, warum Angular nicht Angular.js ist.

Beim Vergleich der Features stellt sich heraus, dass sich alle drei behandelten Frameworks sehr ähnlich sind, und über unterschiedliche Konzepte nahezu dieselben Features umsetzen.

Entscheidungsfindung

Die Erfahrungen bei Zalando haben in den letzten Jahren verschiedene Wege und Irrwege aufgetan, wie die Entscheidung für ein Framework angegangen werden kann.

Dabei hat sich unter anderem herausgestellt, dass die beliebte Methode, mit allen infragekommenden Frameworks eine To-Do-App zu implementieren, in der Regel für eine qualifizierte Entscheidung nicht ausreicht, da eine To-Do-App schlicht zu simpel ist um die Stärken und Schwächen des Frameworks zu erfahren. Stattdessen empfiehlt Vardarova die Implementiertung einer progressive Web App, die als Reader-Client für die Hackernews von YCombinator fungiert.

Außerdem zeige die Erfahrung, dass zu den wichtigsten Faktoren die Community und die Dokumentation zählen.

Projektleiter und Teams können sich am Bus-Faktor orientieren: Wenn der Hauptentwickler des Projekts vom Bus überfahren wird, wie schnell kann ein guter Ersatz gefunden werden?

Die Entscheidung, welches Framework eingesetzt wird, treffen die Zalando-Entwickler pro Projekt, denn jedes Projekt hat seine eigene Roadmap und eigene Bedürfnisse, die in der Entscheidung berücksichtigt werden sollten. Dennoch sei es wichtig, sich eine Deadline zu setzen, da sonst die „decision trap“ zuschlage und die Entscheidung wichtige Entwicklungszeit koste.

And the winner is...

Die Frage, welches Framework das beste ist, wird explizit nicht beantwortet, sondern durch eine andere Fragestellung ersetzt: Welches Framework ist das passendste für mein Projekt?

Mir als Neuling in der JavaScript-Welt, der sich noch nicht auf ein Framework festgelegt hat, hat dieser Vortrag aufgezeigt, dass ich das eventuell gar nicht muss. Es war beruhigend, festzustellen, dass man selbst nach Festlegung auf ein Framework keine technologischen Sensationen verpasst, da alle Frameworks alle populären Features auf verschiedene Weisen umsetzen.

JavaScript-Security: Webbrowser in Gefahr

Joshua Tiago, Cirosec

Cross-Site-Scripting(XSS)-Lücken sind die am weitesten verbreiteten, aber gleichzeitig auch die am trivialsten auszunutzenden Sicherheitslücken im Internet. Da das nicht die beste Kombination für ein sicheres Internet ist, leistet Tiago mit diesem Vortrag seinen Beitrag im Kampf gegen die Sicherheitslücke, über die jeder bereits alles zu wissen glaubt.

Cross-Site-Scripting

Nach einer Zusammenfassung über die Relevanz von Cross-Site-Scripting stellt frischt Tiago er noch einmal die Grundlagen auf:

Der Angreifer schleust fremden Code in eine Webanwendung (z. B. durch einen manipulierten Link zu einer Website, die URL-Variablen ungeprüft im Seitentext ausgibt oder einen javscripthaltigen Forenbeitrag), die dann in einem fremden Browser ausgeführt wird.

Die Voraussetzungen, eine XSS-Lücke auszunutzen, sind allgemein, dass eine Anwendung Eingaben entgegennimmt und später wieder ausgibt, und dabei weder bei der Eingabe, noch bei der Ausgabe Steuerzeichen filtert (keine Eingabefilterung und keine Ausgabekodierung). Die typischen Fälle von Ein- und Ausgaben sind dabei Suchfelder, Online-Formulare und Gästebücher bzw. Foren, aber auch auf weniger offensichtliche Ein-/Ausgabemöglichkeiten wie der Header der HTTP-Anfrage sowie der Inhalt hochgeladener Dateien müssen unbedingt beachtet werden, wenn eine Anfälligkeit für Cross-Site-Scripting vermieden werden soll.

Eingabefilterung und Ausgabekodierung illustriert der Vortrag an zahlreichen Beispielen: So codiert Wikipedia die Ausgabe von Sucheingaben, was die Interpretation von JavaScript-Code darin durch den Browser verhindert.

Persistentes und nicht-persistentes Cross-Site-Scripting

Bei nicht-persistenten XSS-Angriffen (reflected XSS) bringt der Anwender einen Nutzer dazu, die Webanwendung auf eine bestimmte Art und Weise zu benutzen, damit der Schadcode ausgeführt wird. Dafür lässt er den Nutzer beispielsweise einen bestimmten Link anklicken, der eine Eingabe mit Code enthält, die später in der Oberfläche der Anwendung ausgegeben wird. Diese Art von Angriff verändert die Webanwendung selbst nicht und funktioniert nur, wenn der Nutzer die Seite auf die vom Angreifer geplante Art nutzt. Der Nutzer schickt den Schadcode dabei selbst in seiner Anfrage mit.

Persistente XSS-Angriffe (stored XSS) hingegen betten sich im Backend der Anwendung ein und funktionieren auch bei ganz normalen Seitenaufrufen. Sie sind danach dauerhaft in der Anwendung enthalten und betreffen alle Seitenbesucher. Ermöglicht werden solche Angriffe z. B. durch Foren oder Gästebücher.

DOM-basiertes Coss-Site-Scripting

DOM-basiertes XSS ist eine Form des Cross-Site-Scriptings, bei welcher der Schadcode nicht über den Server übertragen wird, sondern der gesamte Angriff im Browser-DOM des Nutzers stattfindet. Dadurch können serverseitige Schutzmechanismen und Filter nicht schützen. Möglich wird DOM-basiertes XSS unter anderem durch Teile der URL, die nicht an den Server geschickt werden (alles nach einem #) und die Verwendung unsicherer JavaScript-Funktionen. Wenn Daten ungeprüft von Objekten wie

  • document.location

  • document.URL

  • document.referrer

übernommen werden, und von den Funktionen

  • document.write

  • document.writeln

verarbeitet werden, ist DOM-basiertes XSS möglich.

Das führt Tiago an einem Beispiel vor, in dem er einen Namen als URL-Parameter entgegennimmt und auf der Seite ausgibt. Ersetzt er den Namen in der URL durch JavaScript-Code, kann er die Seite dazu bringen, ein JavaScript-Alert-Fenster mit der Message „HACKED!!!“ auszugeben.

Um DOM-basiertes XSS zu verhindern, müssen Ausgaben also auch clientseitig codiert werden. Möglich ist das z. B. durch die Bibliothek OWASP ESAPI, die dafür zwei einfache Funktionen zur Verfügung stellt:

$ESAPI.encoder().encodeForHTML( myinput );

$ESAPI.encoder().encodeForJavaScript( myinput );

Neue Techniken, neue Angriffsmöglichkeiten

Die zahlreichen Techniken, die HTML5 mit sich brachte, machten nicht nur das Web schöner und flexibler, sondern auch die Angriffsmöglichkeiten. Diese Features ermöglichen unter anderem den Aufbau von Botnetzen, das persistieren von Schadcode auf dem Client und Angriffe auf die Privatsphäre der Nutzer.

Persistieren von Schadcode

Das Persistieren von Schadcode auf dem Client ist dabei mit allen vorgestellten XSS-Arten möglich (persistent, reflected und DOM-based XSS). Während der Schadcode beim persistent XSS ohnehin schon auf dem Server persistiert ist, kann er bei den anderen XSS-Arten im Application Cache bzw. im Local Storage des Nutzers gespeichert werden. Das macht die Erkennung durch den Server schwer bis unmöglich.

Um den persistenten Code loszuwerden, müssen Web-Cache und Web-Storage komplett gelöscht werden. Der Browser kann danach allerdings sofort wieder infiziert werden, wenn der Schadcode noch in einem anderen Tab oder Fenster läuft.

Der Aufbau von Botnetzen

JavaScript kann Requests aller Art senden, und wenn das JavaScript persistiert ist, lassen sich damit sehr leicht Botnetze aufbauen. Das liegt unter anderem daran, dass inzwischen einige Botnetzframeworks entstanden sind – vergleichbar mit den bekannten App-Frameworks fürs Frontend. Nur eben für Botnetze. Tiago stellt als Beispiel BeEF vor, das eine übersichtliche Weboberfläche zum Dirigieren verschiedenster Botnetz-Funktionen bietet.

SVG-Grafiken

SVG-Grafiken können ebenfalls JavaScript-Code enthalten. Wenn sie über den <svg>-Tag eingebunden sind, wird dieser einfach ausgeführt. Deswegen sollte man zum Einbinden von Grafiken immer den <img>-Tag benutzen – dieser führt keinen Code aus.

Schutzmaßnahmen

Als Schutzmaßnahme schlägt Tiago Content Security Policies vor. Diese können im Webserver konfiguriert werden.

Da XSS-Angriffe meistens über Inline-Skripte in den Ausgaben von Webanwendungen funktionieren, können Content Security Policies grundsätzlich jegliche inline-Skripte verbieten. Darüber hinaus ist es möglich, das Einbinden von Skripten, Grafiken und Videos nur aus bestimmten Quellen zu erlauben. Auch XMLHttpRequests und andere Requests können durch Content Security Policies eingeschränkt werden.

Level-2-Content-Securitiy-Policies können Skripte sogar mittels eines Hashs absichern, der verifiziert, dass das Skript echt ist. Alternativ zum Hash kann, sofern das Skript vom selben Server wie die Webapplikation ausgeliefert wird, ein vom Server generierter Zufalls-Wert, der sogenannte Nonce, das Skript absichern. Dieser wird vom Server sowohl im Skript, als auch im Script-Tag eingefügt und kann von einem Angreifer nicht vorhergesagt werden.

Content Security Policies werden von allen verbreiteten Browsern akzeptiert und sollten daher eingesetzt werden.

JavaScript-Security Top 3

Zum Abschluss stellt Tiago die drei wichtigsten Punkte dar, die JavaScript-Entwickler aus seiner Sicht zum Thema beachten sollten:

  1. Der Client/Browser ist immer als unsicher zu betrachten – es ist immer davon auszugehen, dass er bereits kompromittiert wurde, weswegen alle kritischen Funktionen serverseitig validiert werden müssen

  2. XSS ist mit allen Maßnahmen um jeden Preis zu verhindern: Eingaben müssen immer validiert, Ausgaben kodiert, Content Security Policy aktiviert werden

  3. JavaScript-Bibliotheken müssen immer aktuell gehalten werden

Wertvolles Wissen über Sicherheit – JavaScript-unabhängig

Das Thema XSS-Sicherheitslücken kommt immer wieder auf, ich kannte das Prinzip und wählte diesen Vortrag nur „zur Sicherheit“, um als angehender JavaScript-Entwickler alles richtig zu machen. Dass das Thema so groß ist, welche Techniken alles zweckentfremdet werden können und dass es gar Frameworks gibt, um über XSS Botnetze aufzubauen, hätte ich hingegen nicht gedacht, weswegen ich sehr dankbar bin, diesen Vortrag gehört haben zu können. Das Wissen über die unterschiedlichen Angriffsszenarien wird mir unter allen Programmiersprachen und auch in der Backend-Entwicklung zugute kommen und mir helfen, sicherere Anwendungen zu entwickeln – ich hoffe, den anderen Hörern des Vortrags und den Lesern dieses Blogbeitrags geht es genauso.

Vue.js on Steroids

Christian Hunger und David Müller, eXXcellent

Vue.js gehört zu den beliebtesten drei JavaScript-Fameworks, was sich unter anderem auch in der Anzahl an Vorträgen auf der enterJS zu dem Thema widerspiegelt. In der Praxis wird vue.js allerdings selten alleine eingesetzt – vue.js on Steroids bietet am Beispiel eines fiktiven Supplements-Stores für Web-Developer Überblick über ein vue.js-Ökosystem mit den „Steroids“ nuxt.js, Vuetify, Vue-rx, Vuex und Jest.

Die Entwicklertools

Als Entwicklertools werden das Vue.js-CLI und das Devtools-Plugin für Browser vorgestellt. Beide werden am Beispiel des Supplement-Stores vorgeführt.

So erstellen die Vortragenden das Projekt über das CLI mit dem Nuxt&Vuetify-Template. Ohne Template erstellt das CLI über den Befehl vue create app eine nackte vue-App, das Template hingegen erstellt eine wesentlich umfangreichere Ordnerstruktur, die für die Verwendung mit vuetify.js und nuxt.js ausgelegt ist.

Die Devtools erweitern die Chrome-Entwicklertools um einen Vue-Tab, der tiefe Eingriffe in den Status der vue-Anwendung erlaubt wie das zurücksetzen von Mutations. Mutations sind Commits von States, die den jeweiligen Status der Anwendung repräsentieren, ein System, das von Vuex bereitgestellt wird.

State-Managment mit Vuex

Das State-Managment-Framework Vuex wird auch gleich als nächstes Steroid vorsgetellt. Wer Redux kennt, wird sich hier gleich zuhause fühlen, denn Vuex implementiert genau wie dieses das Flux-Pattern.

Ein State-Managment-Framework bietet allen Komponenten die Möglichkeit, ihren State an einer zentralen Stelle, dem sogenannten Store, zu verändern, und stellt somit einen zentralen Punkt für den Zustand der gesamten Anwendung bereit.

Das verändern des States findet über sogenannte Actions statt. Diese definieren eine Veränderung, ohne diese aber durchzuführen. Dadurch können sie auch asynchrone Abläufe beschreiben. Die tatsächlichen Veränderungen am State hingegen werden über Mutations durchgeführt.

Um auf den Store zuzugreifen, stellt Vuex Getter bereit. Diese bereiten Daten z. B. für die GUI auf und bieten eine logische Sicht auf den Store. Im Zusammenspiel mit Computed Properties lassen sich Getter einfach in eine UI-Komponente einhängen.

Nuxt: Server-Side-Rendering und mehr

Nuxt.js ermöglicht Prerendering, Server Side Rendering und vereinfacht das Routing. Vuex wird durch Nuxt bereits mitgebracht. Nuxt lässt sich in drei Production Modes betreiben:

Single Page Application

Die Single Page Application ist eine ganz normale Single Page Application, die clientseitiges Routing umsetzt und Inhalte per API-Aufruf vom Server nachlädt.

SPA mit Server Side Rendering

Beim Server Side Rendering wird das JavaScript und die Dom-Manipulation bereits vom Server ausgeführt, damit das fertig gerenderte HTML an den Client verschickt werden kann. Auch der Vuex-Store wird bereits vom Server gefüllt und an den Client übertragen. Das Nachladen von Inhalten entfällt, dadurch kann die Seite schneller geladen werden und ist außerdem suchmaschinenfreundlicher (wichtig für SEO). Außerdem ist zumindest beim ersten Seitenaufruf kein JavaScript auf dem Client notwendig.

Prerendered SPA

Statische Seiten kann man sich auch prerendern lassen – wer bspw. einen Blog betreibt, muss die Inhalte nicht bei jedem Seitenaufruf vom Server rendern lassen, sondern kann mit nuxt generate statisches HTML für jede Route generieren. Daher wird dieser Modus im Vortrag auch „Server Side Rendering Light“ genannt.

Alle Dinge, die Nuxt kann, lassen sich auch mit reinem vue.js umsetzen – Nuxt vereinfacht die Dinge aber.

Vue-rx

Vue-rx ist eine Umsetzung von ReactiveX für vue. ReactiveX bietet verbesserte Promises, die komlexe asynchrone Abläufe modellieren können, und versucht dabei das beste aus dem Observer-Pattern, dem Iterator-Pattern und funktionalem Programmieren zu vereinen.

Wer komplexe DOM-Events, Websockets oder Animationen umsetzen will, und wem Promises nicht ausreichen, sollte sich auf jeden Fall einmal mit dem ReactiveX-Konzept befassen.

Schnell UIs zaubern mit Komponentenbibliotheken

Slider, Text-Inputs, Buttons – die meisten GUIs bestehen seit der ersten Smalltalk-Entwicklungsumgebung aus denselben Elementen. Nur dass diese heutzutage geräteübergreifend funktionieren und sowohl mit Maus- als auch Touch-Eingaben zurechtkommen müssen.

Um diese Standard-Komponenten nicht jedes Mal neu schreiben zu müssen, empfiehlt sich der Einsatz von Komponentenbibliotheken – diese bieten einem sämtliche GUI-Elemente, von Slideshows, Tabellen, Radiobuttons bishin zu ganzen Dialogen und Bestellabläufen als Komponenten an.

Wer vor hat, mit vue.js eine Webanwendung zu bauen, sollte sich auf jeden Fall die beiden vorgestellten Komponentenbibliotheken, Vuetify und Buefy, anschauen.

Jest

Unabhängig von Vue.js ist es immer wichtig, Tests zu schreiben – auch für Frontender. Daher wird als letztes Steroid mit Jest das führende JavaScript-Testing-Framework vorgestellt. Jest rühmt sich damit, weitestgehend ohne Konfiguration zu funktionieren. Über die expect-Funktion, die das zu erwartende Test-Ergebnis definieren lässt, kann man so ohne große Lernkurve alle möglichen Arten von Tests schreiben.

Viel zu lernen du noch hast

Dieser Vortrag hat mir wieder einmal gezeigt, wie viel größer als ich dachte die JavaScript-Welt doch ist, und welches Potential in JavaScript-Frameworks steckt. Die meisten der vorgestellten Steroide sind so oder in ähnlicher Form nicht nur für Vue.js verfügbar, von daher werde ich mich auch in der Entwicklung mit anderen Frameworks mit interessanten Konzepten wie State-Managment oder ReactiveX beschäftigen.

JavaScript-Essentials: Die Engine

Rainer Hahnekamp

JavaScript wird zur Laufzeit ausgeführt, und wie jede zur Laufzeit ausgeführte Sprache braucht sie eine Engine. Zu wissen, wie die Engine funktioniert, ist Macht, denn nur so kann man effektiv seinen Code optimieren. Mit viel Live-Coding zeigt Hahnekamp, wie man die Engine für seine Zwecke nutzt.

JavaScript, die lahme Ente

JavaScript eilt ein Ruf voraus. Dieser setzt die Programmiersprache nicht unbedingt mit schnellen Ausführungsgeschwindigkeiten in Verbindung. Inzwischen setzen aber ganze Industriezweige auf die Entwicklung mit JavaScript, mit Node.js gibt es sogar einen als schnell geltenden JavaScript-Server, JavaScript läuft auf embedded devices. Benchmarks zeigen, dass JavaScript die Konkurrenz unter Umständen abhängt. Doch die Erfahrungen jedes passionierten Internetnutzers können bezeugen, dass es noch heute langsamen JavaScript-Code gibt, und wie kann JavaScript überhaupt schnell sein, wenn es doch zur Laufzeit interpretiert wird?

Hahnekamp schreibt ein Programm, das für vier verschiedene Star-Wars-Charaktere Objekte erzeugt, in denen jeweils der Name gespeichert ist. Um die Geschwindigkeit zu messen, iteriert er mehrere zehntausend Mal über die Objekte. Es dauert etwas mehr als zwei Sekunden. Fügt er jedoch einem Objekt eine Eigenschaft hinzu, die die anderen nicht besitzen, dauert das Iterieren über sieben Sekunden – wenn noch mehr Eigenschaften, wie Beruf (nur für Han Solo), Nachname (bei Yoda nicht bekannt) hinzugefügt werden, steigt die Zeit auf knapp 10 Sekunden an.

Optimierte Ausführung mit aktuellen Engines

Um dieses Phänomen zu erklären, führt Hahnekamp in die Geschichte von JavaScript ein: Früher war JavaScript nämlich wirklich sehr lahm und nur für einfach Funktionen in Websites gedacht. Erst mit Googles V8-Engine im Jahr 2008 wurde das Ausführen von JavaScript so weit optimiert, dass damit komplexe Webanwendungen möglich waren.

Dafür werden Teile des Codes vor der Ausführung im Hintergrund vorkompiliert. Gleichzeitig wird der schwach typisierte JavaScript-Code vor der Ausführung intern hart typisiert. Dafür erkennt die Engine in jedem Objekt ein Object Shape und teilt ihm eine Hidden Class zu. Wenn also mehrere Objekte dieselben Properties in der selben Reihenfolge besitzen, erstellt die Engine dafür heimlich eine Hidden Class. Dadurch weiß sie bei Iterationen direkt, wo die Properties im Speicher liegen und muss nicht immer erst die Speicheradresse ausrechnen.

Zurück zum Live-Coding-Beispiel

Hahnekamp ergänzt seine Star-Wars-Charaktere um die fehlenden Properties der anderen, und füllt diese einfach mit null auf. Die Iterationen dauern trotz gestiegener Anzahl der Properties keine drei Sekunden. Wer also gut aufpasst, kann durch das entsprechende Setzen von Properties ordentlich die Performance optimieren. Die gleichen Regeln gelten auch für Sprachen wie TypeScript, wie Hahnekamp referiert, da TypeScript später auch von der selben Engine ausgeführt wird – in den meisten Fällen sollte die Optimierung hier aber ohnehin greifen, da TypeScript eine harte Typisierung erzwingt.

Smarte Engines erfordern smarte Coder

Ich persönlich bin kein Freund davon, wenn eine Programmiersprache so smart ist, dass der Programmierer mindestens genau so smart sein muss, um zu verstehen, was sein Code eigentlich genau macht. Da JavaScript im Web aber einfach alternativlos ist, bin ich sehr froh, nun zu wissen, wie heutige Engines Objektzugriffe optimieren, da Perfomance gerade im Web mit seinen unterschiedlichen Endgeräten von entscheidender Bedeutung ist. Vor allem bin ich auch glücklich über die ansprechende Gestaltung des Talks mit den anschaulichen Live-Coding-Beispielen.

Aurelia – mehr Standards, weniger Framework

Katharina Bähr, Zühlke GmbH

Während es in den meisten Talks nur um die drei großen Frameworks Angular, React und Vue.js kreisen, hat sich Katharina Bähr mit ihrem Entwickler-Team für das Aurelia-Framework entschieden, das sich durch Konformität mit den allgemeinen Standards von JavaScript und TypeScript auszeichnet.

Todo-App

Todo-Apps sind nach Cookie-Hinweisen vermutlich der zweithäufigste Verwendungszweck von JavaScript. Daher bietet sich das Schreiben einer Todo-App als Einstieg in ein Framework ziemlich gut an.

Bähr führt mit einer gut abgestimmten Mischung aus Live-Coding und vorbereiteten Git-Commits durch die Todo-App. Aurelia fällt dabei vor allem dadurch auf, dass man es nicht bemerkt – der entstehende TypeScript-Code enthält kaum Hinweise darauf, dass ein Framework genutzt wird. Lediglich die Klasse main.ts implementiert eine configure-Funktion, der ein Aurelia-Objekt injiziert wird.

Generell ist der Konfigurationsaufwand bei Aurelia aber sehr klein, weil das Framework konventionenbasiert funktioniert. Wenn man sich an das vorgegebene Namensschema hält (das bei Bedarf natürlich konfigurierbar ist), wirkt das Projekt wie reiner TypeScript-Code. Wenn man bereits selbiges oder ES Next beherrscht, sollte Aurelia einen sehr einfachen Einstieg ermöglichen, da nicht viel gelernt werden muss.

Alle Features vorhanden

Aurelia kann trotzdem so ziemlich alles, was die bekannteren Konkurrenten können – Bähr selbst entwickelte bei Zühlke zunächst mit Angular.js, vor Erscheinen von Angular2 entschied sich das dortige Entwicklerteam aber für den Umstieg auf Aurelia. Inzwischen entwickelt sie Web-Apps nahezu ausschließlich mit Aurelia und ist von dem Framework sichtlich begeistert.

Die Community sei zwar nicht so groß, aber mindestens genauso hilfreich wie bei Angular. Das Projekt sei gut dokumentiert, die Erweiterungen zwar nicht so zahlreich, aber dafür umso häufiger vom Aurelia-Team selbst, was sich in Qualität, Dokumentation und Support positiv niederschlage.

Aurelia wird nicht von einem großen Internet-Konzern wie Google oder Facebook entwickelt. Statt dessen verdient Bluespire, das Unternehmen, das Aurelia ins Leben gerufen hat, sein Geld mit Support-Leistungen rund um das Framework. Dadurch hängt laut Bähr das wirtschaftliche Interesse stärker von den Bedürfnissen aller Nutzer ab, während die Entwicklung der anderen Frameworks von der Bedeutung dieser für die Technik-Plattformen der entwickelnden Unternehmen abhinge.

Aurelia ist freundlich

Die vorgestellten Eigenschaften des Aurelia-Frameworks gefallen mir sehr. Das Prinzip Convention over Configuartion kenne ich durch meinen Backend-Hintergrund aus der Entwicklung mit dem PHP-Framework Symfony, wo es den Code stark vereinfacht und gut strukturiert. Vor allem das Einsteigen in ein neues, unbekanntes Projekt wird meiner Erfahrung nach durch gute Konventionen stark vereinfacht und löst viele Probleme beim Verständnis des Codes.

Bähr stellt Aurelia dabei so überzeugend und sympathisch dar, dass ich direkt am nächsten Tag anfing, meine erste Aurelia-App zu schreiben. Dabei musste ich kaum etwas über Aurelia lernen, für mich war das eher ein TypeScript-Tutorial.

Auch Symfony wird durch ein Unternehmen entwickelt, das wirtschaftlich vor allem von Support und Schulung rund um ebendieses abhängt. Bei Symfony hat dieser Umstand zu einer sehr entwicklerfreundlichen Frameworkentwicklung geführt, was es mir plausibel erscheinen lässt, dass sich Bluespire ähnlich gut um die Belange der Entwickler kümmert.

Ein gewisses Kümmern um die Entwickler zeigt sich auch in der Öffentlichkeitsarbeit von Bluespire: nach dem Vortrag erfuhr ich im Gespräch mit Bähr von einem Paket mit Aurelia-Stickern, die das Aurelia-Team ihr zuschickte, nachdem sie auf ihren Blog gestoßen sind, der sich u. a. mit der Aurelia-Entwicklung beschäftigt.

Ich werde mir Aurelia weiter anschauen, und kann jedem, der auf der Suche nach dem richtigen Framework für sich ist oder einfach ein neues Framework ausprobieren möchte empfehlen, das gleiche zu tun.

Die enterJS als Perspektivwandel

Für mich als Backend-Entwickler war JavaScript immer nur das Zeug, das die aus dem Backend kommenden Websites schick animiert und langsam macht. Meine Perspektive auf JavaScript und clientseitige Programmierung als solche hat sich durch die enterJS massiv verändert, nachdem ich sehen konnte, wie viel damit wie ansprechend und performant umgesetzt werden konnte. Ich bedanke mich bei allen Vortragenden, den Organisatoren und bei meinem Kollegen Konstantin Tieber, der mir den Anstoß gab, mit auf die enterJS zu kommen.

]]>
Sun, 08 Jul 2018 08:42:10 +0200 https://www.webfactory.de/blog/enterjs-2018-nochmehr-talks https://www.webfactory.de/blog/enterjs-2018-nochmehr-talks webfactory GmbH webfactory GmbH 0
Für zukünftige Azubis: meine Projektpräsentation als Fachinformatiker bei der IHK Abschlussprüfung Es ist übrigens immer gut, wenn ihr Köder in eurer Präsentation auslegt, auf welche die Prüfer dann im Fachgespräch eingehen. Ich war besonders überrascht, als mich einer der IHK-Prüfer sogar über Containervirtualisierung mit Docker befragt hat, was mein Vorurteil, dass in der IHK-Prüfung nur ältere Technologien thematisiert werden, widerlegt hat. So konnte ich mein breites Wissen aus dem Bonner Microservices Meetup aus dem Ärmel ziehen.

Wenn ihr noch weitere Fragen zur Abschlussprüfung für den Beruf Fachinformatiker Anwendungsentwicklung habt, dann schreibt einfach eine Mail an info@webfactory.de oder tweetet an @xkons64 und ich werde meine Antworten gerne hier im Blog ergänzen.

Hier gibts meine Slides und mein Skript zum Download:

Slides

Skript

Quellcode

]]>
Thu, 05 Jul 2018 18:25:19 +0200 https://www.webfactory.de/blog/ihk-projektpraesentation-fachinformatiker-anwendungsentwicklung https://www.webfactory.de/blog/ihk-projektpraesentation-fachinformatiker-anwendungsentwicklung webfactory GmbH webfactory GmbH 0
enterJS Darmstadt 2018 - Eine Zusammenfassung ausgewählter Talks Übersicht

Micro Frontends: JavaScript Integration Patterns

von Nils Hartmann und Oliver Zeigermann

Nils und Oliver sind Serien-Speaker auf der enterJS. Sie beginnen den Talk mit der Behauptung, dass es genau drei Arten von Anwendungen gibt, die die bestmögliche Benutzererfahrung bieten:

Single-Page-Applications (SPA), mobile Apps und Desktop Apps. Auf die Frage, ob jemand aus dem Publikum nicht zustimmen würde, bleibt der Saal still.

Sie stellen drei Methoden/Architekturen für die Verbindung von Komponenten/Modulen im Frontend vor:

  1. HTML-Links

  2. Majestic Modular Monoliths

  3. Micro Components

Zu 1. HTML-Links

Die Benutzer navigieren über echte HTML-Links zwischen Seiten. Dabei ist jede Seite eine eigene SPA und sie teilen untereinander keinen State.

Diese Architektur ist besonders für Entwickler sehr bequem, da die Module der einzelnen Teams komplett unabhängig voneinander sind. Leider ist das auch der Katalysator für eine inkonsistente und schlechte Benutzererfahrung.

Als Beispiel für diese Architektur nannten Hartmann und Zeigermann Outlook Web. Hier ist der Mail Client in React implementiert und auf der linken Seite befindet sich eine Navigation, um beispielsweise von Mails zum Kalender zu wechseln. Klickt man auf den Kalender, so öffnet sich eine komplett andere Webanwendung, welche auch kein React einsetzen muss. Die Navigation, um zurück zu der React-basierten Mail Anwendung zu kommen, ist dort weiterhin vorhanden, allerdings ein bisschen anders positioniert, was für ein inkonsistente Benutzeroberfläche sorgt.

Zu 2. Majestic Modular Monoliths

Bei einem Majestic Modular Monolith befinden sich mehrere Module auf einer Seite.

Bei der Entwicklung wird empfohlen, dass es pro Modul nur ein Team geben darf. Die Module können entweder in einem großen Repository, vorzugsweise getrennt durch die Ordnerstruktur, oder auch in individuellen npm Paketen verteilt werden.

Für Module, die nicht in die offen zugängliche npm-Registry veröffentlicht werden sollen, gibt es inhouse Lösungen wie nexus. Ein statischer Build setzt schließlich alle Module zu einer Anwendung zusammen.

Um für schnellere erste Interaktion zu sorgen, soll Lazy-Loading verwendet werden.

Der Nachteil an dieser Architektur ist, dass die Entwickler-Teams ihr Frontend-Framework nicht flexibel wählen können, wie beispielsweise bei HTML-Links.

Der Vorteil daran ist, dass generische Präsentationskomponenten, wie Buttons oder Listen, über die Teams hinweg geteilt werden können, um konsistentes Design zu erzielen. Auf diese Weise wird die beste Benutzererfahrung in SPAs erreicht.

Majestic Modular Monoliths brauchen fast immer zentrales State-Management mit Tools wie Redux.

Diese Architektur könnte sich beispielsweise für Google Docs eignen. Wenn sich der Cursor im Text des Dokuments in einer gefetteten Zeichenkette befindet, so muss sich auch die „Werkzeugleistenkomponente“ aktualisieren und den Button für fette Schrift grau hinterlegen.

Zu 3. Micro Components

Im Gegensatz zu MMMs werden die einzelnen Module erst zur Laufzeit miteinander verbunden.

Die Kommunikation zwischen Modulen findet über einen EventBus (Vorschlag: PostalJS) oder geteilten State statt.

Man gewinnt wieder die Freiheit bezüglich der Wahl der Frontend-Frameworks, allerdings neigen diese SPAs aus genau diesem Grund dazu, recht groß zu werden, da mehrere Frameworks eingebunden gleichzeitig verwendet werden, weshalb sie eher für Desktop Apps oder Intranets verwendet werden sollten.

Die aktuell einzige Möglichkeit, um unterschiedliche Micro Components komplett ohne Interferenzen zu integrieren, sind iframes. Alternativen sind div-Tags mit script-Tags und web components, welche aber nicht ganz frei von Nebeneffekten sind.

Ein Beispiel für eine Micro Frontend Architektur ist Spotify.

Kommentar

Bisher bin ich bei meinen React Apps, in welchen oft viele Komponenten denselben zentralen State manipulieren, auch gut mit EventHandlern über Props zurechtgekommen und habe Redux lediglich zu Testzwecken ausprobiert. Nils und Oliver haben offensichtlich schon viele Begegnungen mit komplexen Frontends gehabt und für mich war dieser Talk sehr spannend.

No-Backend Peer to Peer Progressive Web Apps

von Felix Waterstraat und Sven Vowé (spreewunder GmbH)

Use-Cases

  • offline-first Apps

  • Apps, die zu vertrauliche Daten verarbeiten, um sie über einen Cloud Service kommunizieren zu lassen

Architektur

  • Datenbank lokal im Browser mit PouchDB oder Minimongo, welche als Wrapper für IndexedDB und localStorage agieren.

  • Datenbanksicherungen im Backend bei vorhandener Internetverbindung

  • Peer to Peer Synchronisierung mit WebRTC

  • RTCDataChannel zum teilen von Anwendungsdaten unter verschiedenen Browser-Instanzen

Das spreewunder Team kapselt diese Architektur in einem Framework, welches sie „Cloudless“ getauft haben. Es scheint allerdings nicht quelloffen zu sein.

Beispiel EKG-Messung

Das Team der spreewunder GmbH hat einen EKG-Rekorder, nach einem gescheiterten Versuch mit Web USB, über Web Bluetooth an eine No-Backend PWA angebunden und empfängt davon ca. 40000 Datenpunkte pro Sekunde, was mit einer HTTP-Schnittstelle, im Vergleich zu jungen Web-APIs, noch viel größere Herausforderungen mitgebracht hätte. Kleinere Schwierigkeiten mit der Datendurchsatzrate konnten dabei durch das Deaktivieren des Bluetooth Low Energy Modus (BLE) und Verwendung von Bluetooth 5 gelöst werden.

Mit Hilfe von Vega, einem Wrapper für D3.js, werden die Live-Daten in einem Diagramm visualisiert.

Kommentar

Dieser Vortrag hat mich definitiv beeindruckt und auch inspiriert, mich noch tiefer mit PWAs auseinanderzusetzen. Besonders die „persistente“ Speicherung in IndexedDB werde ich auf die Probe stellen, nachdem ich letztes Jahr schon meine alte Kalender Web-App mit der localForage-Library offline-fähig gemacht habe.

Ich finde es schade, dass Cloudless nicht quelloffen ist, da ich durch die Code-Beispiele zur Erstellung und Verwaltung von WebRTC-Verbindungen sehr neugierig geworden bin.

Common Ways We Break Accessibility and How to Avoid Them

von Laura Carvajal @lc512k

Die erste Frage, die wir uns bei Accessbility stellen sollten ist, ob unsere Seite auch ohne eine Maus bedienbar ist.

  • gibt es focus styles?

    • niemals outline: none

    • in CSS4 kommt focus-visible für tab-spezifische Focus-Styles

  • sind alle Elemente durch „Tabben“ erreichbar und in einer sinnvollen Reihenfolge?

    • <a> Tags ohne href-Attribut werden nicht angesteuert, benötigen tabindex=0

  • gibt es Inhalte, die von einem hover-Effekt abhängen?

Speziell für Screenreader ist es wichtig, dass alle <h> Tags auf einer Seite auch dessen Hierarchie widerspiegeln. Als Beispiel wird ein Video gezeigt, in dem ein blinder Mann im Rahmen eines Accessibility-Audits des Digital Accessibility Centers versucht, per Screenreader zu der Hardware-Support Seite auf der Amazon-Hilfeseite zu gelangen, wobei Elemente, die sonst <h2>-Elemente sein sollten, nämlich Unterkategorien für Hilfe (Bestellungen, Hardware, etc.), einfache Links waren. Aus diesem Grund, dauert es für den Besucher deutlich länger, zu der gewünschten Sektion zu navigieren.

H-Tags sollten auch nie zu Styling-Zwecken eingesetzt werden, sie dienen ausschließlich zur Repräsentation der Seitenstruktur!

Auf Seiten mit Video- oder Audioinhalten sind Untertitel einzubauen, welche keine Fehler enthalten und auch gut lesbar sind.

Kommentar

Ich freue mich immer auf Talks zu Accessibility, da ich bisher jedes Mal etwas neues gelernt und ein besseres Verständnis für die verschiedenen Herausforderungen von Menschen mit Behinderungen bei der Verwendung von Websites bekomme habe.

We need to talk about Preact

von Sara Vieira @NikkitaFtw

Preact ist eine JavaScript Library, die von Jason Miller begründet wurde, während er versuchte, die Innereien von Facebooks React zu verstehen. Heute steht eine große (19200 Sterne auf GitHub) und hilfsbereite Community dahinter und es wird von zahlreichen Firmen in Produktion eingesetzt (Uber, Lyft, Financial Times).

Sara nennt einige Punkte, in denen sich Preact von React unterscheidet:

  • 4KB Gzipped vs 32KB React

  • schneidet in Rendering-Benchmarks mehr als doppelt so schnell wie React ab

  • preact-router wird im Gegensatz zu React Router vom selben Team maintained wie die Haupt-Library

  • Standard-addEventListener für Event-Handling im Gegensatz zu Synthetic Events in React

Mit dem preact-compat Paket können außerdem React-Komponenten in Preact verwendet werden. Dazu gibt es im Repository auch eine Demo. Somit schließt man sich mit der Entscheidung für Preact nicht von der großen Auswahl an existierenden React-Komponenten aus.

In Zukunft bekommt Preact sogar asynchrones DOM-Diffing.

In einer Live-Demo baut Sara mit Hilfe der preact-cli eine Preact-App, die eine Liste der heutigen Spiele in der Fußball-WM Spiele inklusive einiger Details zeigt, welche sie sich von einer öffentlichen API holt.

Kommentar

Ich arbeite im Frontend aktuell hauptsächlich mit React und fühlte mich während der Preact-Demo auch direkt zu Hause. Der Sprung von React zu Preact scheint mir alles andere als dramatisch zu sein, allerdings bin ich dem preact-compat Paket gegenüber noch etwas skeptisch, da es sich einfach zu schön anhört.

In diesem Talk ist mir außerdem zum ersten Mal die neue <Fragment> Komponente aus React 16 begegnet. Endlich keine sinnlosen <div>s mehr!

TensorFlow.js

von Oliver Zeigermann @DJCordhose

Wer im Publikum macht Machine Learning? Drei Leute melden sich. Wer von euch kennt TensorFlow? Fast alle melden sich.

Oliver beantwortet für uns die Frage, warum man TensorFlow mit JavaScript verwenden wollen würde, wo doch Python viel schneller ist und es bereits viele Ressourcen dazu gibt:

  • Bildung

    • JavaScript kann man anfassen, man braucht nur einen Browser und Internet.

    • Konzepte sind einfacher zu begreifen, wenn man damit rumspielen kann.

  • Entwicklung

    • JavaScript ist eine weitverbreitete Sprache und dadurch spricht Google mit TensorFlow nun ein größeres Publikum an.

    • Kombination von Number-Crunching und interaktiven Visualisierungen.

  • Deployment

    • JavaScript ist womöglich die einzige Option für ML, weil der Browser alles ist, was du hast.

      • mobile Endgeräte

      • AI in Browser-Spielen

      • Unabhängigkeit von GPU-Hersteller

Um das beste aus beiden Welten zu bekommen, sprich die Schnelligkeit von Python und die Interaktivität von JavaScript, kann man erst in Python sein Keras oder TensorFlow Modell trainieren, um es dann mit dem tfjs-converter zu einem von TensorFlow.js lesbaren Format zu konvertieren und im Browser zu laden.

In Zukunft können wir dank WebGPU noch große Performance-Boosts für TensorFlow.js erwarten.

Kommentar

Auch wenn eine Vielzahl der Demos nicht so geklappt haben, wie erwartet, war es für mich dennoch ein sehr inspirierender Talk und ich hoffe ihr müsst nicht allzu lange warten, bis ich in diesem Blog eine Demo von einem Sprachmodell veröffentliche, das ich vor einem Jahr für den Bonn Data Science Meetup trainiert habe.

Cross-Plattform-Entwicklung mit React und React Native – Möglichkeiten und Stolpersteine

von Jasper Meyer @jasper__meyer

Jasper berichtet von seiner Erfahrung, eine existierende React App durch react-native zu erweitern. Mit Hilfe der react-native-cli ist das schon mit dem Ausführen von „react-native init“ getan, zumindest fast. Wer eine neue App mit React Native bauen möchte, verwendet besser „create-react-native-app“.

Es wird auf einige API-Unterschiede zwischen Web-React und React Native hingewiesen:

  • Styles

    • Web: CSS

    • Native: Stlye Objects

    • Eine Lösung für alle: cssinjs

  • Media Queries

    • Web: CSS

    • Native: Dimensions API

  • lokaler Key-Value-Store

    • Web: localStorage

    • Native: AsyncStorage

Wer React Native Komponenten auch direkt im Web verwenden möchte, für den gibt es react-native-web. Dazu noch ein Lesetipp von Jasper: Write once, run anywhere with Create React (Native) App and react-native-web

Wie darf man sich nun die Entwicklung von Komponenten in einer React Native App vorstellen?

Jasper beschreibt es mit dem bauen einer eigenen Komponenten-Library, um plattformspezifische Komponenten “automagisch” mit es6 imports zu bekommen.

Weiterer Lesetipp:

Warum AirBnb sich von React Native abwendet

Kommentar

In diesem Talk habe ich mich zum ersten Mal tiefer mit React Native befasst und habe bestimmt eine gewisse Sympathie dafür entwickelt. Am meisten stört mich wohl noch die 0 am Anfang der aktuellen react-native Version. Ich hoffe ja, dass ich in Zukunft mit Progressive Web Apps alle Plattformen glücklich machen kann. Dafür fehlt mir lediglich noch ein Pilotprojekt.

Unleash the Power of Higher-Order Components

von David Kopal @coding_lawyer

Eine kurze Definition von HOCs: Higher-Order Components sind Funktionen, die eine existierende Komponente entgegennehmen, diese manipulieren oder erweitern und eine neue Komponente zurückgeben.

David unterscheidet zwischen „smart components“, welche ausschließlich für Logik zuständig sind und „presentational components“, welche, wie es der Name schon sagt, meist nur noch aus der render Funktion bestehen. Diese „presentational components“ gilt es mit HOCs zu „dekorieren“.

Was macht eine wiederverwendbare Komponente aus? Sie ist nicht abhängig von einer spezifischen Property-Struktur.

Als erstes stellt David die sogenannte „Configured Higher-Order Component“ vor, welche dazu dient die Properties einer presentational component zu manipulieren.

HOCs können beliebig verkettet werden:

Die Recompose Library für React beinhaltet die meist verwendeten Higher-Order Components und eine compose() Funktion, welche eine beliebige Anzahl an HOCs entgegennimmt, um diese zu verketten.

Davids Vortrag war sehr Code-lastig und ich habe das Gefühl, dass ich dem Ausmaß der Wissensvermittlung, die ihm gelungen ist, in dieser Zusammenfassung nie gerecht werden kann.

Seine Code-Beispiele findet ihr unter https://github.com/codinglawyer/hocs-code

Kommentar

Higher-Order Components (HOC) ist ein weiteres Pattern, welches mir zum ersten Mal auf der enterJS begegnet ist. Der Speaker David Kopal, ursprünglich Anwalt, erklärt in einem sehr gut strukturierten Talk die Anwendung dieses Patterns, nachdem er es großflächig in einem komplexen React Frontend eingesetzt hat. Ich denke jedoch, dass HOCs ohne Code-Beispiele nicht so spannend sind und empfehle daher, sich Davids Beispiele und auch die offizielle React Dokumentation zu diesem Thema durchzulesen: https://reactjs.org/docs/higher-order-components.html

Einführung in D3.js – Mächtige Datenvisualisierung im Browser

von Mirco Zeiß @zemirco

D3.js ist eine JavaScript Bibliothek für Datenvisualisierungen im Web.

Über die „InputDomain“ kommen Daten in ein d3-Objekt rein und die „OutputRange“ projiziert die Daten.

In d3 gibt es drei Phasen:

  • Enter:      Neue Daten kommen hinzu

  • Update:  Bestehende Daten werden aktualisiert

  • Exit:        Bestehende Daten werden gelöscht

Der Punkt (0,0) ist in D3.js immer links oben und nicht links unten, wie wir es sonst vielleicht gewohnt sind.

Die API eines d3-Objekts lässt sich auf diese Methoden zusammenfassen:

  • constructor(config)

  • init()

  • render(data)

  • update(data)

  • resize(width)

React/Vue und D3.js sind ein Dream-Team! Lasse D3.js rechnen und nutze moderne Frontend Frameworks für dynamisches Re-Rendering.

Mirco hat ein Beispiel für eine Kombination aus React und D3.js auf GitHub veröffentlicht: https://github.com/zemirco/enterjs

Das dynamische Re-Rendering von Visualisierungen soll im „componentDidMount“ Lifecycle-Hook von React passieren, wobei die Reference der d3.js svg aktualisiert wird. Dabei ist es besonders wichtig, dass jeder Datenpunkt einen individuellen key hat.

Für Einsteiger/Neugierige

Es wird empfohlen, nicht direkt mit D3.js Wrappern einzusteigen, welche meist schwer erweiterbar sind, sondern lieber mit GitHub Gists bl.ocks.org einen interaktiven D3.js Playground zu verwenden, um mit reinem JavaScript und HTML neue Visualisierungen auszuprobieren.

Hier ein Beispiel: https://bl.ocks.org/zemirco/ef5dc3ae80b538e1034442c17c44237f

Wer heute ein Tutorial oder Buch zu D3.js bearbeiten möchte, sollte darauf achten, dass es mindestens mit Version 4 der Visualisierungs-Library arbeitet, da in dieser Version große Änderungen dazugekommen sind.

Leseempfehlung von Mirco: The Trouble with D3 plus die Diskussion auf Hacker News

Kommentar

Ich habe D3.js bisher nur indirekt über React Recharts verwendet und bin damit sehr schnell zu schönen Ergebnissen gekommen, die auch für professionelle Dashboards ausreichend waren und noch viel Spielraum bieten. Nach der inspirierenden Keynote von D3.js-Meisterin Shirley Wu war es umso spannender, einen Blick „unter die Haube“ zu werfen.

Epilog

An dieser Stelle möchte ich mich bei den Organisatoren der enterJS bedanken, die ein wirklich qualitatives und vielfältiges Programm auf die Beine gestellt haben! Ich komme gerne wieder :-)

]]>
Tue, 26 Jun 2018 15:45:39 +0200 https://www.webfactory.de/blog/enterjs-2018-talks https://www.webfactory.de/blog/enterjs-2018-talks webfactory GmbH webfactory GmbH 0
Microservices aus einer monolithischen Webanwendung extrahieren Typischerweise ist die Unübersichtlichkeit des Monolithen ein großes Problem. Sein schierer Umfang, mangelhafte Dokumentation und die Abwesenheit seiner ursprünglichen Entwickler erschweren uns häufig das Verständnis seiner internen Komponenten und ihrer Abhängigkeiten. Vielleicht gibt es Indizien wie Namespaces - aber niemand kann garantieren, dass die Ordnungsprinzipien über alle Entwickler hinweg mit dem gleichen Elan befolgt wurden. Spätestens beim Einsatz schwarzer Magie hilft auch keine statische Code-Analyse mehr - und wir leben in ständiger Angst, dass eine Änderung unbeabsichtigte Nebeneffekte haben könnte.

Sobald wir den alten Code verstanden haben, jucken uns wahrscheinlich schon mehrere Refactorings in den Fingern. Hier schnell etwas gerade ziehen, jenes nebenher vereinfachen. Aber der Monolith ist komplex, und ehe wir uns versehen, grinst uns ein sehr, sehr zotteliges Yak an, das wir zumindest in dem Moment doch lieber nicht rasieren wollen.

Deshalb ist es wichtig, eine Strategie mit ganz vielen Reißleinen zu haben. Sobald wir bemerken, dass wir uns verrannt haben, müssen wir schnell wieder auf den letzten Commit fliehen, in Sicherheit durchatmen und dann noch einmal frisch anfangen können. Aber Moment mal - ist das nicht ein Standardproblem der Software-Entwicklung? Ja! Und es gibt auch eine Standardlösung: automatisierte Software-Tests.

Automatisierte Black-Box-Tests

Im besten Fall decken wir mit (z.B. in behat geschriebenen) Black-Box-Tests alle Funktionen des als Microservice zu extrahierenden Features ab. Wir klicken das Feature im Monolithen einmal komplett durch und halten unsere Beobachtungen als Test-Erwartungen fest. So können wir nicht nur später die Funktionalität absichern, sondern lernen auch nach und nach die Details des zu extrahierenden Features kennen.

Beispielsweise können wir HTTP-Status-Code und spezifische Seiteninhalte für die Feature-Startseite testen, für eine Login-Funktion, Erstellen-, Lesen-, Bearbeiten- und Löschen-Operationen, das Abschicken einer Suchmaske und die entsprechende Ergebnisliste. Bei diesem explorativen Ansatz sollten wir berücksichtigen, ob es verschiedene Benutzergruppen (z.B. Administratoren) und damit eingehende Rechte gibt und für jedes dieser Rechte den Zugriffsschutz testen.

Unit-Tests sind in diesem Kontext weniger relevant. Denn zu diesem Zeitpunkt wissen wir noch nicht genug über den Monolithen bzw. den zu extrahierenden Microservice, als dass wir zu jeder getesteten Unit sagen könnten: Dies ist ihr Kontext und daher ist sie ir/relevant für uns.

Tipp: Datenbank-Dumps mit Slimdump
Mit den Black-Box-Tests können wir schon einmal annähern, welche Tabellen der Microservice benötigt bzw. welche Datenzeilen wir für unsere Test-Fixtures benötigen. Später werden wir das noch weiter eingrenzen können, aber für den Moment wollen wir unser Wissen schon einmal festhalten. Dazu können wir beispielsweise in slimdump, einem Tool für hochgradig konfigurierbare MySQL-Dumps, eine Konfigurationsdatei anlegen, versionieren und mit unseren Kollegen teilen.
Neben der Tabellen- und Datenzeilenauswahl können wir beispielsweise konfigurieren, dass Benutzernamen und E-Mail-Adressen einer User-Tabelle nur anonymisiert gedumpt werden oder dass wir aus Performance-Gründen in jener Tabelle nur 10% der Datensätze und keine BLOBs dumpen wollen.

Grüne Wiese oder Klon?

Wie starten wir konkret mit dem Microservice? Bei Null auf der grünen Wiese oder als Klon des Monolithen, von dem wir dann alles wegschneiden, was nicht zum Microservice gehört? Für beide Varianten gibt es gute Gründe, aber für mich kocht die Entscheidung auf die Abwägung zwischen diesen drei wesentlichen Kriterien ein:

  1. Menge der Einschränkungen: Auf der grünen Wiese starten wir mit minimalen Einschränkungen, im Klon nehmen wir erstmal dessen komplette technische Welt mit.

  2. Nutzung alter Meta-Daten: Meiner Erfahrung nach ist insbesondere die Commit Message History oftmals die einzige Chance, eine Stelle mit besonders verrücktem Code zu verstehen. Insbesondere, wenn durch eine Ticket-Nummer der Kontext der letzten Code-Änderungen deutlich wird.

  3. Latenz bis zur Live-Schaltung des Microservices: Starten wir unseren Microservice auf der grünen Wiese, haben wir eine sehr hohe Latenz, bis er live geschaltet werden kann: er muss erstmal von Grund auf entwickelt werden.
    Wenn wir dagegen den Microservice als Klon des Monolithen erstellen und auf einem eigenen Host betreiben, kann der prinzipiell sofort live gehen. Wir richten einfach irgendeinen Proxy (z.B. Varnish oder mit Apache Rewrite-Rules) vor dem Original-Monolithen ein, der Requests an den Microservice an dessen Host und alle anderen Requests wie gehabt an den Monolithen-Host leitet. Vielleicht müssen wir uns noch um Details bzgl. Cookies, Sessions und URL-Rewriting kümmern - aber das ist offensichtlich immer noch erheblich weniger Latenz als die komplette Neuentwicklung auf der grünen Wiese.

In meiner Erfahrung überwiegen die Argumente für den Start mit dem Klon. Ich vermute, dieser Weg ist im Allgemeinen auch ökonomischer: denn so viel Spaß die grüne Wiese auch bereiten mag - sie scheint mir nur ein Euphemismus für einen teilweisen Rewrite zu sein, der Klon dagegen die Basis für ein Refactoring.

Wahrscheinlich gibt es auch Projekte mit besonderen Umständen, in denen die grüne Wiese die klar bessere Entscheidung ist - an solchen habe ich aber noch nicht gearbeitet. Daher behandelt der weitere Artikel den Klon-Weg.

Tipp: Lauffähigen Monolithen behalten
Falls wir den Monolithen bereits installiert haben, sollten wir den tunlichst bis zur Live-Schaltung des Microservices behalten. Denn wir werden im Laufe des Projekts anhand von Heuristiken Entscheidungen treffen, die sich erst Tage später als falsch herausstellen können. Vielleicht schneiden wir zu viel Code weg oder vereinfachen ihn zu stark und stellen erst im Nachhinein fest, dass uns ein Test fehlte, der genau das anzeigen würde.
In solchen Momenten ist es extrem praktisch, schnell in einer lauffähigen Version des Monolithen nachsehen zu können, wie eine bestimmte Verarbeitung konkret ablief.

Erkennung ungenutzter Ressourcen

Wenn wir unseren künftigen Microservice als Klon des Monolithen aufgesetzt haben - wie erkennen wir die ungenutzten Ressourcen, die wir wegschneiden müssen, damit nur der Microservice übrig bleibt? Allgemein gilt:

Ungenutzte Ressourcen = alle Ressourcen - genutzte Ressourcen

Alle Ressourcen einer Art stehen typischerweise bereits als Liste bereit (z.B. bei Dateien mit ls) und die genutzten Ressourcen ermitteln wir mithilfe unserer Black-Box-Tests. Dazu müssen wir nur eine passende Form des Coverage Loggings aktivieren, die Tests ausführen und dann die Coverage in ein aussagekräftiges Format bringen. Schließlich bilden wir deren Differenz und haben damit die ungenutzten Ressourcen.

Unsere Tests haben also eine Doppelrolle: Erstens sichern wir mit Ihnen die Korrektheit des Codes und zweitens verwenden wir ihre Coverage zur Ermittlung der ungenutzten Ressourcen.

Schauen wir uns mal im Detail an, wie die Ermittlung der genutzten Ressourcen bei verschiedene Ressourcen-Arten funktioniert.

Genutzte PHP-Dateien

Die meisten PHP-Frameworks verarbeiten Requests über einen einen FrontController. In einen solchen können wir uns leicht einhaken und z.B. xdebug die Code Coverage loggen und die Pfade der genutzten Dateien in einer Datei used-files.txt ausgeben lassen:

<?php
// Coverage sammeln lassen
xdebug_start_code_coverage();

// Original-FrontController
$app = new App();
$app->handle($_REQUEST);

// Pfade genutzter Dateien schreiben
$outFile = fopen('used-files.txt', 'a');
fwrite(
  $outFile,
  implode(PHP_EOL, array_keys(xdebug_get_code_coverage()))
);
fclose($outFile);

Wir könnten dafür beispielsweise auch sysdig einsetzen, ein Tool zur Überwachung und Analyse von system calls und Linux kernel events. Dessen großer Vorteil ist, dass wir damit nicht nur verwendete PHP-Dateien erfassen, sondern alle geöffneten Dateien - also z.B. auch Konfigurationsdateien und View-Templates. Größter Nachteil ist, dass der benötigte Umfang nur auf Linux verfügbar ist.

Genutzte Composer-Pakete

Wenn wir die used-files.txt aus dem vorigen Abschnitt auf die Dateien filtern, die in einem Unterverzeichnis von composers vendor-Verzeichnis liegen, können wir aus ihren Pfaden unmittelbar die genutzten Composer-Pakete ablesen.

Genutzte MySQL-Tabellen

Ein Coverage Logging ist leicht z.B. mit folgenden SQL-Statements zu aktivieren:

SET global general_log = 1;
SET global log_output = 'table';

Führen wir nun unsere Tests aus, werden die SQL-Queries in der Tabelle mysql.general_log geloggt (die wir deshalb vorher vermutlich TRUNCATEn möchten). Aus diesen können wir die Namen der genutzten Tabellen extrahieren. Das ist händisch allerdings schnell zu mühsam. Denn zum einen werden es typischerweise sehr viele Queries sein. Zum anderen müssten wir bei jedem Query genau hinschauen, an welchen Stellen Tabellennamen vorkommen können: kommagetrennt in der FROM-Klausel, in der JOIN-Klausel und in Sub-Queries.

Genutzte Frontend-Assets

Die Pfade zu genutzten Frontend-Assets wie Bildern, Schriftarten, Javascript- und CSS-Dateien finden wir als Hits in den Webserver-Access-Logs. Mit einem regulären Ausdruck (für das Apache Standard-Access-Log-Format z.B. #"(?:get|post) ([a-z0-9\_\-\.\/]*)#i) können wir sie herausfiltern. Doch dabei gibt es ein paar Probleme:

Assets-Download: Das Standard-behat-Setup verwendet Goutte als Webbrowser, der keine Bilder, kein Javascript und kein CSS runterlädt und ggf. ausführt. Das heißt, diese Hits fehlen im Logfile. Als Lösung können in behat aber auch andere Browser bzw. Browser-Treiber angebunden werden - mittels Selenium auch Firefox, Chrome oder sogar eine Armada von Browserstack.

Konkatenierungen: Jahrelang haben wir die Performance von Webanwendungen verbessert, indem wir Javascript und CSS in wenigen Dateien konkateniert haben, um so die Anzahl der TCP-Verbindungen an unseren Server zu senken. Dieser Ansatz hat sich mit HTTP/2 überholt, wird aber noch viel in Legacy-Monolithen zu finden sein. Dann ist eine Aussage wie “screen.css und app.js werden genutzt” nur wenig hilfreich.

Hier könnte es am Einfachsten sein, die Konkatenierung auszuschalten und die Quelldateien direkt im HTML einzubetten - wenn denn noch leicht herauszufinden ist, welche Datei auf welche Seite eingebunden gehört.

Falls nicht, könnte die Coverage auf Zeilenebene innerhalb der Dateien in Verbindung mit Sourcemaps ausgewertet werden. Die zeilenbasierte Coverage ist wiederum ein eigenes Problem.

Automatisierte Zeilen-Coverage in Javascript und CSS: Für Javascript gibt es eine Vielzahl von Coverage-Logging-Tools wie Istanbul, JSCover und Blanket.js (und bis dieser Artikel erscheint, gibt es vermutlich wieder drei neue). Diese können an JS-Testrunner wie Karma oder Jasmin angebunden werden. Zusammen mit den eigentlichen Javascript-Tests kommt hier möglicherweise einiges an Aufwand hinzu.

Bei CSS ist die Lage noch schwieriger, aber immerhin gerade in Bewegung: Beispielsweise hat Chrome seit der Version 59 ein eigenes Panel für die CSS Coverage. Die Ermittlung der Coverage funktioniert grob so, dass für alle Selektoren in den geladenen CSS-Dateien geprüft wird, ob sie im geladenen Dokument treffen. Falls ja, werden sie und die damit verbundenen Statements als benutzt markiert. Das ist zwar nicht perfekt, scheint aber eine brauchbare Heuristik zu sein. Leider sind weder Ein- noch Ausgabe für diesen Prozess leicht automatisierbar. Es bleibt zu hoffen, dass entsprechende Methoden mittelfristig in der puppeteer-API ergänzt werden.

Wer diesen Prozess unbedingt jetzt schon automatisieren will, kann sich z.B. mit dem Firefox Plugin “Dust-Me Selectors” notbehelfen. Dort können eine Sitemap eingegeben und die resultierende Coverage auf Datei- und Zeilenebene als JSON exportiert werden.

Automatisierung mit dem Zauberlehrling

Der Zauberlehrling ist ein Open Source-Tool, das bei der Extraktion von Microservices unterstützen soll. Insbesondere automatisiert es einige Schritte zur Erkennung ungenutzter Ressourcen:

bin/console show-unused-php-files --pathToInspect --pathToOutput --pathToBlacklist usedFiles

zeigt die ungenutzten PHP-Dateien an. Als Eingabe dient das weiter oben erstellte used-files.txt. Außerdem können der zu untersuchende Pfad auf dem Dateisystem, eine Ausgabe-Datei und eine Blacklist konfiguriert werden, um z.B. Temp-Verzeichnisse auszuschließen oder solche, von denen bekannt ist, dass sie nicht von den Black-Box-Tests abgedeckt werden (z.B. Pfade für Unit-Tests).

bin/console show-unused-composer-packages --vendorDir composerJson usedFiles

zeigt die vermeintlich ungenutzten Composer-Pakete. Die Qualität der Aussage korreliert unmittelbar mit dem Inhalt der usedFiles-Datei: Für den Zauberlehrling gilt ein Paket als genutzt, wenn mindestens eine Datei darin genutzt wird. Enthält die usedFiles-Datei beispielsweise nur mit xdebug ermittelte PHP-Dateien, werden Composer-Pakete, die ausschließlich aus View-Templates oder Konfiguration bestehen, niemals als genutzt erkannt und immer als vermeintlich ungenutzt ausgegeben werden. Mit sysdig erstellte usedFiles-Dateien sind daher hier vorteilhafter.

bin/console show-unused-mysql-tables

ermittelt mit einem SQL-Parser aus der MySQL-Log-Tabelle die genutzten Tabellen, bildet die Differenz zu allen und zeigt die vermeintlich ungenutzten Tabellen an.

bin/console show-unused-public-assets --regExpToFindFile --pathToOutput --pathToBlacklist pathToPublic pathToLogFile

zeigt die vermeintlich ungenutzten Frontend-Assets. Nimmt die Pfade des Public-Verzeichnisses und Access-Logs als Eingabe und kann mit dem regulären Ausdruck zur Erkennung der Dateipfade im Access-Log, der Ausgabe-Datei und einer Blacklist (wie bei den ungenutzten PHP-Dateien) konfiguriert werden.

Kurze Entwicklungs-Zyklen

Die Automatisierung durch den Zauberlehrling ermöglicht das Arbeiten in kurzen Entwicklungszyklen. Nach einem initialen Coverage-Durchlauf können diese wie folgt aussehen:

  1. Ungenutzte Ressource löschen
  2. Tests ausführen (der Geschwindigkeit halber ohne Coverage)
  3. ggf. gelöschte Ressource wiederherstellen, Code oder Tests fixen
  4. committen
  5. zurück zu 1. oder Abbruch.

Sind die erkannten ungenutzten Ressourcen gelöscht, sollte wieder ein Testlauf mit Code Coverage durchgeführt werden. Es lohnt sich auch ein Blick auf die Liste der genutzten Dateien - vielleicht sind hier noch niedrig hängende Früchte zu erkennen. Wenn beispielsweise in einem Composer-Paket nur noch wenige Dateien benötigt werden, können wir es vielleicht ganz überflüssig machen und als Abhängigkeit entfernen. Vielleicht finden wir auch im Kontext unseres Microservices überflüssige Abstraktionen, die wir jetzt vereinfachen können.

Und anschließend nicht vergessen: die Tests wieder ausführen :)

___

Dieser Artikel erschien zuerst im PHP Magazin 2.18. Er basiert auf einem ausführlicheren Vortrag auf der FrOSCon 2017, dessen Mitschnitt beim CCC und auf Youtube veröffentlicht ist.

]]>
Wed, 23 May 2018 11:02:42 +0200 https://www.webfactory.de/blog/microservices-aus-einer-monolithischen-webanwendung-extrahieren https://www.webfactory.de/blog/microservices-aus-einer-monolithischen-webanwendung-extrahieren webfactory GmbH webfactory GmbH 0
Girls'Day bei der webfactory Nachdem uns im März eine E-Mail von einer Mutter einer Bonner Schülerin erreicht hat, in der sie fragte, ob ihre Tochter im Rahmen des Girls'Day zu uns in die Firma kommen könnte, haben wir uns auf der offiziellen Seite als Botschafter für mehr Frauen in der IT-Branche angemeldet.

Ich habe bereits 2015 einen Girls'Day organisiert, als ich noch bei IBM gearbeitet habe und nahm mich daher ohne zu zögern dieser Aufgabe an. Damals war das Feedback sehr positiv, sodass ich die Agenda vollständig übernommen habe:

  1. Kennenlernrunde
  2. Vorstellung der Tätigkeiten in den verschiedenen Rollen bei der webfactory (Backend-Entwicklerin, Designerin, Projektmanagerin)
  3. Spielerisch Programmieren lernen mit der "hour of code" https://code.org/learn
  4. Gemeinsames Mittagessen
  5. Erarbeitung und Präsentation einer eigenen Projektidee

Mit der Unterstützung von meinen Kollegen Eva, Jano und Søren haben wir die Mädchen durch das Programm begleitet.

Mein persönlicher Höhepunkt waren die kreativen Projektideen und der feste Vorsatz von einem der zwei Projektteams, von denen sich zwei von vier Teammitgliederinnen zuvor noch nicht kannten, sich in der Freizeit zu treffen, um das Projekt weiterzuentwickeln.

Schließlich erhielt jede Teilnehmerin noch eine Liste von nützlichen Ressourcen, um mehr über Webentwicklung und Programmierung zu lernen:

Wir sind gespannt auf die nächsten Marktführer für Mode-Sale-Finder und community-driven Fitnessratgeber im Web.

Unser Angebot auf der Girls'Day Website: https://www.girls-day.de/aktool/ez/eventvcard.aspx?id=73844

]]>
Mon, 30 Apr 2018 11:05:45 +0200 https://www.webfactory.de/blog/girls-day-2018 https://www.webfactory.de/blog/girls-day-2018 webfactory GmbH webfactory GmbH 0
Advanced subsearches and transactions in Splunk: Tracing qmail deliveries The email in question was part of a larger mail processing job, and we're using qmail to process these mails. Yes, qmail – it works great when it comes to doing high-volume, outbound-only deliveries in short time. 

The problem challenge is that qmail has an interesting way of logging in the current log, which looks like this:

@400000005aa66b052a527324 new msg 33778541
@400000005aa66b052a527edc info msg 33778541: bytes 7703 from <sender@host.tld> qp 21534 uid 64011
@400000005aa66b052a840e5c starting delivery 7512293: msg 33778541 to remote recipient@host.tld
@400000005aa66b060a418aac delivery 7512293: success: 176.34.178.125_accepted_message./Remote_host_said:_250_OK_id=1evM4J-0005W8-QC/
@400000005aa66b060a419a4c end msg 33778541

I am not talking about the funny-looking tai64 timestamps, but rather the message and delivery ids. There are several problems with this:

  • The message id is based on the Linux filesystem inode id for the mail file sitting in the queue. While being unique at a given time, multiple different mails will use the same message id over time.
  • The delivery id is just a counter that increments with every message processed. It will start from scratch if you restart qmail, and so again, this id is not unique over a longer time.
  • While you get the information that a particular delivery has been started for a given message id, all further information regarding the progress of this delivery is logged only with the delivery id, but does not show the message id again. That's probably due to the way the qmail architecture uses different processes for isolated tasks.

In order to get a comprehensive Splunk report for a given email address and to make it run in acceptable time, I had to learn about Splunk subsearches and transaction grouping.

Use a subsearch to narrow down relevant events

First, lets start with a simple Splunk search for the recipient address.

index=mail sourcetype=qmail_current recipient@host.tld

In particular, this will find the starting delivery  events for this address, like the third log line shown above. Having done our homework, Splunk extractions are set up in a way that we get the qmail_msg and qmail_delivery fields for this event.

Now, in order to get a complete report including delivery progress, we need to consider all log events that include either the appropriate message id or delivery id. 

With a default Splunk subsearch, the outer search will get all events where every field returned from the subsearch matches.

This works because Splunk applies the format  command implicitly on subsearches. Try this:

index=mail sourcetype=qmail_current recipient@host.tld | fields qmail_msg qmail_delivery | format

This will return a single event with a field named search  and a value like

( ( qmail_delivery="8227046" AND qmail_msg="33565415" ) OR ( qmail_delivery="7947353" AND qmail_msg="33719121" ) OR ...)

Splunk will first execute the subsearch. Then, the value from this search  field is taken as a replacement for the subsearch part of the query. Finally, the resulting query is executed.

You can, in fact, put the format command in your subsearch yourself and use parameters to modify the resulting string. Let's do this and directly combine it with a subsearch:

index=mail sourcetype=qmail_current [
    search index=mail sourcetype=qmail_current recipient@host.tld 
    | fields qmail_msg qmail_delivery  | format  "" "" "OR" "" "OR" ""
]

This search fetches all log events that either have a message id or a delivery id for any message or delivery ids that appears in context with the recipient address.

Group events as transactions

You can then use the transaction command to group events. As you can see from the log excerpt above, qmail transactions start with new msg  and end with end msg . We need to pick the message id from the start event and also include all events that have this message id and occur before the end event.

Additionally, the delivery id makes up the transaction. The transaction command is smart enough to pick up any delivery id that appears together with the message id we're following, and it can use this delivery id to include further events, even if they lack the message id. The transaction documentation has an example for this.

Adding a maximum duration between single transaction events for added performance, this gives us

| transaction qmail_msg qmail_delivery
    startswith="new msg" endswith="end msg"
    maxpause=1h

Now the last step is to once again filter out transactions that do not contain our intended recipient. Those transactions may show up because, as I stated in the beginning, the ids used by qmail are not unique. So while the subsearch finds the right ids for our particular recipient, the outer search may produce too many intermediate results.

We remove those transactions by applying a final

| search recipient@host.tld 

The result

Putting it all together, we get

index=mail sourcetype=qmail_current [
    search index=mail sourcetype=qmail_current recipient@host.tld
    | fields qmail_msg qmail_delivery
    | format  "" "" "OR" "" "OR" ""  
]
    | transaction qmail_msg qmail_delivery
          startswith="new msg" endswith="end msg" maxpause=1h
    | search recipient@host.tld

Most Splunk queries like this seem to do magic. And once they work, you tend to forget how they work or why they probably produce correct results. In part, this is why I am writing this up as a note to my future self.

Also, because a query like this is hard to remember or to re-construct, I saved this search as a Splunk dashboard. That allows you to add a handy input box for the address et voilà, we have a simple-to-use interface for our next support call.

]]>
Fri, 16 Mar 2018 09:47:31 +0100 https://www.webfactory.de/blog/splunk-subsearch-transaction-qmail-deliveries https://www.webfactory.de/blog/splunk-subsearch-transaction-qmail-deliveries webfactory GmbH webfactory GmbH 0
Ein paar Worte zum Schluss Frohe Weihnachten

Danke!

Weil es so schön ist, fangen wir doch gleich einmal mit dem Dank an: Liebe Kunden, die Zusammenarbeit mit euch ist das Kernstück unserer Arbeit. Wie könnten wir also nicht mit euch beginnen? Wir danken euch dafür, dass ihr uns – viele von euch schon seit so vielen Jahren – euer Vertrauen schenkt. Jeder einzelne von euch liegt uns wirklich sehr am Herzen und wir sind nach wie vor fest davon überzeugt, die besten Kunden der Welt zu haben! Auch 2017 haben wir wieder einige spannende Aufgaben gemeinsam mit euch gestemmt. An großen Projekten hervorzuheben ist sicherlich der schrittweise Launch der Staatsoper Berlin von Juni bis Oktober. Das Projekt hat uns trotz – oder vielleicht gerade wegen – seiner Komplexität und seines Umfangs sehr viel Spaß gemacht. Wir freuen uns ganz besonders darüber, dass das gute Feedback des Staatsoper-Teams uns direkt ein Folgeprojekt für das Staatstheater Darmstadt in die Firma gespült hat. Neben den Webprojekten aus dem künstlerischen Feld begleitet uns außerdem fast schon das ganze Jahr die Überarbeitung der Website des Gemeinsamen Bundesausschuss, die wir 2018 fertigstellen werden. Auch Jugend für Europa hat uns dieses Jahr wieder einige Projekte beschert: Besonders spannend ist dabei gerade die Umsetzung der Website für das neue Förderprogramm des Europäischen Solidaritätskorps, das 2018 an den Start geht. 

Danke sagen möchten wir außerdem auch all unseren externen Kooperationspartnern und Helferlein, die uns auch in diesem Jahr wieder an vielen Fronten unterstützt haben: Lieben Dank an Benjamin O’Daniel für die Unterstützung bei unserer Mitarbeitersuche und für all den wertvollen Input. Danke an Ruth und ihr Team von kaffeetante.net für die tolle Kooperation bei unserem FrOSCon-Kaffeestand. Danke an die Odenthal-Illustratoren für unsere schönen, neuen Team-Avatare und danke auch an unsere gute Bürofee Jutta für all die Blumen, Kürbisse, Kerzen und Schokoladen, mit denen du uns dieses Jahr eine Freude gemacht hast. 

Webfactory 2017 intern

Für unseren kleinen webfactory Mikrokosmos war das Jahr unseres 20. Geburtstags relativ turbulent. Besonders beeinflusst hat uns sicherlich der Verlust von gleich drei Kolleg*innen in der ersten Jahreshälfte. Auch viele unserer Kunden haben dies leider durch einige Projektverzögerungen zu spüren bekommen. An dieser Stelle danken wir euch hier noch einmal ganz herzlich für eure Geduld. Auf der anderen Seite freuen wir uns sehr darüber, drei neue Kolleg*innen dazugewonnen zu haben, die uns maßgeblich im Frontend, in der Konzeption und Projektorganisation unterstützen. Damit sind wir aber noch lange nicht am Ende, denn im Backend suchen wir immer noch dringend nach Verstärkung. Im vergangenen Jahr haben wir im Hinblick auf die Mitarbeitersuche erstmals in der Firmengeschichte einen eigenen, kleinen Konferenzstand auf der FrOSCon12 betreut und im nächsten Jahr legen wir direkt noch einen drauf: Ab Januar könnt ihr an ausgewählten Bushaltestellen im Bonner Stadtgebiet unsere knallorangene Stellenanzeige bewundern. 

Eine weitere große Veränderung dieses Jahr betrifft die Art und Weise, wie wir unsere Aufgaben organisieren. Seit einigen Monaten sind wir damit beschäftigt, dafür ein sogenanntes Kanban-System in unsere Projektabläufe zu integrieren (dazu sicherlich zu einem späteren Zeitpunkt einmal mehr). Auch wenn wir noch nicht am Ende angelangt sind, so haben wir doch das Gefühl, schon einiges in eine sehr positive Richtung bewirkt zu haben. Insgesamt erhoffen wir uns von der Umstellung eine Intensivierung unseres Arbeitsfokus, einen schnelleren Durchlauf der einzelnen Aufgaben und eine Verbesserung in der Vorhersagbarkeit von Projektlaufzeiten. 

Bei aller Ernsthaftigkeit darf aber auch der Spaß nicht zu kurz kommen, dieses Jahr zum Beispiel in Form eines Paintball-Teamevents. Und auch, wenn es vielleicht nur eine Kleinigkeit ist, freuen wir uns darüber, dass wir uns nach wie vor jeden Mittag zu einem gemeinsamen und vor allem selbst zubereiteten Essen zusammenfinden. Wir glauben, dass wir nur dann zur Höchstform auflaufen, wenn wir zufrieden mit dem sind, was wir tun und wenn wir nicht nur auf Effizienz und Output blicken, sondern ebenso auf soziale Faktoren achtgeben. Somit versuchen wir in unserer Firma einen Ort zu schaffen, an dem alle offen und ehrlich miteinander reden können und auch den Bedürfnissen einzelner Raum gegeben wird. 2017 konnten wir wieder einen stattlichen Jahresbonus an all unsere Mitarbeiter ausschütten und dem Team mit der Zahlung eines 13. Gehalts eine Freude machen. Zum Jahresende haben sich auch auf der sozialen Ebene noch einige Neuerungen ergeben: Seit kurzem bieten wir allen Mitarbeitern die Möglichkeit, jeden Morgen vor Arbeitsbeginn an einer fünfminütigen Meditationsübung teilzunehmen. 2018 wollen wir außerdem ausprobieren, wie sich das Leben mit einem Bürohund anfühlt. 

Zu guter Letzt bleibt nur noch zu sagen: Wir freuen uns auf 2018 und sind gespannt, was das neue Jahr zu bieten hat!

Wir wünschen euch allen fröhliche Weihnachten und einen guten Start in das neue Jahr.

Herzliche Grüße
eure webfactory 

]]>
Tue, 19 Dec 2017 13:55:47 +0100 https://www.webfactory.de/blog/ein-paar-worte-zum-schluss-2017 https://www.webfactory.de/blog/ein-paar-worte-zum-schluss-2017 webfactory GmbH webfactory GmbH 0