Dacă ați construit tablouri de bord cu Lucios sau Streamlitcunoașteți modelul: un proces Python sau R rulează pe un server, vă păstrează datele în memorie și reexecută logica aplicației la fiecare interacțiune. Este puternic, dar înseamnă, de asemenea, că aplicația este la fel de rapidă ca și backend-ul său.
Cadrul observabil (și nu sunt plătit pentru că spun ceea ce spun în această postare) are o abordare diferită. În loc să rulați R/Python la cerere
timp, ar putea rula conducta de date o dată la construi timp, apoi expediați un site complet static – HTML, JS și fișiere de date preprocesate. Niciun proces backend nu servește pagina; browserul face randarea. Cu puțin JavaScript, obțineți tablouri de bord care se încarcă ca o pagină web statică, deoarece, după compilare, exact asta sunt.
Codul sursă complet este disponibil la github.com/thierrymoudiki/tips-dashboard.
Blocurile de bază de bază
1. Încărcătoarele de date rulează o dată, la momentul construirii.
Orice fișier sub src/data/ numit (sau .R, .js, .shetc.) se execută în timpul npm run dev / npm run buildiar stdout-ul său devine un fișier de date static:
import sys, pandas as pd
df = pd.read_csv(SOURCE_URL)
df("tip_pct") = (df("tip") / df("total_bill") * 100).round(2)
df.to_csv(sys.stdout, index=False)
Pandas (sau R, sau o interogare de bază de date) pot face munca grea dată. Browserul nu rulează niciodată Python – doar preia fișierul CSV/Parquet rezultat.
2. Paginile sunt Markdown cu JavaScript reactiv încorporat.
const tips = FileAttachment("data/tips.csv").csv({typed: true});
const filtered = tips.filter((d) => day.includes(d.day));
Fiecare bloc de cod JS este reactiv: modificați o intrare și fiecare bloc care face referire la acesta se rulează automat – fără cablare manuală a evenimentelor, fără reîncărcare a paginii întregi.
3. Intrările stării de acționare, generatoarele o expun ca o valoare reactivă.
const dayInput = Inputs.checkbox(("Thur", "Fri", "Sat", "Sun"), {value: ("Thur", "Fri", "Sat", "Sun")});
const day = Generators.input(dayInput);
4. Observable Plot redă diagramele declarativsimilar în spirit cu gramatica grafică a lui ggplot2, dar nativ pentru JS:
Plot.plot({
marks: (
Plot.dot(filtered, {x: "total_bill", y: "tip", fill: "smoker", tip: true}),
Plot.linearRegressionY(filtered, {x: "total_bill", y: "tip"})
)
});
De ce contează acest lucru pentru timpii de încărcare
Într-o aplicație tipică Shiny/Streamlit, prima vopsea așteaptă: pornirea serverului, inițierea sesiunii R/Python și adesea o încărcare completă a datelor în memorie – de fiecare dată când începe o nouă sesiune, cu excepția cazului în care ați investit în infrastructura de stocare în cache. În Observable Framework, întreaga conductă a avut loc deja în timpul construirii. Browserul vizitatorului descarcă active statice și un fișier de date preprocesat, apoi JS preia controlul – comparabil cu încărcarea oricărui alt site static.
Compensația este reală: pierzi capacitatea de a rula calcul arbitrar pe partea de server per cerere (inferență de model în direct, interogări de bază de date per utilizator) dacă nu adăugați un backend separat. Dar pentru cazul foarte obișnuit – luați niște date tabulare, curățați-le, lăsați utilizatorii să le filtreze și să le exploreze – Framework vă oferă un rezultat mai clar, cu o infrastructură mai mică.
Încearcă
Un exemplu minim: un tablou de bord cu sfaturi pentru restaurante cu un încărcător Python (pandas), filtre reactive (Inputs.checkbox/Inputs.radio), și patru diagrame Plot, construite și implementate ca site static cu
npm run build. Întregul strat interactiv este sub 100 de linii de Markdown + JS – niciun server de gestionat după implementare.
Codul sursă complet este disponibil la github.com/thierrymoudiki/tips-dashboard.

