Files
2nd/10_Wiki/Topics/Domain_Programming/Frontend/OffscreenCanvas Safari 제약 사항.md
T
Antigravity Agent c24165b8bc refactor(topics): 멀티 에이전트용 지식 재편 — _Common(공통 기본기) + Domain_* 구조
에이전트 8종(대화형/프로그래머 C·S/디자이너/설계자/기획자/QA/PD/PM)에게
[공통 기본 능력 + 롤별 Specialty] 2층으로 지식을 주입하기 위한 재분류.
문서 내용·포맷은 무수정, 폴더 이동만 (6,372개 문서 수 보존 확인).

- Topic_Programming → Domain_Programming (내부 구조 보존)
- Topic_Graphic → Domain_Design
- Topic_Business → Domain_Product
- Topic_General → Domain_General
- _Common 신설: Math(구 Topic_Math_Specialty), Reasoning(구 General/From_Thinking & Reasoning),
  Reasoning_Creativity(구 General/From_창의성), Communication(Poetic_Blog_Writing + From_writing)
- 타 도메인의 From_* 폴더는 유지 (출처 표기일 뿐, 이미 도메인에 맞게 분류된 문서)
- 빈 폴더 정리 (memory/procedures)
- 에이전트→폴더 매핑은 workspace의 .astra/agent-knowledge-map.json (9개 에이전트)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 11:05:56 +09:00

5.7 KiB

id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
id title category status canonical_id aliases duplicate_of source_trust_level confidence_score verification_status tags raw_sources last_reinforced github_commit tech_stack
wiki-2026-0508-offscreencanvas-safari-제약-사항 OffscreenCanvas Safari 제약 사항 10_Wiki/Topics verified self
OffscreenCanvas Safari
Safari OffscreenCanvas Limits
OffscreenCanvas WebKit
none A 0.9 applied
canvas
safari
webkit
browser-compat
offscreencanvas
2026-05-10 pending
language framework
JavaScript Browser

OffscreenCanvas Safari 제약 사항

매 한 줄

"매 Safari OffscreenCanvas 의 partial support". Safari 16.4+ 매 2D context 만 지원, WebGL/WebGPU OffscreenCanvas 는 매 17.0+ 부터 점진. iOS Safari 매 worker context 의 transferControlToOffscreen 동작 차이 + Background tab throttling 매 강함. 2026 기준 Chrome/Firefox 와 매 feature parity 거의 도달, 매 edge case 잔존.

매 핵심

매 Safari 의 timeline

  • Safari 16.4 (2023): OffscreenCanvas 2D context.
  • Safari 17.0 (2023): WebGL OffscreenCanvas in worker.
  • Safari 18.x (2025): WebGPU OffscreenCanvas (experimental flag).
  • iOS Safari 매 desktop 의 1-2 minor 늦게 따라옴.

매 주요 제약

  • Background tab throttling: 매 worker animation frame 매 1Hz 까지 drop (Chrome/Firefox 보다 강한 throttle).
  • Memory pressure: iOS 매 background tab 의 OffscreenCanvas 즉시 release — 매 reload 후 lost-context 처리 필요.
  • ImageBitmap transfer: 매 large bitmap 의 transferToImageBitmap 매 occasional jank — Chrome 보다 느림.
  • WebGL2 context loss: iOS Safari 매 page-hide 즉시 lost.
  • Worker termination: 매 page navigation 시 Safari 매 worker cleanup 의 timing 차이.

매 응용

  1. Image processing (Photopea-style) — main thread 차단 회피.
  2. Chart rendering (Plotly, Apache ECharts worker mode).
  3. Game offscreen rendering.
  4. PDF/canvas thumbnail 생성.

💻 패턴

Feature detection (매 graceful fallback)

function supportsOffscreen2D(): boolean {
  return typeof OffscreenCanvas !== "undefined"
    && typeof new OffscreenCanvas(1, 1).getContext === "function";
}

function supportsOffscreenWebGL(): boolean {
  if (!supportsOffscreen2D()) return false;
  try {
    return !!new OffscreenCanvas(1, 1).getContext("webgl2");
  } catch {
    return false;
  }
}

Safari-safe transferControlToOffscreen

const canvas = document.querySelector("canvas")!;
let offscreen: OffscreenCanvas | null = null;
let worker: Worker | null = null;

function start() {
  if (!supportsOffscreen2D()) {
    renderOnMainThread(canvas);
    return;
  }
  offscreen = canvas.transferControlToOffscreen();
  worker = new Worker(new URL("./renderer.worker.ts", import.meta.url), { type: "module" });
  worker.postMessage({ type: "init", canvas: offscreen }, [offscreen]);
}

Lost context handling (매 iOS 필수)

// renderer.worker.ts
self.addEventListener("message", (e) => {
  if (e.data.type === "init") {
    const canvas = e.data.canvas as OffscreenCanvas;
    let gl = canvas.getContext("webgl2");

    canvas.addEventListener?.("webglcontextlost", (ev) => {
      ev.preventDefault();
      console.warn("WebGL context lost (Safari background?)");
    });
    canvas.addEventListener?.("webglcontextrestored", () => {
      gl = canvas.getContext("webgl2");
      reinitScene();
    });
  }
});

Visibility-aware rendering (매 throttle 회피)

let isVisible = !document.hidden;
document.addEventListener("visibilitychange", () => {
  isVisible = !document.hidden;
  worker?.postMessage({ type: "visibility", visible: isVisible });
});

// In worker:
let raf: number;
function loop() {
  draw();
  raf = self.requestAnimationFrame?.(loop) ?? setTimeout(loop, 16);
}
self.addEventListener("message", (e) => {
  if (e.data.type === "visibility") {
    if (e.data.visible) loop();
    else cancelAnimationFrame?.(raf);
  }
});

ImageBitmap chunked transfer (매 Safari jank 회피)

async function processInChunks(blob: Blob, chunkSize = 1024) {
  const bitmap = await createImageBitmap(blob);
  for (let y = 0; y < bitmap.height; y += chunkSize) {
    const chunk = await createImageBitmap(bitmap, 0, y, bitmap.width, Math.min(chunkSize, bitmap.height - y));
    worker.postMessage({ type: "chunk", chunk, y }, [chunk]);
    await new Promise(r => setTimeout(r, 0)); // yield to UI
  }
  bitmap.close();
}

매 결정 기준

상황 Approach
2D rendering, modern browser OffscreenCanvas + worker
WebGL on iOS Safari feature-detect + main-thread fallback
Long-running animation visibilitychange 의 pause
Large bitmap chunked transfer
Production, broad support progressive enhancement, never required

기본값: feature-detect + 매 main-thread fallback path 매 항상 유지.

🔗 Graph

🤖 LLM 활용

언제: heavy canvas 작업의 worker 위임 + Safari/iOS target. 언제 X: simple animation / 매 main thread 충분.

안티패턴

  • No fallback: 매 OffscreenCanvas 의 mandatory 가정 — 매 old Safari user crash.
  • Ignore context lost: 매 iOS background → resume 후 매 black canvas.
  • Throttle 무시: 매 background tab 의 animation 매 progress 가정 — 매 desync.
  • Sync transferToImageBitmap loop: 매 매 frame transfer — 매 GC pressure.

🧪 검증 / 중복

  • Verified (caniuse OffscreenCanvas, WebKit blog 16.4/17.0/18, MDN OffscreenCanvas).
  • 신뢰도 A.

🕓 Changelog

날짜 변경
2026-05-08 Phase 1
2026-05-10 Manual cleanup — Safari timeline, throttling/lost-context/chunked-transfer 패턴