Issue No. 20201123

Canvas 성능 개선: off-screen Canvas 사용하기

화려한 인터랙티브 웹에 대한 수요가 많아지며 일반 HTML 요소들로는 표현이 어려운 캔버스(Canvas)의 사용이 점점 많아지고 있어요. 캔버스는 특성상 계속 반복적으로 렌더링하는 식이다보니, 아무래도 일반 웹페이지보다 기기에 부하가 많이 걸리죠~
그래서 캔버스를 사용할 때 최적화를 해주는 것도 중요한 포인트인데, MDN에 잘 정리된 글이 있어서 소개해드려요.

https://developer.mozilla.org/ko/docs/Web/HTML/Canvas/Tutorial/Optimizing_canvas [새창]

위 글의 내용 중

“캔버스에 표시되지 않는 반복 객체를 미리 그려라”

라는 부분이 있는데요, 캔버스를 다루는 데에 익숙하지 않은 분들은 이것만 읽어서는 실제로 적용에 어려움이 있을거에요. 그래서 이 내용의 구체적인 사례를 보여드리려고 합니다~
이 글은 저 위에 링크한 MDN의 글에 기생(?)하는 글이므로, 원 글의 해당 부분을 지금 읽고 다시 와주세요~ (짧아요)

애플 웹사이트 클론 강의
한땀한땀 구현원리를 공부하자!

보통, 캔버스에서는 context 객체의 drawImage() 메서드를 이용해 그림을 그리죠-
이런 식으로요.

See the Pen Canvas drawImage: Basic by 1 Minute Coding(1분코딩) (@1mincoding) on CodePen.

조금만 더 업글 해 볼게요. 귀요미 얼굴들을 여러개 만들고, 애니메이션을 살짝 줄거에요.

See the Pen Canvas drawImage: Normal by 1 Minute Coding(1분코딩) (@1mincoding) on CodePen.

다른 부분은 그냥 저렇게 움직이게 하려고 넣은 코드들이고, 여기서 중요한 부분은
SunFace 클래스의 draw 메서드의 코드에요. 바로 이 부분.

// 직접 imgElem을 그린다
context.drawImage(imgElem, this.x, this.y);

new Image()로 생성했던 imgElem을, 매 프레임마다 캔버스에 직접 그리고 있습니다.
이건 잘못된 방법이 아니고, 굉장히 일반적인 방법이에요.
하지만 이 글은 이런 보통의 방법보다 더 나은 퍼포먼스를 내기 위한 팁에 대한 글이므로, 이걸 개선해보자는 것이고요~

오프스크린 캔버스는 화면에 보이지 않는 캔버스를 가리키는 말입니다. 오프스크린 캔버스를 사용한다는 것은, 눈에는 보이지 않는 임시 캔버스에 이미지를 미리 그려두고 우리 눈에 보이는 캔버스에 그 임시 캔버스를 그려주는 방식이에요.
이렇게요.

See the Pen Canvas drawImage: Off-Screen Canvas by 1 Minute Coding(1분코딩) (@1mincoding) on CodePen.

아까와 다르게, 이미지를 메인 캔버스에 직접 그리는 대신, 미리 이미지를 그려둔 오프스크린 캔버스를 그려주고 있죠~

// 이미지 엘리먼트 대신, off-screen 캔버스를 그린다
context.drawImage(canvas.offCanvas, this.x, this.y);

사실 이렇게 간단하고 작은 이미지를 사용하는 예제에서는 성능 개선을 체감하기 어려울 거에요. 그치만 이 개념을 알아두면, 나중에 성능이 중요한 큰 이미지를 처리할 때 활용해볼 수 있겠죠~~

(광고)
아, 그리고.. 제가 얼마전에 강의를 또 하나 새로 출시했거든요.
애플의 고오급진 인터랙션을 그대로 한땀 한땀 직접 구현해보는(No 라이브러리), 재미나고 머리도 좀 복잡해지는 수업! ㅋㅋ
https://www.inflearn.com/course/애플-웹사이트-인터랙션-클론 [새창]