모바일용 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 중심)

  1. WebView를 통한 Hybrid App의 일반화
    • 사업/기획팀등 비 개발자도 Hybrid App의 장점을 이해
  2. No App Update
    • 사용자 App update 저항감 회피
    • App Store를 통한 서비스 배포 지연 위험성 회피
  3. iOS/Android One Source 배포
    • 개발, 운영 비용 효율화

상품화 수준 정의

  1. 모든 고객 만족: Android 2.3x 이상, iOS 5.0 이상 지원
OK 캐쉬백 앱: Mobile OS Share

상품화 수준 HTML5 개발을 위한 필수 지식

  1. WebKit 내부 동작: DOM/Render Tree 복잡도 관리/GPU 활용
  2. 개발 환경: Chrome Inspector 활용
  3. Fragmentation의 이해 및 대처
  4. 요구사항의 기술적인 구현 가능성 판단하기

Webkit 엔진 주요 기능 (Blink 포함)

  1. Parsing(HTML, XML, CSS, JavaScript)
  2. Layout
  3. Text, graphics rendering
  4. Image decoding
  5. GPU interaction
  6. Network access
  7. HW acceleration

WebKit 내부 Tree: HTML/CSS Parsing

WebKit 내부 Tree: Parsing 후 HTML/CSS 내부 표현

  1. DOM tree: Document내의 모든 DOM node
  2. RenderObject tree: DOM node중에 화면에 보이는 node
  3. RenderLayer tree: 한번에 painting할 RenderObject 모음: stacking context

GPU 기반 합성 예제

  1. 아래와 같이 주황색으로 표시된 Element는 HW Accelerated Compositing을 사용하는 GPU Texture로 mapping 후 rendering
나는 OpenGLES GPU가 합성합니다. 잘사용하면 CPU 합성과 비교되지 않게 빨라요. GPU가 접근하는 Texture라는 메모리에 살고 있습니다
DOM/Render Tree 복잡도 관점에는 최적화가 안되어 있어요

DOM/Render Tree 복잡도 관리: The More, The Slower

  1. DOM node 및 RenderObject 개수는 최소화
    • DOM node 재활용: DOM node 상수 고정
    • 동적으로 삽입/삭제
    • display:none 설정 -> 해당 Render Object 제거, DOM node 유지
    • visibility:hidden -> Tree 복잡도 유지, painting cost 절감
  2. animation동안 DOM 내용 변경 절대
    • style 변경 -> layout -> painting -> bumpy animation
  3. iframe으로 view 분리 (sandboxing)
    • iframe으로 분리시 서로 분리된 frame(view)간 영향을 주지 않음
    • long-running app 개발시에도 메모리 leak 대응 용이

WebKit 엔진의 설명 자료

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에 따른 게임 정지 최소화
  • 게임엔진 자체 개발

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