This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Friday, 24 July 2026
Comment livrer des réponses rapides pour des tableaux de bord complexes sans être dérangés? Vous cessez de les rendre sur le chemin de la demande.
Un tableau de bord est un type de page trompeurment coûteux.

L’opérateur voit un seul tableau de bord; le serveur voit des listes en direct et des vues à fenêtres coûteuses - les agrégats mobiles
flowchart TB
P[One dashboard page] --> H[Headline counters]
P --> T[Time-series chart]
P --> B[Top bots]
P --> E[Top content pages]
P --> C[Countries / filters]
H --> M[Shared hydrated page model]
T --> M
B --> M
E --> M
C --> M
M --> S[Versioned widget shingles]
S --> U[Independent HTMX OOB updates]
classDef outline stroke:#cbd5e1,stroke-width:1.5px;
classDef emphasis stroke:#38bdf8,stroke-width:2px;
class P,H,T,B,E,C,M,S,U outline;
class M,S,U emphasis;
linkStyle default stroke:#94a3b8,stroke-width:1.3px;
L’application ASP.NET connue permet à chaque widget de saisir ses propres données , d’amorcer ces appels en parallèle , puis d’attendre tous ceux-ci avant de rendre la page
flowchart LR
R[One page request] --> W1[Summary query]
R --> W2[Time-series query]
R --> W3[Countries query]
R --> W4[Endpoints query]
R --> W5[Bot query]
W1 --> J[Task.WhenAll]
W2 --> J
W3 --> J
W4 --> J
W5 --> J
J --> V[Render response]
classDef outline stroke:#cbd5e1,stroke-width:1.5px;
classDef danger stroke:#fb7185,stroke-width:2px;
class R,W1,W2,W3,W4,W5,V outline;
class J danger;
linkStyle default stroke:#94a3b8,stroke-width:1.3px;
Il apparaît rapidement avec une personne et un petit ensemble de données : neuf appels indépendants se chevauchent , de sorte que la page prend environ aussi longtemps que son widget le plus lente plutôt que leur somme
À l’égard de la Stylo.Bot dashboard, une charge normale de page signifiait environ neuf appels parallèles à travers le site–/bordement de la passerelle–. La vue d’aujourd’hui pouvait parcourir plus d’un million de rangéesM SK4 Une seule charge silencieuse était déjà multipleMSC5seconde. Sous un trafic concomitante , le pMST8 a passé sept secondes+, parce que la page attendait Task.WhenAll d’environ dix opérations coûteuses et chaque visiteur a commencé une autre dizaine
Le parallèle est utile. Par - fan de demandes- la sortie est le problèmeM SK3 À cinq téléspectateurs concurrents , neuf appels sont devenus quarante MSC5 cinq appels concurrents~ . A cinquante téléspectators il s’agit de quatre cent cinquant M SK7 La base de données de connexion voit une tempête croissante d’activités indépendantement coûteuses.
Fan parallèle-out permet de faire apparaître plus rapidement une seule demande en multipliant la pression qui détruit le système sous charge.
Ce n’est pas la bonne courbe d’échelle pour un tableaux de bord.
Signal Shingle traite chaque widget du tableau de bord comme un fragment de page préliminaire.
Son empreinte digitale est simplement widget + normalised parameters + data-surface generation. Une mise à jour de pays ne doit pas invalider une carte d’affichage en direct -viseurs; un filtre modifié ne devrait pas faire froid tous les autres widgets
Ces fragments vivent dans un cache LFU limité. Les lectures chaudes conservent les widgets surveillés résidents
SignalR dit qu'une surface a changé; le client demande la quantité affectée de widgetsM SK1 HTMX applique les fragments de bande retournés-ofMSC3avec IdiomorpheMNK4 Le signal porte un indice nuisible , jamais une copie des données du tableaux de bordMMK6
Dans le modèle, signal signifie “considérer la mise à jourM SK1 Établissement d'un réseau de distribution est le résultat adressable indépendamment.
Rendre-Les seuls shingles à côté sont insuffisants. Si chaque erreur déclenche un nouveau scan de base de données , le travail coûteux reste en placeM SK3 Le signal Shingle utilise une cache de deux niveaux - avec une main délibérément étroite
flowchart LR
D[Gateway<br/>authoritative events] --> B[Incremental window buckets<br/>data stays single-source]
B --> C[Level 1 : content cache<br/>hydrated page result]
C --> S[Level 2 : shingle cache<br/>versioned OOB widget HTML]
S --> R[Request path<br/>read + Razor shell]
T[Schedule tick/poll + LFU demand] --> W[Bounded prewarm waves]
W --> B
W --> C
X[Coalesced SignalR dirty beacon] --> U[HTMX batch update]
U --> S
classDef outline stroke:#cbd5e1,stroke-width:1.5px;
classDef emphasis stroke:#38bdf8,stroke-width:2px;
class D,B,C,S,R,T,W,X,U outline;
class C,S,W emphasis;
linkStyle default stroke:#94a3b8,stroke-width:1.3px;
La distinction est faite entre un Modèle et son rendu unités de livraison des widgets. Aucun cache ne devient une autorité pour les données de détectionM SK1
La passerelle est propriétaire des données. Elle contient une projection LFU limitée de buckets à fenêtres incrémentales M SK3 dans la mémoire - avec une rétention journalière de glissement 30-, un ensemble de travail, et non un deuxième entrepôt de données.
Utiliser des buckets fins pour six -horaires et 24-charts d'heuresM SK2 roulement horaire pour les fenêtres longues . Le point est qu'une fenêtre demandée fusionne les buquets plutôt que de le répéter.
last 24 hours → merge 288 five-minute buckets
last 30 days → merge 720 hourly buckets
not
last 30 days → scan and aggregate 1,000,000+ event rows again
Nouvelles observations mettent à jour la plus récente bucket. La partie historique n’est pas réexaminéeM SK1 parce qu’une page a été chargée . La passerelle demeure le seul écrivain et le seul endroit qui décide ce que signifie une détection.
En amont, le site web cache les modèles de tableaux de bord hydratés , clé par un ensemble de widgets normalisésM SK2 fenêtre, filtres et générationMSC4 Il permet d’établir des liens entre les données authentiques et la traduction
Cacher un modèle plutôt que le HTML complet permet de conserver les valeurs du CSRF, chrome d'authentification , drapeaux et nonces des fonctionnalités sur la demandeM SK2 coque remise où elles appartiennent.
Sur une clé froide, retourner un état de réchauffement clair plutôt que de recomputer synchronement. Seul le matérialisateur tick obtient un nouveau résultat de pageM SK2 Les lectures ultérieures servent la dernière génération réussie , même alors qu’une nouvelle est en volMSC4
Le tableau de bord est délibérément divisé : la passerelle détient les données ; le site Web détient Razor et la relation avec le navigateur
Une fois que le modèle de page existe, un widget peut être rendu comme élément OOB et détenu dans la cache de sangle LFU délimitée avec une sécurité TTL. Un sangle chaud passe à côté tant de la composition qu’au rendering RazorM SK2 une erreur lit le résultat de page déjà -de page chaude lorsque possibleMSC4 ne rend que ce widget hx-swap-oob="morph", et stocke le résultat sous son empreinte digitale
Le point final du lot partitionne les widgets en empreintes digitales chaudes et erreurs.
Ce n'est pas un caching redundant. Niveau 1 réponses “qui est le modèle cohérent de tableaux de bordM SK3 Niveau
Le cache de réponse vaut la peine d’être comparé directement. Un cache normal de réponse stocke une réponse HTTP opaque; Des widgets cachés indépendamment développent des modes d’expiration et de défaillance indépendants . La page peut être chargée rapidement alors qu’elle ne décrit plus un état cohérent.
Les modèles de cache connus sont tous utiles. Ils protègent simplement les différentes frontières :
| Méthode | Ce qu'il stocke MSC2 Le meilleur emplacement MSC3 Pourquoi il n'est pas suffisant par lui-même ici SMC4 | |||||
|---|---|---|---|---|---|---|
| Cache de réponse HTTP | Réponse HTTP, normalement saisie par URL et demandeM SK3règles variables ♫ | Points d'entrée publics GET et CDN ♫ | ||||
| ASP.Cache de sortie NET | Produit du serveur généréM SK3 avec politique explicite de variation et d'évacuation | Pages coûteuses avec une petite demande stable | , | Requête stable - | espace de clé | |
| DonutM SK1 trou / cache de fragments | Une coque cachée avec des trous dynamiques, ou fragments cachés indépendamment ♫ | Pages dont le chrome est stable et dont les petites régions dynamices sont véritablement indépendantes ♫ | Il fait à chaque trou son propre cycle de vie du cache ♫ | |||
| Signal Shingle | Une génération hydratée,M SK3modal de page assortie de fragments versionnés d'un widget de livraison | Un tableau de bord dont les parties doivent être mises à jour indépendamment et Continuer à décrire un état | La limite du cache est la projection composite ; les échelons sont dérivés de celle-ci |
Niveau-2 shingles sont un cache de sortie, délibérément petit et fragmentéM SK1 en forme de . La différence est que les fragments ne déterminent pas la réalité des données indépendamment. Le modèle du contenu est constitué d’abord , sous une seule générationMSC5 chaque shingle est un rendering de ce modèle
flowchart LR
D[One authoritative<br/>gateway dataset] --> G[Generation 184]
G --> M[One hydrated<br/>page model]
M --> H[Headline shingle<br/>generation 184]
M --> T[Chart shingle<br/>generation 184]
M --> B[Bot-list shingle<br/>generation 184]
M --> C[Country shingle<br/>generation 184]
H --> P[One coherent page]
T --> P
B --> P
C --> P
classDef outline stroke:#cbd5e1,stroke-width:1.5px;
classDef emphasis stroke:#38bdf8,stroke-width:2px;
class D,G,M,H,T,B,C,P outline;
class G,M,P emphasis;
linkStyle default stroke:#94a3b8,stroke-width:1.3px;
Lorsque les données changent, la composition affectée reçoit une nouvelle génération.1 Un navigateur peut voir brièvement celle précédente alors qu’une mise à jour est en vol.2 Mais cette âge est explicite et limité.3 Il n’est jamais un ensemble séparé de caches appartenant à - qui font des allégations contradictoires au sujet de “.
Une autorité, une génération composée, plusieurs fragments de livraison réutilisablesM SK2
Signal Shingle n'est pas une API JSON avec un client- panneau de bord peint sur le dessus . Le Stylo.Boot de bord est la première Razor SSR MSC3 compteurs significatifsM SK4 tableauxMNK5 tables MNK6 liens et navigation avant que JavaScript ne fonctionneMRK7 HTMXMMK8 SignalR et Alpine améliorent ensuite cette page plutôt qu'en la remplaçant.
flowchart LR
R[GET dashboard] --> S[Razor SSR<br/>complete useful HTML]
S --> V[Operator can read<br/>and navigate now]
S --> H[HTMX enhancement]
S --> A[Alpine enhancement]
S --> G[SignalR enhancement]
G --> D[Dirty beacon<br/>not dashboard JSON]
D --> H
H --> O[GET OOB widget batch]
O --> W[Versioned HTML shingles]
W --> M[HTMX / Idiomorph morph]
A --> I[Local UI state<br/>menus, filters, affordances]
classDef outline stroke:#cbd5e1,stroke-width:1.5px;
classDef emphasis stroke:#38bdf8,stroke-width:2px;
class R,S,V,H,A,G,D,O,W,M,I outline;
class S,W,M emphasis;
linkStyle default stroke:#94a3b8,stroke-width:1.3px;
HTMX demande le HTML et échange l'île retournée. SignalR fournit un petit signal polluant plutôt que les modèles JSONM SK1 Alpine possède l'état local de l'interface : menus , toggles et prix qui ne méritent pas une rondeMSC4tripMNK5 Retirer n'importe lequel d'entre eux et la page SSR reste utileMST6 ajouter tous les trois et elle gagne en temps réelMSL7 faibleMS- mise à jour des bureauxMSV9
Le renouvellement se produit à l’extérieur de la demande de page. Il s’agit d’une limite dure : une lecture froide retourne un résultat de réchauffementM SK2 alors que seul le matérialisateur tick compose . La demande de pages est une lecture d’un projet cohérentMSC4 jamais une excuse pour commencer un travail coûteux sur les donnéesMNK5
Les coordonnateurs se sont rangés et, récemment, les enveloppes ont été lues. Task.WhenAll portant un nouveau nom.
La limite de coïncidence fait partie de la correction : le boucle refresh obtient un budget de capacité connuM SK1 jamais un ensemble sans limites de connexions. Une mise à jour pleinement chaude n’a aucune composition ou rendering Razor en tout
Orchestre, non une tempêteM SK1 C’est la règle opérationnelle.
Un cache ne peut pas protéger la première demande si elle se réchauffe seulement après que la demande arrive. Le matérialisateur a donc deux tâches. Défaults de pinnage conserver les choix de fenêtres réelles 6hM SK1 24h+, \7d et \ 30d chaudes Demande-enveloppes comptabilisées filtres de couverture que les gens utilisent réellement, classé par nombre d'accès et recevabilitéM SK1 Une seule demande réelle permet de garder une personne vivante.
flowchart TB
P[Pinned default windows<br/>6h · 24h · 7d · 30d] --> Q[Warm queue]
L[Recently read filtered views<br/>LFU hotness order] --> Q
Q --> G{Tick budget<br/>still available?}
G -->|yes| W[Bounded warm wave<br/>compose once, store model]
G -->|no| N[Defer to next tick<br/>serve prior generation]
W --> H[Level 1 content cache]
H --> Z[Level 2 shingle cache<br/>rendered on demand]
classDef outline stroke:#cbd5e1,stroke-width:1.5px;
classDef emphasis stroke:#38bdf8,stroke-width:2px;
class P,L,Q,G,W,N,H,Z outline;
class Q,W,H emphasis;
linkStyle default stroke:#94a3b8,stroke-width:1.3px;
Le préchauffage doit correspondre à la surface réelle du produit. Si l’interface offre quatre fenêtres normales et que le chauffeur en sait une, les trois quarts de la première fenêtre attendue -le chemin de clique est encore froidM SK3
LFU est plus que l’évacuation ici. Accès est le signal de la demande : il décide ce qui reste résident , qui se rafraîchère d’abord par les travaux requisM SK3 et ce qui peut disparaître en toute sécuritéMSC4 Ce qui rend l’espace de filtre sans limites géréableMska5 Un filtre de pays surveillé tout le jour demeure chaudM Ska6 un filtre essayé une fois vieillissanteM ska7 Il n’y a pas de tableau distinct Mska8tableau populaire M Ska9 table nécessaireMSKA10
Les tableaux live traditionnels réagissent à un plus grand trafic en faisant davantage de travail, alors ils deviennent moins utiles au point où les opérateurs les ont le plus besoin . Le signal Shingle inverse cette relation. Le contrôleur de rafraîchissement mesure le coût du rafraichement par rapport à un budgetM SK3 les cycles coûteux prolongent des intervalles efficacesMSC4 ceux peu coûteux contractent vers la cadence requiseMST5
refresh cost <= budget → preserve requested cadence
refresh cost > budget → lengthen effective cadence
cost settles → cautiously shorten it again
Il s’agit d’une boucle fermée sur la ressource protégée.
La charge rend le tableau de bord moins efficace, non plus. C'est pourquoi le modèle décroît plutôt que s'effondre
Il s’agit de la dernière projection cohérente connue.
La moitié statique est le contrat de réponse : un snapshot cohérent à partir des niveaux du cacheM SK2 la moitié dynamique est un procédé budgétaire distinct : scheduler- contrôles dûment dirigésMSC5 accélération optionnelle SignalR pour les widgets vivantsMST6 et réconnexion resyncMst7 La réponse demeure rapide même lorsque le snapshot devient plus vieuxM st8 et l'âge reste visibleMstr9
Ainsi, le système peut glisser continuellement entre deux modes utiles:
quiet / cheap refreshes → dynamic dashboard, short effective cadences
busy / expensive refreshes → static-like snapshot, longer declared cadences
Il s’agit d’une escalation adaptative intégrée à l’architecture.
Non tous les widgets méritent la même fraîcheur. Un graphe de tendance ou un classement des points culminants peut être à quelques minutes ou une heure de retard ; Une liste des visiteurs récents ou des notes courantes a besoin d’une cadence plus étroite
| Classe | Widgets typiques MSC2 Cadence de base MSC3 Pourquoi SMC4 | ||
|---|---|---|---|
| Sommaire | Synthèse, TendancesM SK3 PaysMSC4 Points finals MSC5 minutes à l’heure MSC6 Le signal change assez lentement pour que la stabilité soit plus précieuse qu’une agitation. | ||
| En direct | visiteurs récentsM SK2 séances , noms+, points=, menaces | environ une minute | L'opérateur cherche le mouvement courant |
Deux widgets visiblement identiques peuvent demander des cadences différentes. Mettre la cadence dans la clé de cache dupliquait les données
L'invariante est simple:
Une entrée de cache partagée ne doit jamais servir un staler que par l’un ou l’autre de ses consommateurs actifs demandés.
Formellement:
effective cadence(entry) = MIN(requested cadence of every active consumer)
Cadence est un consommateur par plancher, ne fait pas partie de la signatureM SK1 Si un consommateur demande 60 secondes et un autre pour cinq minutes M SK3 une entrée partagée rafraîchère chaque
Un système adaptatif doit être honnête quant à son adaptation. Le chrome de widget montre la cadence efficace actuelle M SK1 “à jour tous les SSK3s”, \“à date de toutes les données 5mMSC7 | | “ |
Il faut quelques règles pour garder une projection honnête:
Il s’agit d’une projection dont l’âge et la génération sont limités.
Voici l’ensemble du commerce dans un tableau
| Per-request fanM SK3out MSC4 Signal Shingle double couche S | ||
|---|---|---|
| Demande de page | Démarre le prélèvement et l'attente des données N | Lecte un modèle prêt/chunk et rend la coque M |
| Travaux de données | Réponses par visiteur | partagésM SK3 incrémentales, bouclierMSC5remboursé M |
| Mise à jour des widgets | Chaque widget peut être téléchargé indépendamment de lui-même. | |
| Concurrence | Task.WhenAll élargit avec le trafic |
ondes de rafraîchissement limitées avec un budget de coût mesuré |
| Vues filtrées | Non cachés ou non liés SSK2 Combinations chaudes demeurent vivantesM SK3 froides LFU- évités | |
| Réponse à la charge | Plus de trafic crée plus de travail | |
| Frique | Implicite et souvent incohérente | Explicite par widgetM SK3 min- sécuritaire pour les entrées partagées M |
| Modèle d'échec | Demandes lentesM SK2 Épuisement du bassin, Collapse MSC4 Projection plus ancienne mais marquéeMSC5 Travail limité SMC6 |
Signal Shingle compose des pièces d’ASP connues.NET : un LFU, SignalRM SK3 composition en lotsMSC4 RazorMNK5 HTMX et un calendrier avec un budget de convergence réelleMRK6 La passerelle demeure authentiqueMMK7 le site web dessert une projectionMBK8 le navigateur reçoit des fragments de petites versionsMZK9
Déplacer la reproduction hors du chemin de demande. Laisser fonctionner le travail de réfrigération des gouttelettes de charge plutôt que la réponse.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.