The Power of HTML5:
고성능 HTML5 Web App 개발
Beyond the Web front-end you know
Hype or Hope
Two Key Development Policy:
Mobile
Commercial-ready
HTML5 Mobile Web App 개발 및
최적화: The Practice
임상석, Web 기술개발팀
thanks to impress.js for prezi-like styling

핵심 메세지

  1. 안정화된 상용 Platform 수준으로 성숙치 않은 HTML5 기반 상품화의 성공은, 기반하는 Engine 이해가 필수적
    • 무엇을 얼마만큼 할수 있는지를 알아야 뛰어난 Web App을 개발 할 수 있다.
  2. Blackbox로 두지 말고 Tool을 활용하여 분석하자. Native 대비 부족하지만 급격히 기능이 좋아지고 있다.
    • Web inspector를 통한 다양한 profiling 기능이 제공되기 시작함

HTML5 구동 환경 정의

  1. Android 및 iOS가 구동되는 모바일 단말
    • PC환경은 Chrome, Firefox, IE 서로 다른 엔진간의 파편화
  2. WebKit 엔진 계열
    • Firefox, IE, Opera 는 구현 방식이 현격이 다를수 있음
  3. Web site, WebView를 통한 hybrid 공통
    • JIT enable 여부, CSS일부 property등의 동작은 다를수 있으나, 공통적으로 적용 가능

Slide 자체의 동작 기술의 이해

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

고성능 HTML5 Web App 개발 방법 핵심 정리

  1. DOM 및 RenderTree의 복잡도 관리
    • DOM, Render Tree의 생성 및 삭제 원리 이해
    • e.g) Fastbook by Sencha, Infinite Scroll by SK Planet
  2. CSS 2D/3D 기반 GPU 가속 Rendering
    • Timeline, Continuous painting mode
    • Layers in Canary Inspector
  3. WebKit 내부 지식 + DOM Inspector + Practice ==> Commercial-ready 고성능 Web App 개발 매우 기본

Mobile 단말에서 HTML5의 현실

fragmentation은 광범위한 practice를 요구함
                function deviceFragmentationHandler() {
                    //set to use deviceProfileManager
                    var effect = window.getEffect(),
                        device = window.getDeviceInfo();

                    //fragmentation handling is done in three phases
                    //For the first, OS version based tunable paramenter setting
                    //For the secnod, device model based setting as an exception from the OS version
                    //For the third, browser type based setting as an exception from the OS version

                    //Start from OS version based
                    if( (/Android/i).test(device.os) ){
                        scrollerConfig.scrollBar = false;
                        appConfig.resizeDelay = 300;
                    }
                    if( (/Android 2/i).test(device.os) ){
                        scrollerConfig.smartScrolling = true;
                        scrollerConfig.momentumDistCap = window.innerHeight*2;
                        scrollerConfig.updateOnScrollEnd = true;
                        scrollerConfig.offsetYMargin = window.innerHeight*2;
                        scrollerConfig.minYDelta = window.innerHeight*1;
                        scrollerConfig.useTransition = false;
                        scrollerConfig.useRequestAniFrame = false;
                        appConfig.mainListHighlight = false;
                        //안드로이드 2버전에서는 transition 없이 페이지 이동

                        appConfig.transition = "none";//slide disable
                    }
                    if( (/Android 4.0/i).test(device.os) ){
                        scrollerConfig.smartScrolling = true;
                        momentumDistCap = window.innerHeight*3;//iScroll momentun flick distance's maximum value
                        updateOnScrollEnd = false; //not update during scrolling, but do right after scrolling
                        offsetYMargin = window.innerHeight*4;
                        minYDelta = window.innerHeight*4;
                        scrollerConfig.useTransition = false;
                        scrollerConfig.useRequestAniFrame = false;
                    }
                    if( (/Android 4.1/i).test(device.os) ){
                        scrollerConfig.smartScrolling = true;
                        scrollerConfig.momentumDistCap = window.innerHeight*3;
                        scrollerConfig.offsetYMargin = window.innerHeight*10;
                        scrollerConfig.minYDelta = window.innerHeight*10;
                        scrollerConfig.useTransition = false;
                        scrollerConfig.useRequestAniFrame = true;
                    }
                    if( (/iPhone/i).test(device.os) ){
                        scrollerConfig.scrollBar = true;
                        appConfig.resizeDelay = 50;
                        scrollerConfig.useTransition = true;
                    }
                    //device model based
                    if ( (/SHW-M110/i).test(device.modelName) ) {
                        //Galaxy S, Android 2.3 default setting is partially overriden for this device
                        scrollerConfig.momentumDistCap = window.innerHeight*3;
                        scrollerConfig.offsetYMargin = window.innerHeight*2;
                        scrollerConfig.minYDelta = window.innerHeight*2;
                        scrollerConfig.useTransition = true;
                    }
                    if ( (/SHV-E210/i).test(device.modelName) ) {
                        //SHV-E210: 갤럭시 S3
                        if( (/Android 4.0/i).test(device.os) ){
                            scrollerConfig.useRequestAniFrame = false;
                            scrollerConfig.useTransition = true;
                        }
                    }
                    if ( (/SHW-M250/i).test(device.modelName) ) {
                        //SHW-M250: 갤럭시 S2
                        if( (/Android 4.1/i).test(device.os) ){
                            scrollerConfig.useTransition = true;
                            scrollerConfig.smartScrolling = false;
                        }
                    }
                    if ( (/LG-F240/i).test(device.modelName) ) {
                        //Optimus G Pro
                        scrollerConfig.useTransition = true;
                        // scrollerConfig.useRequestAniFrame = true;
                    }
                    if ( (/SHV-E250/i).test(device.modelName) ) {
                        //Galaxy Note  II
                        // scrollerConfig.useRequestAniFrame = false;
                    }
                    if ( (/SHV-E270/i).test(device.modelName) ) {
                        //Galaxy Grand
                        scrollerConfig.useTransition = true;
                        scrollerConfig.smartScrolling = true;
                    }
                    if(device.browser === "ChromeMobile"){
                        scrollerConfig.smartScrolling = false;
                        scrollerConfig.useTransition = false;
                        //Galaxy S4
                        if ( (/SHV-E300/i).test(device.modelName) ) {
                            scrollerConfig.smartScrolling = false;
                            scrollerConfig.useTransition = true;
                        }
                    }

                    if((device.browser !== "ChromeMobile")  !(/iPhone/i).test(device.os)){
                        $.mobile.defaultTransitionHandler = createHandlerA(false);
                        $.mobile.transitionHandlers = {
                            "default": $.mobile.defaultTransitionHandler
                        };
                    }

                    appConfig.fixedElement = effect.fixedElement;
                    //browser type based
                    if(!appConfig.useFixedMenu){
                        appConfig.transition = "none";
                    }
                }

Web App Platform Architecture

  1. Webkit Engine 구조 및 동작
  2. Webkit rendering basics

Webkit Open Source Project: 동거 후 각자의 길

  1. Apple 및 Google 주도의 open source project였음: Google은 분가
  2. Blink: Google이 Webkit project를 forking
    • 기술적으로 Chrome의 multi-process 구조와 Apple주도의 Webkit2 방식의 차이로 인한 기술 발전 속도 지체
    • Web application의 속도를 최대한 빠르게 하기 위함
  3. WebKit 엔진 부분은 현재 큰 차이가 없으나, 앞으로 fragmentation이 급속히 커질것으로 예상(http://www.chromium.org/blink/developer-faq)
    • deliver a speedier DOM and JS engine
    • keep the platform secure
    • refactor for performance
    • enable more powerful rendering layout
    • JS binding, event, style calculate, layout, iframe 부분을 개선하겠다고함 --> WebCore를 포함한 상당한 수정이 불가피

Webkit과 Platform별 Port 이해하기

http://paulirish.com/2013/webkit-for-developers/

Webkit 주요 기능

  1. Parsing(HTML, XML, CSS, JavaScript)
  2. Layout
  3. Text, graphics rendering
  4. Image decoding
  5. GPU interaction
  6. Network access
  7. HW acceleration
1,2 만 공통이고, 나머지는 port 별로 구현 및 최적화 방식이 다름

Chrome 브라우져 구조: Muli-Process

안드로이드 브라우져 구조: Multi-threaded(UI) 4.1 이하

HTML Parser: Basic

Preload Scanner:HTMLPreloadScanner, CSSPreloadScanner

  1. 기본 동작:
    • HTML parser가 script loading을 대기하여 멈출때마다 불린다
    • stylesheet, image등의 network request를 미리 전송하여 전체 loading 시간 개선
    • CSSPreloadScanner는 @import를 preload하는 기능 지원
  2. 사용 Tip
    • CSS stylesheet은 전체가 load된 후에 preload scanning: @import는 되지만 쓰면 늦게 적용
    • head에서 block시 body에 포함된 resource에 대해서는 수행하지 않음: CSS는 head의 최상단에, JavaScript는 DOM parsing 완료 이후로 최대한 미루어야

WebKit 내부 Tree

  1. DOM tree: Document내의 모든 DOM node를 갖음
  2. RenderObject tree: DOM node중에 화면에 보이는 node
  3. RenderLayer tree: 한번에 같이 painting 할 RenderObject를 모아서 관리: 같은 z-index에 있는 node

DOM/Render Tree 복잡도 관리

  1. DOM node 및 Render Object 개수는 최소화
    • DOM node 재활용: DOM node 상수개 고정
    • 동적으로 삽입/삭제
    • display:none 설정 -> 해당 Render Object 제거, DOM node 유지
    • visibility:hidden -> Tree 복잡도 유지되나 painting cost 절감 가능
  2. animation동안 DOM 내용 변경 절대 지양
    • recalculate style -> layout -> painting을 야기하여 bumpy animation의 주요 원인
    • Inspector로 확인시 Composite Layer만 존재할 경우가 최적
  3. iframe으로 view 분리 (sandboxing)
    • iframe으로 분리되면 아무리 복잡하더라도 서로 분리된 view간 영향을 주지 않음
    • long-running app 개발시에도 메모리 leak 대응 용이

WebKit 내부 Tree

RenderLayer Tree 생성: Stacking Context 관리

overlapping 영역 관리

RenderLayer Tree 생성 대상

  1. Root Objet
  2. CSS position: relative, absolute, transform
  3. opacity, overflow, alpha mask, reflection
  4. CSS filter
  5. canvas 2D, 3D
  6. video

GraphicsLayer Tree 생성

  1. 3D 또는 perspective transform CSS 속성
  2. video, canvas 2D/3D, composited plugin, CSS filter
  3. 투명도로 CSS animation 수행, webkit-transform 수행
  4. CSS filter
  5. z-index가 낮은 형제가 compositing layer를 갖는 경우(위 생성조건을 만족하지는 않지만 z-index에 의해서 compositing layer 위에 위치하는 경우)

다중 Layer Painting 절차

  1. SW rendering path (CPU)
    • 하나의 graphic buffer를 할당(mobile에서는 이것도 GPU를 활용하는 texture 임, ana backingstore)
    • Z order에 따라 뒤에서 앞으로 칠함: Hello를 칠함 --> World 칠함
  1. HW 가속 path: Accelerate compositing by GPU
    • CPU graphcs buffer와 GraphicsLayer 별 GPU가 접근하는 buffer 생성
    • Layer별로 주어진 buffer에 painting: 변경 내용이 없으면 buffer를 그대로 둠
    • 모든 결과를 sync후 GPU를 통해서 compositing하여 하나의 결과물로 만든 후 windowing system buffer로 복사

GPU기반 합성

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

GPU Texture 생성/변경/제거

  1. 생성
    • CPU로 주어진 GraphicLayer에 속한 Element를 GPU가 접근 가능한 메모리로 정의된 surface로서 painting 연산 수행
  2. 변경
    • 한 pixel이라도 변경되면, 전체 GraphicsLayer를 CPU를 통하여 다시 painting
  3. 삭제
    • GraphicsLayer 생성조건을 만족하는 CSS 속성 제거시 Texture는 제거되고 SW rendering path로 변경됨
    • display:none 또는 visibility:hidden(버전 따라 다름)시 Texture는 제거
  4. 성능 tip
    • 한번 생성한 Texture는 변경하지 않는것이 성능에 가장 기본
    • 변경 필요시 painting이 발생하는 단위로 GraphicsLayer가 생성되도록 속성 지정: Texture 개수 증가는 성능 저하 가능성 증가!

고성능 Animation을 위한 Tip: No painting while animating

  1. Animation 도중 painting 발생하는 연산 미사용
  2. CPU로 생성하는 Texture는 재활용
    • animation완료후 transform 속성 미제거
  3. 내부 timer를 사용하는 keyframe animation/transition을 사용
    • Webkit 내부에서 수행되고, JavaScript 개입(style 변경)이 없어서 매우 빠름
    • 지정된 시간동안 animation의 완료가 interrupt되는 경우 사용자 반응성이 떨어질수 있음(뒤에서 설명)
  4. 합성 layer 수는 최소로 유지: 일부 단말에서 성능 저하
    • Chrome에서 layer용 VRAM이 소진시 오히려 성능이 느려지거나, silent crash
    • * { -webkit-transform: translate3d(0,0,0) 를 무턱대고 쓰지말고, 왜 느린지 원인을 분석해서 꼭 필요한 경우에만 적용하여 해결하라
  5. animation flickering 원인 및 대처
    • scrolling 동안 GPU texture/tile을 swipe in/out 하면 발생
    • CPU rendering을 GPU rendering으로 switch 하는 경우 발생
    • 대처: CPU와 GPU communication 최소화

Declarative vs JavaScript 기반 Animation

  1. Declarative Animation
    • CSS로 animation 설정
    • WebKit 엔진 내에서 최적화 가능
    • main thread가 overloaded되어도 수행이 됨
  2. JavaScript Animation
    • 애니메이션 시작, 끝, 일시중지등 복잡한 형태를 구현 가능
    • main thread가 overloaded될 경우 animation이 제대로 수행되지 않음
    • main thread의 부하를 증가 시킴
    • https://github.com/ianvollick/animation-proxy/blob/master/Explainer.md
    • http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/

Animation시 Trouble Shooting

  1. -webkit-transition-delay 오류: Chrome일부에서 멈추기 위해서 0으로 setting해도 멈추지 않음 --> 1로 설정
  2. -webkit-transition-delay 속성 변경시 적용되는 전체 DOM이 repaint 되는 오류 --> painting cost 줄이기
  3. 합성 layer에 scale되는 image 포함시 painting 발생 --> image를 offline에서 scale
  4. requestAnimationFrame사용시 성능이 오히려 저하: setTimeout(1000/60), (1000/120)
  5. Android 4.03/4.04에서 animation 시작시 화면이 깨지는 이슈: AC 구현 방식의 변경으로 Texture를 생성하는 delay가 매우 느림. 단, 생성된 Texture로 animation은 그전 버전 대비 많이 빠름
  6. iOS를 포함하여 화면이 지글거리거나 깨지는 현상: -webkit-backface-visibility:hidden으로 설정

Web Animation: 새로운 표준

  1. requestAnimationFrame기반 JS 방식의 단점과 key-frame animation 방식의 단점을 해결
  2. requestAnimationFrame: 매 frame JavaScript를 실행 해야 함
  3. keyframe animation: 세세한 animation control을 할수 없음
    • Global Clock을 두고 CSS effect, SVG effect, custom effect를 수행
    • element.animate()로 동작하는 animation을 직접 통제 가능/li>
  4. https://www.youtube.com/watch?v=ep0_0W0qWsc

Webkit엔진 메모리 관리

  1. space를 좀더 쓰더라도, object 생성/삭제가 빠른 방법이 필수
    • DOM/Render tree생성 및 JavaScript 실행시 수많은 C++ object가 생성/삭제됨
  2. fastMalloc: Google의 TCMalloc의 derivative로 WebCore와 JavaScriptCore에서 사용
    • Thread local cache 와 central page heap(large object)을 별도로 관리하여 성능 향상
    • Small object 할당: 60개의 size class로 구분하고 singly-linked list로 관리
    • Karge object 할당(32KB): 4K 단위 page의 group의 list로 관리
  3. system malloc: memory allocator로 WebKit이 사용하는 외부 library에서 사용
  4. 속도는 빠르지만, 충분히 사용하고 빠르게 반환하지도 않음: 할당 보다 반환에 보수적임
  5. 메모리 절약 Tip
    • 새로운 object를 생성하기전에 쓰지 않는 ojbect를 먼저 제거한다.
    • Single DOM App 경우, AJAX로 신규 page를 loading전에 inactive page를 미리 DOM에서 제거

소중한 Memory는 어디로: Memory-hog Webkit

  1. Runtime 환경으로 RenderTree, DOM tree를 포함한 수많은 객체 및 JavaScript 수행
  2. Page cache: DOM을 통채로 유지함 ANA back/forward cache
    1. SSL, load/onload handler등록, form 등이 있을때,
    2. load fail이나 error 발생된 페이지는 cache 하지 않음
  3. Decoded image cache: decoding된 image를 painting하기 위해 cache
    • painting은 decoded image cache에서 가져다 함
    • decoded image가 특정 크기가 넘어가면 cache 하지 않음(2M, 3M으로 compile 시간에 정함
    • mobile 단말에서는 cache가 되지 않으면 painting 성능 저하가 클수 있음: iOS는 RAM크기(256MB기준) 제약이 있다.
  4. Component cache: 각종 resource cache

LLVM JIT

  1. JavaScript 수행 속도를 Native 수준으로 끌어 올리는 기술
  2. LLVM을 통해서 다양한 방식의 코드 생성 최적화를 수행
  3. https://www.webkit.org/blog/3362/introducing-the-webkit-ftl-jit/

CSS JIT

  1. CSS Selector Matching을 수행하는 Native 함수는 매우 generic 함수
  2. 실제 Web Page에서 사용된 CSS Selector용 전용 Native Selector Match 함수를 동적으로 생성
  3. psuedo selector는 기존의 generic/slow path를 사용/li>
  4. https://www.webkit.org/blog/3271/webkit-css-selector-jit-compiler/

Web App 개발용 Tooling 현실

Web App Tooling: 이제 시작일 뿐

  1. Native 대비 매우 열악함, 그러나
  2. 최근 1년 사이 Web Inspector의 비약적인 발전
    • 단순 요소 검사이외에 Timeline 및 Profiling 기능 제공
  3. Chrome For Mobile 및 iOS 6 버전이상에서 Web Inspector 지원
    • Android 젤리빈부터는 Chrome for Mobile이 Binary 형태로 제공 --> 제조사 customize 불가
    • But, 제조사별로 별도 side-loading 가능: Galaxy S4는 Chrome 계열이나 미지원 T.T
  4. 이제부터 시작이고, 지속적인 발전 예상 --> 사용법을 잘 익히는 것이 필수
    • 상세 profiling을 통한 성능 개선은 사용성, battery 절약에 매우 중
    • Google code school: http://discover-devtools.codeschool.com/
    • https://developers.google.com/chrome-developer-tools/

Chrome Dev Tool: Timeline

  1. 상단 panel
    • Events: 시간축으로 발생한 event를 순차적으로 보여줌
    • Frames: 시간축으로 매 frame 단위로 event를 순차적으로 보여줌
    • Memory: 메모리 사용 양을 보여줌
  2. 하단 record panel
    • Recalculate Style: 변경된 CSS 속성값에 따라 전체 style 값을 다시 계산
    • Layout: 변경된 style값에 따라 element의 위치 값을 재계산
    • Paint: layout이 완료된 RenderLayer들에 속한 element들을 z-ordering을 고려하여 그리
    • Composite Layers: Document를 구성하는 모든 RenderLayer를 합성하여 화면에 최종 출력
    • 각종 event fire: setTimout, requestAnimationFrame등

Timeline 분석 및 Painting 성능 최적화 1/2

  1. -webkit-transform 제거시 animation이 완료된 후 GPU 영역에서 제거되고, 추후 animation시 다시 CPU로 painting 하게

Timeline 분석 및 Painting 성능 최적화 2/2

  1. GPU 가속 device에서 CSS animation시 painting(by CPU)은 최초 1회만 발생하는 것이 이상적
  2. Paint는 강적이다. 긴 Paint는 주적이다 (paint는 일반적으로 layout의 결과로 수반됨)

Long Paint 분석 및 최적화: Continuous Painting Mode

  1. Chrome canary에서 지원
  2. 강제적으로 연속적으로 painting을 수행하므로 높은 painting 비용의 element를 쉽게 찾을수 있다: CTRL+H로 hidden

Chrome Dev Tool: Profiling

  1. JavaScript, CSS를 sampling 방식으로 profiling 결과를 알려줌
  2. 현재 Browser내의 heap memory 사용량을 snapshot으로 알려줌

Chrome Dev Tool: on-device

  1. 설치
    1. Android SDK 설치
    2. 단말 Chrome setting에서 USB debugging mode enable
    3. 단말 케이블 연결
    4. Dev Tool을 단말에 연결: adb forward tcp:9222 localabstract:chrome_devtools_remote
    5. PC의 chrome에서 localhost:9222 open 후 연결된 page click
  2. starting guide: http://www.html5rocks.com/en/mobile/profiling/#toc-starting-guide

transtiion을 이용한 animation의 성능 분석

timeline panel programming(4 Chrome)

  1. custom annotation: console.timeStamp("My Event")
  2. custom timeline marker: console.time("Start"); console.timeEnd("End");

Composite Layer Viewer: Hot and Cool!

  1. Web page의 HW 가속 Layer를 Graphical하게 출력 해줌
  2. 설치
    1. Chrome Canary의 about:flags page 진입
    2. experimental debugging feature enable
    3. browser restart
    4. DOM inspector 설정의 experimant Tab에서 "Show Layers Panel" 클릭
    5. Inspector 상단에 Layer panel 생성

Chrome://tracing

  1. 궁극의 Profiler로 thread/process 단위로 profiling
  2. Profiling할 tab만을 남기고 모두 닫은후 Profiling 수행
  3. Compositor thread와 RendererMain thread를 집중적으로 분석
  4. keyboard로 결과 navigation: a(좌),d(우), w(zoom in), s(zoom out)

DumpRenderTree

  1. WebKit 엔진이 주어진 HTML을 읽어서 내부적으로 생성하는 RenderTree를 출력해주는 기능
  2. Web Inspecor에서 보이지 않는 Render Tree 구조를 직접 확인하고 최적화가 가능함
  3. 설치 및 실행
    1. www.webkit.org에서 webkit source code down 및 build
    2. /Tools/Scripts/run-webkit-tests HTML문서이름

Painting 성능 최적화: Layout 및 Repaint를 최소화 (1/2)

  1. Layout 및 Repaint trigger 요인
    • DOM node의 add/remove/update
    • DOM node를 display:none, visibility:hidden(layout은 미발생), DOM을 움직일때
    • stylesheet을 추가하거나, style property를 변경시
    • window resize, font 변경
  2. Repaint only: visibility, color, transform, background-image, transparency 변
  3. Webkit은 paint throttling queue을 통해 연속되는 request를 한꺼번에 모아서 수행, 아래의 경우는 queue를 flush 하므로 잘알고 사용해야 함
    • offsetTop, offsetLeft, offsetWidth, offsetHeight값을 JavaScript로 접근
    • scrollTop/Left/Width/Height , clientTop/Left/Width/Height , getComputedStyle()
  4. throttling queue등의 최적화로, 실제 화면에 paiting이 완료되는 시점을 정확히 하는 것은 불가능
    • Welocom to setTimeout() hell

Painting 성능 최적화: Layout 및 Repaint를 최소화 (2/2)

  1. 개별 style을 하나씩 변경하지 말고 class로 일괄 적용 또는 cssText에 적용
  2. DOM의 변경은 documentFragement를 이용하여 offline으로
  3. display:none 상태에서 일괄 변경 후 다시 보여주기
  4. computed sytle값을 읽는 회수로 최소화
  5. 자주 변경되는 element는 offsetParent 변경되지 않는 element의 offsetParent로 부터 분리: absolute position을 활용

단말에서 비싼 CSS

  1. rounded corner
  2. box-shadow, text-shadow
  3. background-position, background-repeat, 2개 이상의 background image
  4. border-image
  5. gradient
  6. HW 가속 받지 않는 CSS filter

모바일 단말 Anomaly

  1. transition 오동작
    • -webkit-transition: 0s를 주어 진행중인 animation을 멈추는게 일반적
    • Chrome for Android 일부 버전에서 동작하지 않음: workaround 0s가 아닌 1s
    • -webkit-transition 속성 변경시 해당 element 전체에 대해서 repaint 발생 (일부 Chrome)
  2. CSS fixed element내에 absolute 포함시: 화면 전체 영역에 대한 repaint 발생
  3. resize 된 image가 -webkit-transform element에 포함시 repaint 발생
  4. scrolling 도중 unnecessary paint 발생(Chrome)
    • position:fixed, overflow:scroll 사용
    • hover effect 사용
    • touch listeners 등록된 경우

stroll.js 최적화 실전

  1. 부드러운 animation
    • li 단위로 Texture를 생성하고 유지하기
    • 한쪽 방향만 animation을 수행하도록 하여 동시 수행 animation 수를 줄이기
    • scroll bar 그리지 않기
    • absolute position으로 고정후 동적으로 display:none 설정:Plaga Smart Scroller 적용 전후 비교
    • scrolling 동안 신규 li를 display:none 해제 하지 않기

HTML5 Game 개발: DOM vs Canvas

  1. DOM: CSS3 with HW 가속
    • retained mode: scene graph 제공
    • event handler 등록하여 처리
    • HW Accelerated Composition
    • DOM의 증가 성능 감소
  2. Canvas
    • immediate mode
    • canvas로 hit test 및 object 모델링(scene graph)
    • painting의 무한 반복
    • painting이 느리면 속도가 감소
    • DOM node 개수는 증가하지 않음

HTML5 Game 개발: Hybrid

  1. DOM
    • Painting이 필요하지 않고 위치만 변경되는 layer
    • 배경, 정적인 Object
  2. Canvas
    • Game animation과 같이 매 frame painting이 필요한 부분
    • 총알 같이 개수가 많은 object
    • Canvas내에서도 Layer로 구분하여 painting 후 CSS로 합성하여 출력

HTML5 Game 개발: 단말에서 성능 개선

  1. WebWorker
    • Physics Engine
    • Network 게임: 서버 통신 부분
  2. Canvas는 화면 Painting 영역에 크기에 비례하여 성능 감소
    • Canvas로 그리고 CSS style로 늘리기
    • 최소 2가지 해상도 게임 개발

결론

  1. 속도 관련 모든 최적화는 Web Inspector를 통해 분석하는 것으로 부터 시작
  2. 모바일 단말별 Browser 구현에 따른 오동작 발생은 피할수 없지만, 대부분 회피는 가능하다.
    • Sencha, jQueryMobile등의 framewwork 도입으로 부분적으로 해결 가능
    • 문제에 따라서는 GUI나 UX를 변경해야 함
  3. Mobile 환경에서의 HTML5 활용은 큰 흐름이나, 현 시점에서 상품화까지 목적으로 할 경우 단순한 cross-platform에 대한 환상만으로 시작은 금물
  4. Hybrid app 개발자라면 Native와 Web의 요소를 어떻게 mix할 것인지 사용자/서비스 운영 관점에서 결정
    • 나는 뛰어난 개발자 이므로 단순히 모든 것을 native 또는 Web으로 하겠다는 것은 비효율적인 생각

질문

  1. iOS도 Web Inspector 사용 가능 한가요? 예 iOS 6.0이상에서 가능 합니다.
  2. 단말별 browser별 fragmentation은 언제 사라질까요? 사라지지 않고 심화될 가능성이 농후 합니다. Android, iOS, Tizen, Windows별로 fragmentation handling은 필수 입니다. framework의 사용으로 고통을 완화 할수 있습니다.
  3. Hybrid app 개발시에도 적용 가능한가요? 설명드린 tip은 가능하지만, Web Inspector는 App으로 직접 붙일수 없고 Browser 에서 별도로 적용후 통합 하여야 합니다.
  4. layout과 painting이 끝난는지 정확히 알수 있는 방법이 있나요? 아직까지는 setTimeout으로 충분히 기다리는 것 이외에 대안을 찾지는 못했습니다.