https://developer.mozilla.org/ko/docs/Web/API/OffscreenCanvas
https://tech.kakao.com/posts/442
https://velog.io/@hoonsbory/offscreencanvas
개념을 알려면
이 링크가 가장 깔끔하게 설명하니 참고하시길!
그래서 이걸 쓰고 싶었는데 일단 못했다...
이걸 적으면서 흐름을 찾고자 한다.
한줄로 요약하면 작업자를 한명 더 두는 것.
JS는 흔히 싱글 스레드라고 한다.
데이터를 불러오고, UI를 그리고, 사용자와 인터렉션 하는 것들을 하나의 스레드에서 하게 된다.
즉 Main Thread가 busy 하다면 작업의 속도가 느려진다.
이걸 offScreenCavnas + Web Worker 개념을 통해 하나의 스레드를 더 쓰는 것 처럼 작동하게 하여
더 빠른 작업 속도를 통해 Canvas 태그 내 그려지는 그래픽 렌더링을 더 빠르게 하는 것.

OffscreenCanvas가 성능에 좋다는 건 알지만, 막상 내 프로젝트에 적용하려니 막막했다.
GameCanvas처럼 한 파일 안에서 모든 걸 처리하다가
SimplePixelCanvas처럼 역할을 나누려니 어디서부터 손대야 할지 감이 안 왔다.
이건 코딩 기술의 문제라기보다,
애플리케이션을 설계하는 관점을 바꾸자고 생각했다.
어려움의 근원은 메인 스레드와 워커 스레드가 서로 직접 대화할 수 없는,
철저히 격리된 공간이라는 사실에서 시작된다.
GameCanvas에서는 그냥 옆에 있는 함수를 호출하면 끝이었지만,
이제는 다른 도시에 있는 동료에게 소포(postMessage)를 보내서 일을 시켜야 하는 상황인 것이다.
하지만 OffscreenCanvas를 쓰면 상태가 두 종류로 나뉜다.
GameCanvas의 showQuestionModal, isLoading처럼 UI의 모양이나 동작을 결정하는 상태. 이건 여전히 React의 useState로 관리한다.pixels Map 객체), 현재 뷰포트 위치(viewPos), 확대 배율(scale) 등. 이건 워커 파일 안의 일반 변수로 존재한다.핵심: 워커의 렌더링 상태를 바꾸고 싶으면, React에서 직접 수정하는 게 아니라 "상태를 바꿔줘"라는 메시지를 워커에게 보내야 한다.
워커는 DOM을 전혀 볼 수 없다. window나 document 객체가 존재하지 않는 것이다.
SimplePixelCanvas에서 본 것처럼,ResizeObserver 등으로 크기를 측정한 뒤,postMessage)로메인 스레드와 워커는 오직 postMessage로만 대화한다. 함수 호출처럼 즉시 결과를 반환받을 수 없다.
handleClick() -> draw() 호출 (동기적)handleClick() -> postMessage({ type: 'DRAW_PIXEL', ... }) -> (시간차) -> 워커가 메시지 받고 draw() 호출 (비동기적)이 비동기 흐름에 익숙해져야 한다.
GameCanvas를 OffscreenCanvas 방식으로 바꾼다고 상상하며 역할을 재정의해 보자.
매니저 (메인 스레드 - GameCanvas.tsx)
ResizeObserver).실무자 (워커 스레드 - game.worker.ts)
pixels Map)를 직접 소유하고 관리한다.viewPos, scale)를 직접 관리한다.SimplePixelCanvas의 VIEW_UPDATED 메시지처럼)interactionCanvas를 클릭. handleClick 함수 실행.e.clientX, e.clientY 값을 바탕으로 물리 좌표를 계산.worker.postMessage({...})onmessage 실행.viewPos, scale을 이용해 어떤 픽셀인지 계산.pixels 데이터를 업데이트.draw() 함수를 호출해 OffscreenCanvas에 그림을 다시 그림.OffscreenCanvas의 최신 그림을 화면의 <canvas>에 자동으로 보여줌.글로 적어도 왜 감이 안올까...
왜 안되는지 이유를 반드시 찾아보자.