[TIL/06.25-기획단계] Canvas API & Web worker 개념

CHO WanGi·2025년 6월 24일

KRAFTON JUNGLE 8th

목록 보기
75/89

Canvas API

JS와 HTML을 사용하여 그래픽을 그릴 수 있는 HTML Tag.
<canvas> 태그를 사용하고 JS로 이 element 인터페이스를 그려서 조작하는 방식이다.
웹 상에서 2D 그래픽을 그릴 수 있는 Tag.

왜 쓸까

비트맵 데이터로 구성되어 있어서 Pixel 하나하나 조작이 가능하고, 상대적으로 좋은 그래픽 처리 성능을 갖고 있다.

  • ImageData
    사진이나 도형같은 요소들을 이렇게 비트맵 데이터로 저장한다.
// 1px 는 4개의 RGBA 값을 구성
Uint8ClampedArray(1920000) [
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  ... (많은 0들)
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]

브라우저 지원 확인

  1. Modernizr 라이브러리로 Canvas API를 지원하는지 확인하는 방법
  2. 라이브러리 없이 getContext 반환값이 Null 이라면 미지원으로 판단하는 방법

이 두가지 방식을 활용하여 진행할 수 있다.

Canvas API : 2D Context vs WebGL

  • 2D Context (getContext('2d'))
    • 직관적 API, 간단한 도형과 이미지 그리기에 최적화
    • CPU 기반으로 동작, 1024 * 1024 개의 픽셀을 다시 그리는 작업시 성능저하 우려
  • WebGL (getContext('webgl'))
    • GPU 가속을 활용한 압도적 성능, shader를 이용한 복잡한 시각효과도 구현 가능
    • 복잡한 API와 가파른 학습곡선, 많은 코드량
    • PixiJS, Konva 등의 렌더링 라이브러리 검토 필요

Web Worker

Web Worker개념이란?

JS는 싱글 스레드 환경에서 동작함. 따라서 서버와의 통신, UI 렌더링 작업등 무거운 작업들을 싱글스레드로 처리하려면 프로덕트가 버벅이거나 작업이 지연되는 문제점이 발생.

이를 Web Worker를 활용하여 더블 스레드와 유사한 패턴으로 추가 스레드를 사용해서
작업을 더 빠르게 처리할 수 있는 이점을 얻을 수 있음.

https://web.dev/articles/workers-overview?hl=ko
https://tech.kakao.com/posts/442

  • Main Thread ⇒ UI 처리
    • 사용자 입력 처리
    • WebSocket 통신
    • 커서 위치, 타이머 숫자 업데이트
  • Background Thread(Web Worker) ⇒ OffscreenCanvas(무거운 작업 수행)
    • OffscreenCanvas 에 픽셀 그리기
    • OffscreenCanvas를 하나의 완성된 이미지 비트맵으로 변환
    • 메인 스레드로 전송

사용자 Click시 시나리오

  • 사용자 A의 클릭:
    • [Main Thread] 클릭 좌표와 색상 정보를 확인 후, 쿨다운이 아니면 서버로 전송.
    • [Main Thread] 자신의 UI에 쿨다운 타이머를 시작.
  • 서버의 처리:
    • [Server] A의 픽셀 정보를 받아 유효성을 검사하고 저장.
    • [Server] 접속한 모든 클라이언트(A, B, C...)에게 "A가 어디에 무슨 색을 찍었다"고 방송(Broadcast).
  • 모든 클라이언트의 수신:
    • [Main Thread] (A, B, C 모두) 서버로부터 픽셀 업데이트 정보를 받음.
    • [Main Thread] 받은 정보를 그대로 Web Worker에게 전달. (worker.postMessage(...))
  • 각 클라이언트의 렌더링:
    • [Web Worker] (A, B, C 모두) "픽셀을 그려라" 지시를 받고, 자신의 OffscreenCanvas에 해당 픽셀을 그림.
    • [Web Worker] 그리기가 완료된 캔버스를 이미지(ImageBitmap)로 만들어 메인 스레드로 보냄.
  • 화면 업데이트:
    • [Main Thread] (A, B, C 모두) 워커로부터 받은 최종 이미지를 main-canvas-layer에 한 번에 drawImage 함.

여전히 미궁속

React라는 큰 틀안에 Canvas 영역을 JS로 컨트롤해야하는 큰 그림은 이해가 되었다.
1. 무거운 픽셀단위의 UI를 렌더링하는 작업을 Web Worker가 수행
2. Main Thread의 canvas가 Web Worker의 최종 작업 결과물인 이미지비트맵을 표시
라고 하는 Canvas 로직과

BE와 Canvas 의 변화를 통신하는 통신 로직을 어떻게 이어서
하나의 완성된 로직을 만들지가 잡히지가 않는다

profile
제 Velog에 오신 모든 분들이 작더라도 인사이트를 얻어가셨으면 좋겠습니다 :)

0개의 댓글