Eine Website ohne Framework und viele Bibliotheken erstellen
(kodingkitty.com)- Koding Kitty setzt für kleine Unternehmenswebsites auf einen statisch HTML-zentrierten Stack und betreibt damit die nötigen Seiten und einen Blog ganz ohne großes CMS oder Framework
- Die Auswahlkriterien waren Geschwindigkeit, Entwicklungsfreundlichkeit, günstiges Hosting und geringe Komplexität; WordPress, No-Code, Frameworks und Jamstack brachten im Verhältnis zu den Anforderungen zu viel Einrichtungs- und Lernaufwand mit sich
- Inhalte werden nicht in Markdown oder mit einem visuellen Editor, sondern direkt in HTML geschrieben, wodurch sich Beiträge mit gemischten Text- und HTML/CSS/JS-Widgets leicht umsetzen lassen
- Wiederkehrende Strukturen und gemeinsame Blöcke werden mit Jinja-Templates gelöst, und ein 45 Zeilen langes Python-Skript verbindet Änderungserkennung, HTML-Rendering und den Aufruf der Tailwind CSS CLI
- Da es sich um eine statische Website handelt, reicht günstiges Hosting aus; Hetzner Webhosting beginnt bei 2 EUR und hielt auch Traffic-Spitzen auf dem Niveau der Hacker-News-Startseite aus
Warum ein einfacher Stack gewählt wurde
- Der Tech-Stack der Koding-Kitty-Website wurde bewusst einfach gehalten, statt aktuellen Trends im leichtgewichtigen Web Development zu folgen, und an den tatsächlichen Anforderungen ausgerichtet
- Ziel war eine Konfiguration mit möglichst wenig Reibung für Entwickler, und man sah in einer einfachen Lösung für Kunden oft die bessere Wahl als in einer komplexen Kombination aus Frameworks und Bibliotheken
- Ein eigenständiges, aber nicht übertriebenes Design ließ sich auf verschiedene Arten umsetzen, doch die aktuelle Konfiguration ist eine Auswahl passend zum benötigten Umfang
Anforderungen und erste Kriterien
- Von Anfang an fiel die Entscheidung für eine statische Website
- Benötigt wurden im Wesentlichen eine Startseite, eine Showcase-Seite und ein Blog, viel mehr nicht
- Es gab vier Kriterien
- schnelle Website
- schnelle Entwicklung
- günstiges Hosting
- minimale Komplexität
Geprüfte, aber verworfene Optionen
-
WordPress und ähnliche CMS
- Es wird anerkannt, dass WordPress eine große Rolle im Internet gespielt hat
- Für die bescheidenen Anforderungen war es jedoch zu viel
- Es bestand kein Bedarf, Inhalte in einer Datenbank zu speichern, und auch Plugins oder visuelle Editoren wurden nicht benötigt
-
No-Code-Tools
- Für jemanden, der Websites codiert, fühlte sich der Einsatz von No-Code-Tools unnatürlich an
- Man wollte die Inhalte direkt besitzen und die Website vollständig nach Wunsch handhaben können
- Das Erstellen per Code erschien schneller als ein No-Code-WYSIWYG-Editor
- Auch der anfängliche und fortlaufende Lernaufwand wurde als Belastung gesehen
-
Frameworks
- Erfahrung mit Frameworks war vorhanden, aber man wollte nicht die gesamte Konfiguration mit übernehmen
- Datenbank, Konfiguration, Bibliotheken, Admin-Funktionen und weitere Bestandteile konnten schnell zu viel werden
- Zwar wäre vollständige Anpassung möglich gewesen, doch das Ergebnis hätte letztlich WordPress ähneln können
-
Jamstack und Static Site Generatoren
- Static Site Generatoren wirkten zunächst wie eine gute Wahl für die Anforderungen
- Man kann eine Sprache wählen, Code schreiben und dann per Button oder Skript schnell eine statische Website erzeugen
- Dennoch wären Ersteinrichtung sowie anfängliches und fortlaufendes Lernen nötig gewesen
- Die Bequemlichkeit, einen Blog in Markdown zu schreiben, wurde anerkannt, insgesamt fiel die Wahl aber auf eine noch einfachere Lösung
Aufbau von KittyStack
- Die Konfiguration von Koding Kitty wurde entlang der vier Anforderungen organisiert
-
Schnelle Website
- Eine statische Website ist schnell
-
Schnelle Entwicklung
- Inhalte werden nicht in Markdown oder einem fortgeschrittenen Editor, sondern in HTML geschrieben
- Da die Beiträge von Koding Kitty Text mit HTML/CSS/JS-Widgets mischen, war das direkte Schreiben in HTML passend
-
Günstiges Hosting
- Die Hosting-Kosten für statische Websites hängen vom Anbieter und von benötigten Zusatzfunktionen ab
- Statische Websites benötigen keine große Hardware-Konfiguration, sodass eine Minimalausstattung gewählt werden kann
- Hetzner webhosting beginnt bei 2 EUR
- Die Website von Koding Kitty hielt auch Traffic-Spitzen in der Größenordnung eines Platzes auf der Startseite von Hacker News aus
-
Minimale Komplexität
- Einige Seiten und Beiträge enthalten wiederkehrende Muster
- Das ließe sich per Copy-and-paste lösen, könnte aber mit der Zeit schwer kontrollierbar werden
- Benötigt wurden Schleifen sowie die Möglichkeit, Codeblöcke wie Header und Footer einzubinden
Jinja und der Build-Ablauf
- Wiederkehrende Strukturen und das Einbinden gemeinsamer Dateien werden mit Jinja Templates umgesetzt
- Jinja bietet Schleifen, das Einbinden von Dateien wie Navigationsleiste und Footer sowie weitere Template-Funktionen
- Das Team hatte in der Vergangenheit bereits Frameworks auf Jinja-Basis verwendet und musste daher kein neues System lernen
Einfache Toolchain
- Die finalen statischen Seiten werden mit einem 45 Zeilen langen Python-Skript erzeugt
- Die Zeilenangabe schließt Kommentare und Leerzeilen ein
- Der Build-Ablauf sieht so aus
- Ein Entwickler bearbeitet
index.src.html Watchdog.pyerkennt Dateiänderungen- Das Jinja-Template wird zu
index.htmlgerendert - Die Tailwind CSS CLI wird aufgerufen, um
styles.min.csszu erzeugen
- Ein Entwickler bearbeitet
- Während der Entwicklung stellt Live Server die Dateien bereit und lädt bei Änderungen neu
- Zum Deployment werden die Dateien manuell per FTP hochgeladen
Vorteile weniger komplexer Webentwicklung
- Web Development kann einfach gehalten werden, ohne auf allzu viel verzichten zu müssen
- Wenn man die Auswahlmöglichkeiten auf einige wenige beschränkt, kann sich das sogar freier anfühlen
- Für viele Kunden kann eine schnellere, einfachere und günstigere Lösung hilfreich sein
- Es lohnt sich, im Web insgesamt zu prüfen, ob sich dasselbe Ergebnis mit einem weniger komplexen Tech-Stack erreichen lässt
1 Kommentare
Hacker-News-Kommentare
Bei Foto-Portfolios hat sich bei mir derselbe Ansatz etabliert. Seit ich von der Entwicklung zur Fotografie gewechselt bin, ist es ein Vorteil, nicht wie andere Fotografen auf Squarespace angewiesen zu sein.
Nachdem ich mehrere serverbasierte Optionen mit Ghost, Statamic und Phoenix/Vapor sowie die üblichen Static-Site-Generatoren ausprobiert hatte, bin ich am Ende bei reinem HTML ohne Templates gelandet, das ich per rsync auf einen Hetzner-Server hochlade.
Dass es für gemeinsame UI-Elemente wie die Navigation keine Templates gibt, ist etwas lästig, aber Änderungen, die mit Regex mehr als ein paar Minuten gedauert hätten, hatte ich bisher noch nicht; und als mir am Anfang einmal ein gieriger regulärer Ausdruck Inhalte gelöscht hat, hat git mich gerettet.
Das Erzeugen von Varianten für Bildgrößen und -formate ist mühsam, aber es bringt mich dazu, neue Layouts auszuprobieren, statt mich auf starre Layouts wie bei Ghost zu verlassen. Außerdem wirkte die Qualität der für das Web exportierten Bilder aus dem RAW-Editor Capture One etwas besser als bei den Bibliotheken oder CLI-Tools, die die meisten Static-Site-Generatoren verwenden.
Es ist langsamer, aber ich sehe es eher als das Erstellen eines Fotobuchs. Am Anfang ist es mehr Handarbeit, aber wenn es einmal fertig ist, ist es fertig, und ich muss in den nächsten 20 Jahren nicht zwischen diversen CMS hin- und herwechseln und dabei alles kaputtmachen.
Im Grunde ist es nur eine Handvoll HTML-Dateien mit etwas Template-Power; über die Flickr API werden Fotos aus einem nur für diese Website vorgesehenen Album geladen, und Netlify deployed automatisch, sobald ich
git pushmache.Die Gesamtkosten inklusive Hosting liegen bei 0 Dollar, und mit der Flickr-App kann ich Fotos vom Handy aus verwalten. Dank Netlify muss ich auch keinen echten Server anfassen, was angenehm ist.
Vielleicht hilft auch der Ansatz, den ich kürzlich verwendet habe (https://news.ycombinator.com/item?id=36592641). Google Sheets als Datenquelle zu nutzen war einfach, und mit einem Foto-Dateisystem wäre es wohl genauso gewesen.
Das wirkt nicht wirklich einfach (simple), sondern eher nur simplistisch (simplistic). Wenn man nichts tut und die Ecken abschleift, kann man eine relativ einfache Website bauen.
Schon am Dark Mode, fast der einzigen nichttrivialen Funktion auf dieser Seite, sieht man das: Er wird über verzögert geladenes JS umgesetzt, wodurch bei jedem Seitenaufruf unvermeidlich ein weißes Flackern entsteht. Richtig wäre eine CSS-Body-Klassen-Lösung; und eine Lösung, die nicht funktioniert, ist weder in einfacher noch in komplexer Form sinnvoll.
Außerdem steht es im Widerspruch zur Idee von „Einfachheit ist die ultimative Vollendung“, für drei Zeilen JS rund um localStorage und die Dark-Mode-Einstellung einen kompletten Custom-„hyperscript“-Interpreter wie https://hyperscript.org/ einzubinden. Eine nicht gecachte 96-KB-Bibliothek nur dafür zu laden ist seltsam, und ich frage mich, ob deshalb auch die HTML-Validierung fehlschlägt.
Und zuletzt: Ein binärer Toggle ist eine schlechte Dark-Mode-Implementierung, weil er die System-/Browser-Einstellungen ignoriert. Selbst wenn auf dem Smartphone-OS Dark Mode aktiviert ist, bekommt man Light Mode, bis der Nutzer es manuell einschaltet, und auch Systemvorgaben, die sich nach Uhrzeit oder Umgebungslicht ändern, werden nicht respektiert. localStorage kann ablaufen, Geräte wechseln sich, also muss man die Einstellung wiederholt neu setzen; Nutzer werden der vom Entwickler sogenannten „einfachen“ Umsetzung daher vermutlich nicht zustimmen.
Wenn man System-/Browser-Einstellungen, zeitbasierte Umschaltung oder Umgebungslicht berücksichtigen will, entsteht eine Komplexität, die mit der Philosophie einer einfachen Website kollidiert. Dann lässt man Dark Mode besser ganz weg; auch HN ist immer im Light Mode, und nachts lesen lässt es sich trotzdem problemlos.
Normalerweise möchte man
prefers-color-schemerespektieren und trotzdem einen Toggle anbieten, und wenn der Nutzer auf der Website zuvor selbst eine Auswahl getroffen hat, möchte man diese bevorzugen. Dann braucht man weiterhin JS und localStorage.Mein bevorzugter Ansatz ist, per Inline-Style
body {visibility: hidden; opacity: 0;}zu setzen. Dann bleibt die vorherige Seite sichtbar, bis beiDOMContentLoadedprefers-color-schemeund localStorage geprüft, die Body-Klasse korrekt gesetzt und erst danach die Seite gerendert wird.Meine Website respektiert per CSS Light-/Dark-Themes und hat keinen manuellen Toggle. Mein persönliches Ziel ist eine reine HTML/CSS-Seite ohne JS, und ich finde, die Light-/Dark-Einstellung sollte die Präferenzen des Nutzers respektieren. Wenn es einen Toggle geben muss, dann nicht auf der Website selbst, sondern als Einstellung in der Browser-Toolbar.
Falls /u/gwern mitliest: Meine Seite https://daveon.design/ wurde von gwerns Design und Tufte.css beeinflusst. Auch alte Publikationen, Manuskripte und mein persönlicher Geschmack spielen hinein, aber gwern war für mich das entscheidende frühe Beispiel dafür, wie eine moderne, saubere persönliche Website aussehen und was sie enthalten kann.
Wenn ich es unbedingt sagen müsste: SvelteKit + Skeleton ist derzeit wirklich beeindruckend, was die Geschwindigkeit angeht, mit der man einen brauchbaren Prototypen bauen kann
Selbst wenn man Svelte nicht wirklich gut kennt, muss man im Grunde nur das dateibasierte Routing verstehen; der Rest ist fast nur HTML, bis man ihn wirklich braucht. Tailwind ist standardmäßig dabei, und auch das Theming bleibt größtenteils nahe an Vanilla
In den letzten Monaten habe ich Astro, Lit, Next.js, die eingebauten Templates von Go, pug, Eleventy und einiges mehr ausprobiert, und bisher gefällt mir diese Kombination in fast jeder Hinsicht am besten
Schon auf der eigenen Website von Skeleton https://www.skeleton.dev/docs/get-started sieht man es: Mit Page Down kann man nicht scrollen, wenn man mit der Maus über die Navigationsleiste fährt, ebenfalls nicht, und beim Drucken wird nur der sichtbare Bereich abgeschnitten. Ich habe das angesprochen, aber obwohl es offenbar keine hohe Priorität hat, verwenden viele Websites weiterhin dieses Komponenten-Muster
Skeleton scheint davon auszugehen, dass man durch Invertieren der Farben eines Dark Themes ein brauchbares Light Theme erhält, aber in der Praxis stimmt das nicht. DaisyUI ist ausgereifter, performanter, weiter verbreitet und nimmt Barrierefreiheit ernst. Beeindruckend ist auch, dass dort alles nur mit CSS-Animationen und ohne JS umgesetzt wird. Es nimmt einem die schwierigen HTML/CSS-Teile ab, während man die einfachen Svelte-Teile selbst schreiben kann. Außerdem ist die Bindung an Svelte gering, sodass sich DaisyUI-HTML leicht in andere Frameworks übertragen lässt
Tailwind funktioniert sofort, und das Deployment zu Netlify oder ähnlichen Diensten ist ebenfalls sehr einfach. Für mich ist es derzeit der beste Builder für statische Websites und deutlich einfacher als der im Artikel beschriebene Ansatz
Mit
+page.tsund passender Konfiguration kann man auch statische Websites bauen und später zu einer Multi-Page-App oder Single-Page-App weitergehenMeine Güte, eine Website mit HTML und CSS zu bauen, klingt ja verrückt
Spaß beiseite: Abgesehen vom Templating nutze ich denselben Stack. Wenn man kein Webentwickler ist, sehe ich den Bedarf für ein CSS-Framework nicht so richtig, und es ist viel einfacher, es selbst zu machen. Ich habe auch Hugo als Site-Generator ausprobiert, aber das hat mir überhaupt keine Zeit gespart
Vor ein paar Monaten habe ich zur Verbesserung meiner CSS-Fähigkeiten einige Unternehmenswebsites nachgebaut, und rein optisch ließ sich alles nur mit HTML und CSS reproduzieren. Die tatsächlichen Websites dieser Firmen erschienen aber gar nicht mehr, sobald man JS deaktiviert hatte
Wir stapeln immer mehr Frameworks auf Frameworks, dazu neue Sprachen und neue Tools, und meistens erhöht das nur die Komplexität und die Beschäftigung der nächsten Generation. Die 5 % der Websites, die so etwas wirklich brauchen, sind die Ausnahme
Ich fand auch interessant, dass es sich um eine Website zum Verkauf realer Dienstleistungen handelte, und hätte gern gewusst, in welcher Preisrange sie lag
Ich denke, der minimalste und zugleich produktivste Weg ist einfach PHP zu verwenden. Die Sprache wurde ursprünglich genau für so etwas gemacht
Für eine einfache Website braucht man weder Composer noch Router-Logik; man legt einfach Dateien für Header/Footer/Navigation an und bindet sie auf jeder Seite per include ein
header.php,pagename.phpundfooter.phpein. Für einfache Websites mache ich das so, und es ist sehr leicht und schnellWenn HTML wie CSS oder JS externes HTML einbinden könnte, wäre selbst das meiste davon unnötig. Ich wünschte, das wäre einfach frei nutzbar
Wenn man etwas ändert und per git commit/push aktualisiert, sind die Änderungen in unter 30 Sekunden weltweit live. Das ist ziemlich großartig, und man braucht kein separates Server-Hosting
Das erinnert mich an den Spruch: „So einfach wie möglich, aber nicht einfacher.“ Wahrscheinlich stammt er nicht von Albert Einstein.
Reines HTML + CSS, wobei das CSS direkt in die einzelnen HTML-Tags oder in die Seite geschrieben wird, ist für den Einstieg okay. Sobald es zwei Seiten gibt, lagert man das CSS in eine separate Datei aus.
Wenn man aber anfängt, eine Website mit mehreren Seiten im gleichen Format zu bauen, braucht man ein Template-System mit Includes und einen statischen Seitengenerator.
Wenn die Seiten datengetrieben sind, braucht man einen programmierbaren Site-Generator, der Daten frisst und Seiten ausspuckt. Wenn die Daten „in Echtzeit“ sind, muss man Seiten pro View erzeugen, also landet man mindestens im PHP-Bereich, eher noch bei modernen Web-Frameworks mit laufendem Server.
Ich habe kürzlich pro bono eine Hobby-Website gebaut: eine Tanz-Promo- und Event-Seite, deren Besitzerin eine Tanzlehrerin ohne viel technisches Wissen ist. Ich habe mit Eleventy(https://www.11ty.dev/) auf dem kostenlosen Netlify-Tier eine statische Site erzeugt und benutzerdefinierten Build-Code ergänzt, der Daten aus Google Sheets zieht, damit die Lehrerin kommende Events definieren kann.
Der Bau hat ein gutes Dutzend Stunden gedauert, aber jetzt läuft alles problemlos ohne Betriebs- oder Verwaltungskosten. Dabei habe ich gemerkt, dass es einen starken Sweet Spot zwischen einem absoluten Minimal-Setup und dem Niveau von Rails/Phoenix/Django gibt.
Bei der Zahl der Seiten einer Website ist das allerdings etwas anders, denn die wird fast sicher über 3 liegen, anders als bei der Wahrscheinlichkeit, dass derselbe allgemeine Codeblock dreimal verwendet wird.
Mich interessiert auch, ob die Daten clientseitig über die Google Sheets API geladen werden und, falls ja, ob es eine Cache-Schicht gibt oder ob jeder Client jedes Mal eine neue Kopie bekommt.
Die Debatte über Frameworks und Komplexität ist inzwischen wirklich ermüdend.
Wenn ein Kunde ein Custom-CMS mit mehrstufigem Publishing-Workflow, Internationalisierung und barrierefreier Compliance verlangt, braucht man leistungsfähige Werkzeuge, um das in der erwarteten Zeit zu liefern. Im Enterprise-Bereich gibt es viele solcher Kunden, deshalb ist die Nachfrage nach solchen Tools groß. Wer nur B2C gemacht hat, mag überrascht sein, aber das ist der unter der Wasserlinie liegende Teil des Eisbergs der Tech-Industrie.
Es stimmt, dass man für einen statischen Blog keine komplizierte Next.js-Konfiguration oder Vite-Toolchain braucht. Aber wer diese Tools ernsthaft diskutiert, redet normalerweise nicht darüber, eine einfache Blog-Site zu bauen. Ein Blog mag im Tutorial das heruntergebrochene Beispiel sein, aber das eigentliche Problem ist ein anderes.
Deshalb würde ich mir wünschen, dass dieser Framework-Hass etwas abkühlt. Wenn jemand eine gute Idee hat, wie man Websites einfacher baut, kann er ein Tutorial veröffentlichen, und wenn der Ansatz attraktiv ist, werden Leute ihn an den passenden Stellen einsetzen. Aber bitte nicht immer gegen einen vagen Feind aus „scharfen Toolchains und Hype-Frameworks“ argumentieren.
Oder sie haben lange interne Business-Apps mit zweistelligen Nutzerzahlen und ohne UX-Anforderungen gebaut und halten sich deshalb für allwissend. Solche informationsarmen Urteile verdrängen die eigentliche Diskussion.
Diesmal allerdings ohne Updates für die Person, die den Code später erbt, und ohne einfache Hilfe auf Stack Overflow.
Ich verstehe nicht, warum man nicht je nach Aufgabe unterschiedliche Werkzeuge verwenden dürfen sollte. Es gibt Fälle, in denen kein Framework nötig ist, aber meiner Erfahrung nach sind die selten, sobald man nicht gerade etwas extrem Einfaches und selten Veränderliches baut.
Bei einem Team und einem Kunden fällt es mir schwer, mir vorzustellen, wie eine Website mit „einfachen Tools“ in der Praxis funktionieren soll — nicht als Vorwurf, sondern weil ich es wirklich nicht weiß.
Selbst das hier klingt für mich schon zu komplex.
Ich schreibe die Texte in Gemtext, also Markdown für Gemini, und habe ein Python-Skript gebaut, das sie nach HTML umwandelt und Indexseiten erzeugt.
Das CSS hat nur 42 Zeilen, deshalb habe ich es in jede Seite eingebettet, und ich habe sogar überschlagen, dass die zusätzlichen 42 Zeilen pro Datei nie teurer sein werden als ein zweiter HTTP-Request.
Ohne Python-Bibliotheken oder Templates war das viel einfacher als erwartet. Am schwierigsten war die Erzeugung der E-Mails für die Mailingliste. Ich habe Monate damit verbracht, verschiedene Frameworks und statische Seitengeneratoren zu analysieren, und Wochen damit, brauchbares CSS zu finden.
Laut Git-Historie habe ich zwei Wochen daran herumgehackt, einschließlich der Übernahme von 18 Jahren WordPress-Historie. Da es reines Python ist, musste ich nichts Neues lernen, und wenn es Bugs gibt, kann ich sie leicht beheben oder ändern. Es ist schließlich mein Code.
Informatiker haben völlig vergessen, dass man statt alles wiederverwenden zu wollen auch einfach eine ad-hoc maßgeschneiderte Lösung programmieren kann. Die Zeit fürs Lernen und Anpassen ist größer als die Zeit fürs Selberbauen.
Code: https://git.sr.ht/~lioploum/ploum.net
Website: https://ploum.net
Meine Website wird von einem 6502-Prozessor ausgeliefert, den ich 2003 aus Balsaholz geschnitzt und mit Epoxidharz an ein Ethernet-Kabel geklebt habe. Wenn ich etwas ändern will, erwärme ich das EPROM mit einem Föhn, bis die gewünschten Bits kippen. Keine Templates, kein Code, kein Bloat.
Beim Scrollen nach unten fühlt es sich nostalgisch an, als würde man Technikgeschichte noch einmal durchgehen.
Wenn ich das nicht missverstehe, sieht es nicht wesentlich anders aus als ein durchschnittlicher Static Site Generator. Es wirkt wie der Unterschied zwischen dem Erzeugen von HTML-Dateien mit Python-basierten Jinja-Templates und Jekyll, das HTML-/Markdown-Dateien mit Ruby-basierten Liquid-Templates erzeugt
Eine PHP-Seite für Includes oder ein bestehender Static Site Generator würden für mich deutlich mehr Sinn ergeben
Ich verstehe es nicht. Man wollte keinen Static Site Generator und hat deshalb selbst einen Static Site Generator geschrieben