requestAnimationFrame과 cancelAnimationFrame의 관계

MochaChoco·2023년 8월 9일
0

QA팀으로부터 현재 운영 중인 웹 사이트 관련해서 리포트를 몇 건 전달받았다. 사이트를 탐색하다보면 전체적으로 사이트가 느려진다는 내용이었는데, 리포트들의 공통점은 특정 애니메이션을 실행하고 난 후부터 사이트가 느려진다는 것이었다.

해당 애니메이션은 loop되는 구조로써 특정 영역을 mouseEnter하면 재생되었다가, 해당 영역을 mouseLeave하면 애니메이션이 숨김 처리되는 형식이다. 그래서 애니메이션을 재생하면서 개발자 콘솔로 메모리 상태를 살펴보니 animation Frame Fired라는 항목이 가장 높은 점유율을 차지했고, 이것이 애니메이션이 화면에서 사라졌음에도 불구하고 지속적으로 메모리를 점유한다는 사실을 발견했다.

그래서 애니메이션 메모리 최적화 방법을 찾아보니 requestAnimationFrame 이라는 단어가 계속해서 언급이 되었고, 마침 운영 중인 사이트에서도 이것을 사용하고 있길래 관심을 가지게 되었다. 그렇다면 requestAnimationFrame란 무엇이며, 이것을 수동으로 해제하는 방법은 무엇일까?

requestAnimationFrame이란?

자바스크립트의 내장함수로써 매 프레임마다 호출되어 다음 프레임에 호출할 애니메이션을 지정하고 이를 호출하는 함수이다.

기존 setInterval 함수와 달리 주사율에 비례하여 호출 횟수가 조절되고, 백그라운드 상태에서는 호출되지 않는다는 장점이 있다.

하지만 유의사항이 있는데 setInterval 함수가 clearInterval 함수를 사용해서 타이머를 해제하듯이 requestAnimationFrame 함수도 별도의 조건을 지정하지 않는다면 cancelAnimationFrame 함수를 사용하여 애니메이션을 해제해주어야 한다.


// 애니메이션을 저장할 변수
let id = 0;


... 
function init(){
	...
    console.log("animation start!!");
    animate();
}

...
// 매 프레임마다 id를 갱신한다. 
function animate() {
	console.log("animate...");
	id = requestAnimationFrame(animate); 
}

...
// 애니메이션 종료 때 호출하여 저장해놓은 id값을 인자에 넣어준다.
function destory(){
	console.log("animation end // animation id : ", id);
  	cancleAnimationFrame(id);
}

사용법은 간단하다. requestAnimationFrame 함수는 id값을 반환하는데 해당 id를 별도의 변수에 저장해놓고, 애니메이션을 종료시켜야 할 시점에 id값을 cancelAnimationFrame 함수의 인자에 넣어 호출하면 된다.

cancelAnimationFrame 적용 비교

cancelAnimationFrame 함수가 잘 동작하는지 별도의 코드를 만들어 보았다. 영역을 하나 만들고 해당 영역에 mouseEnter하면 애니메이션이 재생되고 mouseLeave하면 애니메이션이 사라지면서 멈추는 형식이다. 해당 영역에 마우스를 초반 10초 동안 mouseEnter 상태에서 가만히 두고, 나머지 10초는 mouseLeave 한 상태에서 가만히 두는 식으로 테스트를 진행했다.

cancelAnimationFrame 함수 적용 전

cancelAnimationFrame 함수 적용 후

위가 cancleAnimataionFrame 함수를 적용 전이고, 아래가 적용 후이다. 위의 그래프를 보면 10초가 지났음에도 지속적으로 파란색 그래프가 일정한 높이에서 유지되는 반면, 아래쪽 그래프는 10초가 지나자 확 줄어드는 모습을 볼 수 있다. 그리고 콘솔창을 비교해봐도 위는 계속해서 animate 함수가 실행되어 메모리 누수가 발생하는 것을 알 수 있다.

이 결과를 참고삼아 실제 웹 사이트에서도 cancelAnimationFrame을 적용하니 애니메이션이 사라진 후에도 메모리를 계속해서 점유하는 현상이 사라졌고 사이트가 느려지는 문제도 해결되었다.

샘플코드

github 저장소 이동 (https://github.com/MochaChoco/request-animation-frame)

참고 자료

웹 애니메이션 최적화 requestAnimationFrame 가이드
[JS] requestAnimationFrame/cancelAnimationFrame원리와 사용 방법 (Feat. 브라우저 작동 방식)
[자바스크립트] RequestAnimationFrame()을 사용하는 방법 및 예제
Chrome DevTools로 JS 메모리 누수(Memory Leak) 디버깅하기

profile
길고 가늘게

1개의 댓글

comment-user-thumbnail
2023년 8월 9일

좋은 글 감사합니다. 자주 방문할게요 :)

답글 달기