요청 시 렌더링은 미리 모든 경로를 만들지 않고 필요한 경로가 처음 요청될 때 HTML을 생성합니다. 생성 결과를 캐시에 두면 뒤따르는 요청은 저장된 페이지를 받을 수 있습니다.
첫 방문은 생성 작업 때문에 느릴 수 있고 캐시 수명과 무효화 규칙이 필요합니다. 모든 요청마다 새로 만드는 SSR과는 캐시 재사용 여부가 다릅니다.
언제 쓰나
경로가 많아 전부 사전 생성하기 어렵고, 첫 요청 비용을 감수할 수 있을 때 적합합니다.
처음 방문한 경로만 요청 시 생성하고, 만든 결과를 다음 방문에 재사용합니다.
<section class="stage"><div class="heading">ON DEMAND <span class="hint">first visit → cached</span></div><div class="demand"><div class="people"><span>visitor 1</span><span>visitor 2</span></div><div class="arrow">→</div><div class="tile generator">RENDER<div class="gear">+</div></div><div class="arrow">→</div><div class="tile cache">/item/42.html</div></div><div class="caption">Only the first visit runs the renderer</div></section>.stage{width:min(94vw,780px);height:min(88vh,322px);padding:clamp(12px,3vmin,20px);border:1px solid var(--line);border-radius:16px;background:var(--surface);box-shadow:0 12px 36px #0001;display:flex;flex-direction:column;gap:clamp(7px,2vmin,14px);font:500 clamp(12px,3.5vmin,17px)/1.3 var(--font-sans,system-ui,sans-serif);overflow:hidden}.heading{display:flex;justify-content:space-between;align-items:center;gap:8px;font-weight:750;color:var(--accent)}.hint{color:var(--muted);font-size:clamp(12px,3.2vmin,14px);font-weight:500}.caption{margin-top:auto;color:var(--muted);font-size:clamp(12px,3.2vmin,14px)}.row{display:flex;gap:clamp(5px,1.5vmin,12px);align-items:center}.tile{padding:clamp(6px,1.8vmin,13px);border:1px solid var(--line);border-radius:9px;background:var(--bg);text-align:center;min-width:0}.arrow{color:var(--accent);font-weight:800}.stage [data-on]{transition:background .3s,border-color .3s,opacity .3s,transform .3s}.stage .on{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 14%,var(--surface));color:var(--accent)}.demand{display:flex;align-items:center;justify-content:center;gap:clamp(4px,1.4vmin,12px);flex:1}.people{display:flex;flex-direction:column;gap:8px;white-space:nowrap}.people span{opacity:.35;transition:opacity .3s}.generator,.cache{flex:1;max-width:145px;min-height:65px;display:grid;place-items:center;opacity:.3;transition:opacity .3s}.gear{color:var(--accent-3);font-size:1.5em;line-height:1;animation:spin 3s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.stage[data-step="1"] .people span:first-child,.stage[data-step="1"] .generator,.stage[data-step="1"] .cache,.stage[data-step="2"] .people span:last-child,.stage[data-step="2"] .cache{opacity:1}.stage[data-step="2"] .generator{opacity:.25}.stage[data-step="2"] .cache{border-color:var(--accent);color:var(--accent)}.stage small,.stage button,.stage .cards b,.stage .phase b,.stage .pair b,.stage .tree-mini b{font-size:clamp(12px,3.2vmin,14px)!important}const stage=document.querySelector(".stage");let step=0;function tick(){stage.dataset.step=String(step);step=(step+1)%3}tick();let timer=setInterval(tick,1000);stage.addEventListener("pointerdown",()=>{clearInterval(timer);tick()})요청 시 렌더링은 미리 모든 경로를 만들지 않고 필요한 경로가 처음 요청될 때 HTML을 생성합니다. 생성 결과를 캐시에 두면 뒤따르는 요청은 저장된 페이지를 받을 수 있습니다.
첫 방문은 생성 작업 때문에 느릴 수 있고 캐시 수명과 무효화 규칙이 필요합니다. 모든 요청마다 새로 만드는 SSR과는 캐시 재사용 여부가 다릅니다.
경로가 많아 전부 사전 생성하기 어렵고, 첫 요청 비용을 감수할 수 있을 때 적합합니다.