앱 세상에서 HTML5 생존기
HTML5 기반 모바일 단말용 게임 개발 및 최적화
Click의 Web 시대가 지고
Touch의 앱 천지가 되다.
HTML5는
Hype (과대 광고) 또는
Hope (희망) 일까?
The Mission:
HTML5를
성공적으로 상업적으로 활용해보자
본 발표에서는
HTML5 기반 OK 캐쉬백 오락실
상용 개발시 기술 경험을 공유합니다.
데모앱 설치: Google Play/T Store에서 OK 캐쉬백으로 검색 후 설치
OK 캐쉬백 오락실 기술 Overview
- Web UI: CSS3D, keyframe animation
- Game: Canvas/DOM Hybrid
- Webview: OK 캐쉬백 App Embedded
- OS: Android 2.3 이상, iOS
앱 세상에서 HTML5 생존기:
HTML5 기반 모바일 단말용 게임 개발 및 최적화
임상석 팀장 > Web 기술 개발팀 > SK 플래닛

발표자 개발 이력 소개

- Web Front-end: OK 캐쉬백, Syrup Store, JavaScript (2013 - Now)
- HTML5 Web Platform: Android/iOS/Hybrid, JavaScript (2011 - Now)
- WebKit Browser: Linux/Tizen, C++, C (2008 - 2011)
- Mobile Firefox Browser: Linux, C++ (2007 - 2008)
- L4/L7 Switch/ Apache Server: Linux, C (2001 - 2006)

HTML5 개발에 대한 단상들

  1. 모바일 브라우져/모바일 Web에 대한 서비스 활용도 저하
    • 서비스 소개와 App 설치 유도 페이지로 전락
  2. 제3의 OS로서의 HTML5 가능성 쇠퇴
    • Cross Platform 대응 보다는 각 OS 최적화 개발
    • Native Platform의 대체 SW Platform으로서의 가능성 기대 쇠퇴
  3. 엔진 성능/기능 fragementation 심화 및 개발 환경 미흡
    • Android 버전간 성능 격차/Android/iOS간 성능 격차
    • 개발 툴 부재(debugging/profiling)
  4. HTML5 전문 개발자 부족
    • JavaScript 정통한 개발자
    • Engineering 분석을 통한 Fragementation 극복 역량

그래도 HTML5는 죽지 않았다

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

SK 플래닛의 HTML5 상업적 활용 사례

  1. CSS2D/3D 기반 Web UI
    • Hybrid App내 Native 동등 수준 Web UI
  2. <canvas> 기반 게임
    • 사용자 놀거리 제공: App/서비스 UV 제고

상품화 수준 정의

  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. CPU로 만들어진 texture는 다시 repaint되거나, 가속영역에서 제거되지 않을 경우 OpenGL ES 내에서 연속적인 합성을 위하여 재활용된다.

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 엔진의 설명 자료

Web Inspector

  1. 진정한 의미 개발(Debugging/Profiling)이 가능해 짐
    • Native 수준 복잡도의 Web App 개발 가능
  2. 최근 1년사이 Web Inspector 기능의 비약적인 발전
    • Timeline: style, layout, compositing
    • Profiling: memory, canvas, JavaScript
    • GPU Layer visualization
  3. On-Device 지원
    • Chrome For Mobile/Chrome Webview
    • iOS 6 버전 이상에서 Web Inspector 지원
  4. 상세 정보
    • Google code school: http://discover-devtools.codeschool.com/
    • https://developers.google.com/chrome-developer-tools/

Chrome Dev Tool: Timeline

  • 시간 축으로 주요 Event를 도시
    • network, style 변경, layout, painting, compositing, input event, garbage collection

GPU 렌더링 영역 실시간 도시

  • Web page의 HW 가속 Layer를 Graphical하게 출력 해줌

Canvas Profiling

  • 캔버스의 개별 Primitive 연산결과를 Frame by Frame으로 출력

성능 최적화 절대 규칙: 이것만은 기억하자

  • 애니메이션 Element는 GPU Layer
  • 애니메이션 도중에는 Style 변경 완전 제거
  • DOM 및 Render Object 개수는 최소

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월 버전 부터는 게임 소개페이와 실행 페이지 분리 예정

요리조리 베이스볼 적용 사례

  • DOM/Canvas Hybrid
  • Smart repaint
  • Sprite 이미지 분리

요리조리 베이스볼 적용 사례

  • <canvas> 내 전광판 점수 영역을 DOM으로 분리: Painting 영역 감소
  • 점수 update시 layout 연산발생으로 인한 painting overhead가 증가하여 역효과

2048

  • DOM 방식(open source)
  • 문제점
    • Node 움직이기 시작할때 DOM이 CPU영역에서 GPU 영역, 움직임이 종료시 다시 GPU 영역에서 CPU영역으로 이동
    • 2.3 및 4.04 단말에서 화면이 심하게 깜빡거리고 fps 저하가 심각
  • 해결책: GPU영역에서 유지 되도록 코드 패치

SPACE 2014

  • clearRect VS fillRect
  • 게임 배경 단순화
  • 이전 Frame 1회 재활용

핵심 메세지 정리

  • 모바일 단말에서 30 fps 가능하도록 게임을 기획
    • 게임 오브젝트, 디자인 요소, 배경, 애니메이션
  • Browser 엔진에 대한 기본적인 이해는 성능 최적화에 필수적
    • canvas/DOM Hybrid, 이미지 사이즈 최적화, GPU 활용 등
  • Inspector의 다양한 기능을 활용하여 최적화
    • 성능 분석 용이, 잔 실수를 사전에 차단