2012-03-22 3 views
6

나는 꽤 무거운 (중간 무게보다는) canvas 작업이 진행되는 페이지가 있습니다. 모바일 장치 및 오래된 컴퓨터 사용자를 위해 캔버스 요소가 실제로 표시되는지 확인하고 상수 계산 및 캔버스 업데이트 (30fps에서 실행되는 애니메이션)를 수행해야하는지 여부를 결정하는 메커니즘을 구현할 수 있다고 생각했습니다. .브라우저는 뷰포트 안에 있지 않은 캔버스 요소를 렌더링합니까?

이것은 잘 작동하고 있지만 Chrome Dev Tools로 성능 테스트를 수행 할 때 가시성 검사를 사용 중지하고 문제가 발생한 기능의 CPU 사용량이 항상 렌더링되도록 할 때도 캔버스 요소 (들)의 어떤 부분도 보이지 않을 때 (이론적으로는 여전히 동일한 작업을 수행해야 함). 따라서 적어도 내 컴퓨터에서 Chrome 17을 실행하면 요소의 실제 가시성을 확인하면 실제로 차이가 발생하지 않습니다.

간략한 이야기를 요약하면 :이 작업을 수행해야합니까, 아니면 그러한 사례를 처리 할 수있을 정도로 똑똑하고 브라우저를 말하지 않고도 (그리고 가시성 검사를 저장할 수 있습니까?)?


편집는 :

그래서 나는이 주제에 대한 몇 가지 "연구"를 만들어 어떤 일이 것은 단지 초당 30 프레임 노이즈를 생성하는 것입니다 this fiddle.

을 만들었습니다. 눈을 너무 기쁘게하지는 않지만, 음 ... 위쪽 부분은 뷰포트를 차단하는 단순한 div입니다. 아래로 스크롤하여 뷰포트에서 canvas 요소를 사용하면 CPU 사용량이 약 40 % 가량 걸린다는 것을 알 수 있습니다. 따라서 브라우저에서 여기에서해야 할 일이 많습니다. 위로 스크롤하면 위로 스크롤하여 내 뷰포트에 적색의 색갈색 div을 표시하고 CPU 사용량을 프로필하면 약 10 %까지 떨어집니다. 다시 아래로 스크롤하면 사용량이 다시 증가합니다. 내가 좋아하는 가시성 검사를 구현할 때

그래서이 modified fiddle에, 나는 캔버스 경우 확인하는 추가 작업이 있기 때문에 (대신 드롭의 CPU 사용량의 증가를 (작은 사람이 정직하기)를 참조 할 뷰포트 안에 있음).

나는 이것이 내가 알지 못하는 (또는 프로파일 링 할 때 큰 실수를하고있다) 일부 부작용이 있는지 또는 브라우저가 그러한 상황을 처리 할만큼 충분히 똑똑 할 것으로 기대할 수 있는지 궁금해하고있다.

누군가가 그 점을 밝힐 수 있다면 나는 매우 감사 할 것입니다!

답변

8

로직이 실행 중인지와 렌더링이 발생하는지 여부가 혼란 스럽습니다. 많은 브라우저가 이제는 캔버스를 하드웨어 가속화하므로 모든 렌더링이 GPU에서 발생하므로 실제 픽셀 푸싱은 CPU 시간이 필요하지 않습니다. 그러나 귀하의 틱 기능을 CPU에 임의의 노이즈를 생성하는 사소한 코드가 있습니다. 따라서 틱 기능이 실행 중인지 여부 만 신경 써야합니다.캔버스가 오프 스크린이면, 그것은 디스플레이에 렌더링되지 않습니다 (보이지 않습니다). 캔버스 그리기 호출에 대해서는 브라우저에 따라 다를 수 있습니다. 갑자기 다시보기 위해 스크롤 할 경우 화면 꺼짐 캔버스로 모든 그리기 호출을 렌더링 할 수 있습니다. 그렇지 않으면 캔버스를 스크롤하여 볼 때까지 모든 그리기 호출을 큐에 대기시킬 수 있습니다. 각 브라우저가 무엇을하는지 잘 모르겠습니다.

그러나 캔버스 애니메이션setInterval 또는 setTimeout을 사용하면 안됩니다. 새로운 requestAnimationFrame API를 사용하십시오. 브라우저는 타이머 호출에서 무엇을하는지 모르기 때문에 항상 타이머를 호출합니다. 반면에 requestAnimationFrame은 시각적 인 것들을 위해 특별히 설계되었으므로 브라우저는 틱 기능을 호출하지 않거나 캔버스 또는 페이지가 표시되지 않는 경우 호출 속도를 낮출 수 있습니다.

브라우저가 얼마나 인지 실제로는을 처리하는 방법에 대해서는 확실하지 않습니다. 그러나 향후 브라우저가 requestAnimationFrame을 더 효율적으로 최적화 할 수 있으므로 setInterval 또는 setTimeout을 최적화 할 수 없기 때문에 분명히 선호해야합니다. 현대적인 브라우저는 페이지가 보이지 않으면 일반 타이머를 1Hz로 줄이는 효과가 있지만 브라우저가 requestAnimationFrame을 최적화하는 것이 훨씬 쉽고 일부 브라우저는 V-syncing 및 기타 niceness를 얻을 수 있습니다.

그래서 requestAnimationFrame은 캔버스가 보이지 않게 스크롤되는 경우 눈금 기능이 호출되지 않는다는 것을 의미합니다. 따라서 을 사용하여requestAnimationFrame과 기존의 가시성 확인을 모두 사용하는 것이 좋습니다. 그것은 당신에게 가장 효율적인 렌더링을 보장해야합니다.

+0

와우, 그 슈퍼 철저한 대답에 너무 감사드립니다! 이전에'requestAnimationFrame'에 대해 들었 습니다만, 항상 그것에 관해 나를 괴롭힌 것은 60fps에서 실행되는 애니메이션을 목표로하는 것입니다 (많은 종류의 애니메이션에서 너무 부드럽게 보임). 이것을 제한하는 유일한 방법은'setInterval'을 다시 한번 포함하는 것입니다. .... 제한/변경하는 방법이 있는지 알고 있습니까? – m90

+0

너무 부드럽습니까? 너무 매끄러운 애니메이션을 들어 보지 못했는데, 그게 뭐가 잘못 됐어? : S – AshleysBrain

+0

나는 이상하게 들릴지 모르지만 고전 애니메이션에 대한 배경 지식을 가지고 있기 때문에 나는 이것이 지금까지 내 뇌의 일부라고 생각하는 12fps로 생각한다. 이의 제기가 95 %의 경우에 어리석은 일 이겠지만, 어떤 경우에는 더 많은 통제가 필요합니다. – m90

2

내 자신의 경험에 비추어 볼 때, 화면상의 위치에 관계없이 렌더링하기 위해 무엇을 말 하든지 렌더링합니다.

예를 들어 캔버스 크기를 초과하는 타일을 그릴 경우 스크립트를 최적화하지 않으면 성능 저하가 계속 발생합니다.

성능이 요구되는 애니메이션으로 기능을 시험해보고 여전히 동일한 결과가 나오는지 확인하십시오.

+0

전체 ''요소가 화면 밖으로 스크롤되면 CPU 사용량이 감소한 것 같습니다. 당신이 썼을 때 당신은 단지 그것의 2px 높이 또는 모든 것을 볼 수 있다면 차이를 만드는 것처럼 보이지 않습니다. – m90

+0

웹 사이트에서 탭 아웃 할 때와 같은 이유 일 수 있습니다. 브라우저는 캔버스가 보이지 않기 때문에 대기 모드로 들어갑니다. 탭으로 이동하고 5 분 후에 다시 돌아 오면 애니메이션은 대략 어디를 떠났을까요. – justanotherhobbyist

관련 문제