DEV Community

Nevik Schmidt
Nevik Schmidt

Posted on

Ich habe einen kostenlosen Strompreis-Rechner gebaut — hier sind die echten Daten

Ich habe einen kostenlosen Strompreis-Rechner gebaut — hier sind die echten Daten

Wer in Deutschland Strom bezieht, zahlt nicht einfach nur für die Kilowattstunde. Der Strompreis ist ein komplexes Konstrukt aus Netzentgelten, Abgaben, Steuern und Umlagen — und genau diese Transparenz fehlt den meisten Verbrauchern. Deshalb habe ich einen interaktiven Strompreis-Rechner gebaut, der den vollständigen Preis-Breakdown visualisiert.

👉 Live-Demo: strom.nevik.de/strompreis-rechner

In diesem Artikel zeige ich dir, wie der Rechner technisch funktioniert, welche Architektur dahintersteckt und wie du einen ähnlichen interaktiven Visualisierungs-Rechner selbst bauen kannst.


Das Problem: Strompreistransparenz in Deutschland

Der durchschnittliche Strompreis in Deutschland lag 2024 bei rund 40 Cent pro kWh. Aber was steckt in diesen 40 Cent? Hier ist der typische Breakdown:

Komponente Anteil Cent/kWh
Strombeschaffung & Vertrieb ~25% ~10,0
Netzentgelte ~22% ~8,8
Mehrwertsteuer (19%) ~16% ~6,4
Stromsteuer ~14% ~5,6
Konzessionsabgabe ~5% ~2,0
KWK-Umlage & Sonstige ~18% ~7,2

Diese Zahlen ändern sich regional und saisonal. Genau hier setzt mein Rechner an: Er nutzt aktuelle, tagesaktuelle Daten über eine eigene API und berechnet den Breakdown dynamisch.


Die Architektur: Vanilla JS + SVG statt Framework-Overhead

Ich habe bewusst auf ein schweres Framework verzichtet. Der Rechner besteht aus:

  1. Vanilla JavaScript (~400 Zeilen) — keine Build-Tools, kein npm
  2. SVG-Charts — handgezeichnet, keine Charting-Library
  3. CSS Custom Properties — für theming und Animationen
  4. Fetch-API — für die Datenanbindung an meine eigene Strompreis-API

Warum kein React oder Vue? Für einen Single-Purpose-Rechner ist das Overkill. Die Seite lädt in unter 200ms, und der gesamte Code ist in einer einzigen HTML-Datei verständlich.


Der interaktive Breakdown-Rechner

Das Herzstück ist der Slider, mit dem Nutzer ihren Jahresverbrauch einstellen. Bei jeder Änderung wird der komplette Breakdown neu berechnet und animiert.

Hier ist die Kernlogik:

// Strompreis-Breakdown berechnen
function calculateBreakdown(consumptionKwh, pricePerKwh) {
  const total = consumptionKwh * pricePerKwh;

  // Prozentsätze basierend auf BNetzA-Daten
  const breakdown = {
    strombeschaffung: total * 0.25,
    netzentgelte: total * 0.22,
    mehrwertsteuer: total * 0.16,
    stromsteuer: total * 0.14,
    konzessionsabgabe: total * 0.05,
    sonstige: total * 0.18
  };

  return breakdown;
}

// Slider-Event verarbeiten
const slider = document.getElementById('consumption-slider');

slider.addEventListener('input', (e) => {
  const kwh = parseInt(e.target.value);
  const price = await fetchCurrentPrice();
  const breakdown = calculateBreakdown(kwh, price);

  renderSVGChart(breakdown);
  renderCostTable(breakdown);
});
Enter fullscreen mode Exit fullscreen mode

Die Magie passiert im Event-Listener: Jede Slider-Bewegung triggert eine Neuberechnung und ein re-render des SVG-Charts.


SVG-Charts von Hand bauen

Die meisten Entwickler greifen bei Charts sofort zu Chart.js, D3 oder Recharts. Für diesen Rechner wollte ich volle Kontrolle über die Animationen — also habe ich das SVG direkt generiert.

Ein animiertes Balkendiagramm mit Vanilla JS sieht so aus:

function renderSVGChart(breakdown) {
  const svg = document.getElementById('price-chart');
  const max = Math.max(...Object.values(breakdown));
  const barWidth = 60;
  const gap = 20;
  const chartHeight = 300;

  let html = '';
  let x = 20;

  for (const [label, value] of Object.entries(breakdown)) {
    const barHeight = (value / max) * chartHeight;
    const y = chartHeight - barHeight;

    html += `
      <rect x="${x}" y="${y}" width="${barWidth}" height="${barHeight}"
            fill="url(#bar-gradient)" rx="4"
            style="transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);">
        <animate attributeName="height" from="0" to="${barHeight}" dur="0.6s"/>
      </rect>
      <text x="${x + barWidth/2}" y="${chartHeight + 20}" 
            text-anchor="middle" fill="#666" font-size="12">
        ${formatLabel(label)}
      </text>
    `;
    x += barWidth + gap;
  }

  svg.innerHTML = html;
}
Enter fullscreen mode Exit fullscreen mode

Der Vorteil: Die Animation läuft über CSS-Transitions und das SVG <animate>-Element, was buttery smooth läuft — ohne JavaScript-Animation-Loop.


Die Datenquelle: Eine eigene Strompreis-API

Der Rechner wäre ohne aktuelle Daten wertlos. Deshalb betreibe ich eine eigene kostenlose Strompreis-API mit tagesaktuellen Durchschnittspreisen für Deutschland.

Die API ist CORS-enabled und liefert sauberes JSON:

curl https://strom.nevik.de/api/
Enter fullscreen mode Exit fullscreen mode
{
  "strompreis_ct_kwh": 39.42,
  "strompreis_eur_kwh": 0.3942,
  "datum": "2025-01-15",
  "quelle": "BNetzA, SMARD, EEX",
  "aufschluesselung": {
    "strombeschaffung_vertrieb": { "prozent": 25.0, "ct_kwh": 9.85 },
    "netzentgelte": { "prozent": 22.0, "ct_kwh": 8.67 },
    "mehrwertsteuer": { "prozent": 16.0, "ct_kwh": 6.31 }
  }
}
``"

Die API hat drei Endpoints und ist komplett kostenlos nutzbar. Mehr Details dazu in meinem nächsten Artikel: [Wie ich eine kostenlose Strompreis-API für Deutschland gebaut habe](#).

---

## UX-Details, die den Unterschied machen

Ein guter Rechner ist mehr als nur Mathematik. Hier sind Designentscheidungen, die die Nutzererfahrung deutlich verbessern:

### 1. Sofortiges Feedback beim Slider

Jede Bewegung aktualisiert die Visualisierung in Echtzeit. Kein "Berechnen"-Button, keine Ladeanimation. Das Gehirn sucht nach Cause-and-Effect — und der Slider liefert es sofort.

### 2. Vergleichswerte als Kontext

Ein isolierter Zahlenwert ist bedeutungslos. Deshalb zeigt der Rechner immer Vergleichswerte:

- *"Das ist X% mehr als der Bundesdurchschnitt"*
- *"Entspricht dem Verbrauch von Y Haushalten"*
- *"CO₂-Äquivalent: Z kg"*

### 3. Animierter Zahlen-Countup

Wenn sich der Wert ändert, zählt er nicht einfach um — er animiert vom alten zum neuen Wert:

Enter fullscreen mode Exit fullscreen mode


javascript
function animateValue(element, start, end, duration = 600) {
const range = end - start;
const startTime = performance.now();

function update(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
// easeOutCubic für angenehme Animation
const eased = 1 - Math.pow(1 - progress, 3);
const current = start + range * eased;

element.textContent = current.toFixed(2) + ' €';

if (progress < 1) requestAnimationFrame(update);
Enter fullscreen mode Exit fullscreen mode

}

requestAnimationFrame(update);
}


### 4. Mobile-First responsive

Der Rechner funktioniert auf dem Smartphone genauso gut wie am Desktop. Die SVG-Charts skalieren über `viewBox` automatisch, und der Slider ist touch-optimiert mit `input[type=range]`.

---

## Performance: 0.2 Sekunden Ladezeit

Hier ist der Performance-Check:

| Metrik | Wert |
|---|---|
| First Contentful Paint | ~180ms |
| Time to Interactive | ~220ms |
| Total bundle size | < 15 KB (ungezippt) |
| JavaScript payload | ~8 KB |
| External dependencies | 0 |

Keine Frameworks, keine Build-Tools, keine Dependencies. Das ist möglich, wenn man bewusst auf Komplexität verzichtet.

---

## Technische Herausforderungen

### Herausforderung 1: Datenaktualität ohne Caching-Probleme

Strompreise ändern sich nicht sekündlich, aber Nutzer erwarten aktuelle Daten. Die Lösung: Die API cached serverseitig für 1 Stunde mit klar definierten Cache-Headers:

Enter fullscreen mode Exit fullscreen mode


http
Cache-Control: public, max-age=3600
Stale-while-revalidate: 86400


### Herausforderung 2: SVG-Animationen performant halten

Bei schnellen Slider-Bewegungen kann die SVG-Regeneration zum Performance-Bottleneck werden. Die Lösung: **Debouncing** mit `requestAnimationFrame`:

Enter fullscreen mode Exit fullscreen mode


javascript
let rafId = null;

function debouncedRender(breakdown) {
if (rafId) cancelAnimationFrame(rafId);
rafId = requestAnimationFrame(() => {
renderSVGChart(breakdown);
rafId = null;
});
}




So werden nur Render-Cycles ausgeführt, die auch wirklich auf dem Bildschirm landen.

---

## Was du für deinen eigenen Rechner brauchst

Wenn du einen ähnlichen interaktiven Rechner bauen willst — egal ob für Strompreis, Heizkosten oder Steuerlast — hier ist der minimale Stack:

1. **HTML** mit einem `<input type="range">` und einem leeren `<svg>`
2. **Vanilla JS** mit Fetch + Event Listeners (~200 Zeilen)
3. **Eine Datenquelle** (eigene API oder statische JSON-Datei)
4. **CSS-Transitions** für Animationen
5. **Keine Build-Tools** — einfach eine `.html`-Datei

Der gesamte Code meines Rechners ist weniger als 400 Zeilen JavaScript. Du kannst das Konzept auf jeden Datensatz übertragen.

---

## Fazit und nächste Schritte

Der Strompreis-Rechner auf [strom.nevik.de/strompreis-rechner](https://strom.nevik.de/strompreis-rechner/) zeigt, dass man für datengetriebene Web-Tools keine schweren Frameworks braucht. Mit Vanilla JS, SVG und einer soliden Daten-API lassen sich beeindruckende interaktive Visualisierungen bauen.

Die wichtigsten Takeaways:

- **Transparenz schafft Vertrauen** — Nutzer verstehen ihren Strompreis besser, wenn sie den Breakdown sehen
- **Echtzeit-Interaktion** ist mit Vanilla JS problemlos möglich
- **SVG-Charts von Hand** geben volle Kontrolle über Animationen und Styling
- **Eine gute Datenquelle** ist die halbe Miete

Wenn dich die API hinter dem Rechner interessiert, lies meinen Artikel über den Bau der Strompreis-API. Und probiere den Rechner selbst aus:

🔗 **[Strompreis-Rechner ausprobieren](https://strom.nevik.de/strompreis-rechner/)**

🔗 **[Strompreis-API Dokumentation](https://strom.nevik.de/api/)**

Wenn du Fragen zum Code oder zur Architektur hast, schreib gerne einen Kommentar. Ich erkläre gerne jedes Detail.

---

*Viel Spaß beim Strompreise vergleichen und beim Bauen eigener interaktiver Rechner!*
Enter fullscreen mode Exit fullscreen mode

Top comments (0)