Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ ul.tick li::before {
content: "→"; position: absolute; left: 0; color: var(--accent);
}

/* ---- the round-trip sequence diagrams (mermaid) ---- */
/* ---- the round-trip sequence diagrams ---- */
.seq { display: grid; gap: 18px; margin: 20px 0; }
.seqcol {
border: 1px solid var(--line); border-left-width: 4px; border-radius: 8px;
Expand All @@ -152,11 +152,19 @@ ul.tick li::before {
.seqcol h4 { margin: 0 0 14px; font-size: 13px; letter-spacing: .04em; }
.seqcol.bad h4 { color: var(--warn); }
.seqcol.good h4 { color: var(--accent); }
/* before mermaid runs, .mermaid is a <pre>; reset the code-block chrome */
.seqcol .mermaid {
background: none; border: 0; padding: 0; margin: 0; overflow-x: auto;
text-align: center; color: var(--fg-faint); font-size: 12px; line-height: 1.45;
/* step-flow: one row per hop, no lifelines to overlap */
.flow { list-style: none; margin: 0; padding: 0; }
.flow li { display: flex; gap: 12px; align-items: baseline; padding: 4px 0; font-size: 13px; color: var(--fg); }
.flow .hop {
flex: 0 0 76px; text-align: right; white-space: nowrap;
font-family: var(--mono); font-size: 11.5px; color: var(--fg-dim);
}
.flow li.phase {
display: block; margin: 12px 0 4px; font-size: 11px;
text-transform: uppercase; letter-spacing: .1em; color: var(--fg-faint);
}
.flow li.phase:first-child { margin-top: 0; }
.flow li.learn { display: block; color: var(--warn); font-size: 12.5px; padding: 6px 0 2px; }
.seqcol .verdict { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--line); }
.seqcol.bad .verdict { color: var(--warn); }
.seqcol.good .verdict { color: var(--accent); }
Expand Down
90 changes: 18 additions & 72 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -142,23 +142,17 @@ <h2>the wasted round trip</h2>
<div class="seq">
<div class="seqcol bad">
<h4>HTTP/3 advertised only via the Alt-Svc HTTP header</h4>
<pre class="mermaid">
sequenceDiagram
participant C as Client
participant D as DNS
participant S as Your server
Note over C,S: First connection
C->>D: look up A / AAAA
D-->>C: IP address
C->>S: TCP + TLS handshake
S-->>C: connected (HTTP/2)
C->>S: HTTP/2 request
S-->>C: response + Alt-Svc: h3
Note over C,S: only now does the client learn you speak HTTP/3
Note over C,S: Second connection
C->>S: QUIC + HTTP/3 handshake
S-->>C: connected (HTTP/3)
</pre>
<ol class="flow">
<li class="phase">first connection</li>
<li><span class="hop">&rarr; DNS</span><span>look up A / AAAA</span></li>
<li><span class="hop">&larr; DNS</span><span>IP address</span></li>
<li><span class="hop">&harr; server</span><span>TCP + TLS handshake, now on HTTP/2</span></li>
<li><span class="hop">&rarr; server</span><span>HTTP/2 request</span></li>
<li><span class="hop">&larr; server</span><span>response + <b>Alt-Svc: h3</b></span></li>
<li class="learn">only now does the client learn you speak HTTP/3</li>
<li class="phase">second connection</li>
<li><span class="hop">&harr; server</span><span>QUIC + HTTP/3 handshake, now on HTTP/3</span></li>
</ol>
<div class="verdict">HTTP/3 only on the second connection.</div>
</div>
<p>
Expand All @@ -171,19 +165,13 @@ <h4>HTTP/3 advertised only via the Alt-Svc HTTP header</h4>
</p>
<div class="seqcol good">
<h4>HTTP/3 advertised in an HTTPS DNS record</h4>
<pre class="mermaid">
sequenceDiagram
participant C as Client
participant D as DNS
participant S as Your server
Note over C,S: First connection
C->>D: look up HTTPS record
D-->>C: alpn=h3 + IP hints (+ ECH)
C->>S: QUIC + HTTP/3 handshake
S-->>C: connected (HTTP/3)
C->>S: HTTP/3 request
S-->>C: response
</pre>
<ol class="flow">
<li class="phase">first connection</li>
<li><span class="hop">&rarr; DNS</span><span>look up HTTPS record</span></li>
<li><span class="hop">&larr; DNS</span><span><b>alpn=h3</b> + IP hints (+ ECH)</span></li>
<li><span class="hop">&harr; server</span><span>QUIC + HTTP/3 handshake, now on HTTP/3</span></li>
<li><span class="hop">&rarr; server</span><span>HTTP/3 request</span></li>
</ol>
<div class="verdict">HTTP/3 right away, on the first connection.</div>
</div>
</div>
Expand Down Expand Up @@ -415,47 +403,5 @@ <h3>Should I drop the <code>Alt-Svc</code> header?</h3>
<script src="js/charts.js"></script>
<script src="js/rtt.js"></script>
<script src="js/lookup.js"></script>
<script type="module">
// Mermaid renders the two sequence diagrams. It's a ~1MB CDN module, so we
// only fetch it once the diagrams are about to scroll into view. If it never
// loads, the raw diagram source stays visible as a readable fallback.
let loaded = false;
async function renderDiagrams() {
if (loaded) return;
loaded = true;
try {
const { default: mermaid } = await import(
"https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs"
);
const dark = window.matchMedia("(prefers-color-scheme: dark)").matches;
mermaid.initialize({
startOnLoad: false,
theme: dark ? "dark" : "default",
securityLevel: "loose",
fontFamily: "var(--mono)",
sequence: { useMaxWidth: true, mirrorActors: false },
});
await mermaid.run({ querySelector: ".mermaid" });
} catch (e) {
/* leave the source text visible */
}
}

const seq = document.querySelector(".seq");
if (seq && "IntersectionObserver" in window) {
const io = new IntersectionObserver(
(entries) => {
if (entries.some((e) => e.isIntersecting)) {
io.disconnect();
renderDiagrams();
}
},
{ rootMargin: "400px" }
);
io.observe(seq);
} else {
renderDiagrams();
}
</script>
</body>
</html>