[프론트엔드] canvas.toBlob로 병목 해결하기

Woonil·5일 전
0

프론트엔드

목록 보기
4/5

캡스톤 프로젝트로 진행했던 왕눈이(wangnOOni)는 인공지능으로 운전자의 행동을 실시간으로 탐지해 피드백을 주는 서비스이다. 이때, 프론트엔드에서 폴링 방식으로 Video에 녹화된 운전자 모습을 일정 주기로 스냅샷처럼 canvas에 그려 백엔드 서버로 전송하고 있었다.

개발 당시에 폴링 방식이 사실 웹소켓에 비해 완벽한 실시간 구현은 아닌 만큼, 주기를 최대한 짧게 유지하고 싶었다. 그래서 그 주기를 1s로 설정하였고 구현은 어찌저찌 완성했었다. 하지만 응답 시간이 주기보다 긴 1.5~2.0s에 머물러 있었고(로컬 개발 기준), 이는 동시 접속자 수나 네트워크 환경으로 인해 더 오래걸릴 수도 있겠다고 판단했다.

🤔과정

이를 해결하고자 크롬 개발자 도구로 성능을 측정하였고, 메인 스레드에서의 병목을 발견할 수 있었다. 일정 간격으로 병목이 있는걸 확인할 수 있었는데, 해당 구간을 자세히 살펴보니 실행 시간 중 toDataURL에 대한 스크립트 실행이 대부분을 차지하고 있었다.

따라서 MDN에 해당 canvas 메서드에 대해 검색해보았다.

즉, canvas 내의 화면을 이미지로 바꿀 때, 큰 용량의 이미지라면 toDataURL() 대신 toBlob() 메서드를 사용하라는 얘기다. toDataURL()을 사용하면 data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ…9oADAMB과 같이 base64로 인코딩된 data URL이 반환된다. 바이너리를 아스키문자로 변환하는 과정에서 용량이 커지는 등 성능에 좋지 않는 영향을 줄 수 있다. base64 인코딩을 사용하지 않더라도 현상황과 같이 복잡한 이미지(운전자 이미지)를 보내는 경우 이 방법은 적합하지 않다.

이와 관련한 스택오버플로우 답변이다.

표로 정리하면,

toDataURL()toBlob()
동기/비동기동기비동기
인코딩OX

그래서 위의 기존 코드를 아래와 같이 바꿔주었다. 참고로 이후 성능 비교를 위해 이미지 품질은 보존하였다.

😎결과

메서드를 바꾼 결과 병목(빨간색 부분)이 사라진 것을 확인할 수 있다.

toDataURL()

toBlob()

💭배운점

당시에는 챗지피티 답변을 바탕으로 코드를 구성했었는데, 검증을 제대로 안한 탓이 큰 것 같다. 몇 개월이 지난 사이 웹에서 바이너리를 다루는 방식에 대해 조금 더 알게 되었고, 공식문서나 스택오버플로우의 내용이 더 이해가 수월했다. 또한 웹 성능 측정에 대한 지식도 개선점 발굴의 시발점이 된 것 같다. 아는 만큼 보이는 것을 새삼 느꼈고, AI의 답을 잘 검증하기 위해서는 기본 지식을 갖추는 것이 먼저인 것 같다고 생각했다.

profile
프론트 개발과 클라우드 환경에 관심이 많습니다:)

0개의 댓글