모바일용 HTML5 게임 성능 최적화
<앱 세상에서 HTML5 생존기>
Click의
Web 시대
가 지고
Touch의
앱 천지
가 되다.
Hybrid App에서
상리 공생 전략
을 통해서 생존해 나가자
게임 서비스 기술 Overview
- Web UI: CSS3D, keyframe animation
- Game: Canvas/DOM Hybrid
- Webview: OK 캐쉬백 App Embedded
- OS: Android 2.3 이상, iOS
서비스 관점 HTML5 활용도 (Hybrid App 중심)
WebView를 통한 Hybrid App의 일반화
사업/기획팀등 비 개발자도 Hybrid App의 장점을 이해
No App Update
사용자 App update 저항감 회피
App Store를 통한 서비스 배포 지연 위험성 회피
iOS/Android One Source 배포
개발, 운영 비용 효율화
상품화 수준 정의
모든 고객 만족: Android 2.3x 이상, iOS 5.0 이상 지원
OK 캐쉬백 앱: Mobile OS Share
상품화 수준 HTML5 개발을 위한 필수 지식
WebKit 내부 동작: DOM/Render Tree 복잡도 관리/GPU 활용
개발 환경: Chrome Inspector 활용
Fragmentation의 이해 및 대처
요구사항의 기술적인 구현 가능성 판단하기
Webkit 엔진 주요 기능 (Blink 포함)
Parsing(HTML, XML, CSS, JavaScript)
Layout
Text, graphics rendering
Image decoding
GPU interaction
Network access
HW acceleration
WebKit 내부 Tree: HTML/CSS Parsing
WebKit 내부 Tree: Parsing 후 HTML/CSS 내부 표현
DOM tree:
Document내의 모든 DOM node
RenderObject tree:
DOM node중에 화면에 보이는 node
RenderLayer tree:
한번에 painting할 RenderObject 모음: stacking context
GPU 기반 합성 예제
아래와 같이 주황색으로 표시된 Element는 HW Accelerated Compositing을 사용하는 GPU Texture로 mapping 후 rendering
나는 OpenGLES GPU가 합성합니다. 잘사용하면 CPU 합성과 비교되지 않게 빨라요. GPU가 접근하는 Texture라는 메모리에 살고 있습니다
DOM/Render Tree 복잡도 관점에는 최적화가 안되어 있어요
DOM/Render Tree 복잡도 관리: The More, The Slower
DOM node 및 RenderObject 개수는 최소화
DOM node 재활용: DOM node 상수 고정
동적으로 삽입/삭제
display:none 설정 -> 해당 Render Object 제거, DOM node 유지
visibility:hidden -> Tree 복잡도 유지, painting cost 절감
animation동안 DOM 내용 변경 절대
style 변경 -> layout -> painting -> bumpy animation
iframe으로 view 분리 (sandboxing)
iframe으로 분리시 서로 분리된 frame(view)간 영향을 주지 않음
long-running app 개발시에도 메모리 leak 대응 용이
WebKit 엔진의 설명 자료
CPU에서 동작하는지 GPU에서 동작하는지 이해하고 활용 가능한 지식 필수
관련 자료들
WebKit 엔진 및 고성능 웹 앱 개발 (동영상)
WebKit 엔진 및 고성능 웹 앱 개발 (동영상)
WebKit 엔진 및 고성능 웹 앱 개발 Best Practice (Slide)
HTML5 모바일 웹앱 개발 동향/사례/전망 (Slide)
App-Embedded Branded Casual Game
iOS/Android 동시 지원
App Embedded: App 사용자 retention
No 네이티브 앱 Update
30-50만명 실시간 랭킹
HTML5 canvas 기반 게임 개발
Browser 엔진을 게임 플랫폼으로 사용시 고려 사항
Rendering -> canvas, DOM, canvas/DOM Hybrid
Audio -> WebAudio/audio tag
Resource loader -> img tag/XHR
input -> touch
DPI 별 resource 관리
기능별 제약 조건 분석후에 상용화 조건 부합시에만 사용
HTML5 canvas 기반 게임 개발
기존 오픈 소스 게임 엔진의 한계
PC 향 게임에 적합한 기능 및 크기
모바일 단말 성능 미고려로 Android 2.3을 포함한 상용화 수준 달성 힘듦
Mobile 단말 특화 필수 요건
Rendering 성능 최적화: 안정적인 20fps 이상(android 2.3 이상, iOS 5.0)
Play 가능한 interactive한 touch 반응성
garbage collection에 따른 게임 정지 최소화
게임엔진 자체 개발
SK 플래닛 HTML5 게임엔진소개
canvas 게임 기본 로직
책장 넘기 효과
지우고 그리고 지우고를 반복
Game내 Object 표현
Image 기반:
이미지의 crop/scaling up/down 조합
ctx.drawImage() 함수의 성능에 rendering 성능이 의존
Drawing primitive 조합:
최종 해상도 고려하여 path,circle,curve등을 조합하여 그리기
다단계 scaling을 피할수 있으나, Object 표현력의 한계로 디자인 제한적
Game내 Object 표현: Drawing Primitive 조합 방식 예제
최종 canvas 해상도 고려하여 path,circle,curve등을 조합하여 그리기 -> Image 방식 대비 상대적으로 성능 높음
블로그 상세 설명
<canvas> RunTime의 Rendering 성능의 이해
Bottleneck은 "Image Rendering 성능"
성능 Challenge
canvas HW 가속 미지원: Android 2.3.x, iOS4.0 이하 -> DOM 방식이 개수가 적을때 canvas 방식보다 제한적으로 유리
Kitkat의 Chrome Webview(4.4, 4.4.2) 성능 재앙: 구글에 의한 희망에서 절망으로
4.4.3에서 해결됨, 그러나 4.4.2가
60%
시장 차지
상품화를 위한 성능 문제 정의
<canvas> HW 가속이 되지 않는 Android 2.3 및 4.4.2(Kitkat)에서 성능 향상 방법
Kitkat Webview 성능 분석
painting 면적, object 개수에 대한 painting 성능을 fps로 측정
게임 <canvas>를 포함한 DOM Tree의 복잡도에 대한 영향 측정
실험 대상 단말: 옵티머스 G Pro(4.4.2), Nexus 5(4.4)
Kitkat Webview 성능 측정 결과
painting 면적, object 개수에 대한 painting 성능을 fps로 측정
왼쪽 그래프: object 개수 1, painting 면적 증가
오른쪽 그래: object 개수 증, painting 면적 25x25 고정
Kitkat browser에서는 해당 실험에서는 60fps로 성능 차이가 미미함
Kitkat Webview 성능 측정 결과
게임 <canvas>를 포함한 DOM Tree의 복잡도에 대한 영향 측정
Kitkat Webview 성능 측정 결과
DOM Tree 복잡도 증가시 비정상적인 성능 현상 발생
Kitkat Webview 성능 분석 결과 정리
Painting 영역의 크기에 비례하여 성능에 성능 감소
<canvas>를 내포한 페이지의 DOM Tree 노드가 증가
최대 100% 성능 감소 및 fps fluctuation 심하게 발생
성능 개선: DOM/Canvas Hybrid
애니메이션이 없는 게임 Object를 DOM으로 분리하여 GPU 가속을 사용하여 렌더링
게임 엔진단에서 오브젝트별 rendering context를 DOM/Canvas 지정 가능
성능 개선: DOM/Canvas Hybrid
DOM Node Pool: DOM Renderer의 구현 최적화
Viewport 내의 게임 오브젝트를 담는 DOM노드를 Pool로 관리
애니메이션이 없으므로 Object 이미지도 재활용 필수 -> reset시 painting 발생으로 오히려 성능 저하
Invalidate 영역 관리
이전 Frame의 <canvas>를 지우지 않고 현재 Frame에 재활용
Invalidate 영역만을 redraw
매 frame 마다 dirty object를 추적
전체 화면을 깜빡이는 등의 animation은 기획 단계에서 배제
Source 이미지 크기 관리
Sprite 이미지 사용시 네트워크 요청 개수를 줄일수 있음.
그러나,
원본 이미지의 크기가 커지면 비례하여 crop하는 영역이 고정 크기여도 속도 저하
Kitkat단말 fps기준 10% 이내 정도
해결책: 자주 쓰이는 object는 개별 이미지로 분리
분리->
Garbage Collection 최소화 1
게임내 모든 주요 Object는 Static Object Pool을 통해 관리
Static Object 구현 방식에 따른 성능 차이
Single Array, Double Array, Doubly Linked List
성능 비교 직접 해보기
JS 메모리 관리 by Addy Osamani
Garbage Collection 최소화 2
Single Array: push/pop 사용시 가장 빠름 (splice 매우 느림)
GC를 완벽히 차단하는 것은 매우 어렵다
해상도 파헤치기
최종 화면에 하나의 Pixel이 그려지기 위해서는 실질적으로 다단계 이미지 Scale 발생
canvas.width, canvas.height
canvas.style.width, canvas.style.height
drawImage(원본 이미지 위치, destination scaled 위치)
window.devicePixelRatio
원본 크기(canvas.width/height가 scale이 되지 않거나 또는 정수배 scale시 가장 성능이 좋음
현실적으로 단말별 해상도 차이 및 디자인 제약으로 쉽지 않음
Game 실행 환경 분리 필수
canvas 게임을 Web Page에 embedding 시 canvas rendering 성능 저하
fps가 swing 하는 현상이 발생하며 30% 저하
Web Page에 embed 시키지 말고 별도의 HTML로 실행
디자인/Publishing/게임 개발이 서로 다른 팀에서 결과물에 대해서 pipeline 형태로 작업시 발생 가능
위주 업체 제작: 700개 엘리먼트 --> 내부 제작: 350개 엘리먼트
10월 버전 부터는 게임 소개페이와 실행 페이지 분리 예정
핵심 메세지 정리
Hybrid App을 통한 상업적 활용 가치가 급속히 높아짐
Native와의 경쟁이 아닌 상호 협력
Browser 엔진에 대한 기본적인 이해는 성능 최적화에 필수적
canvas/DOM Hybrid, 이미지 사이즈 최적화, GPU 활용 등
엔진 및 게임 오픈 소스 공개 예정 (~10/31)
https://github.com/SK-Planet-WebTechTeam/Planet-HTML5-Game-Engine