티스토리 뷰

dev.

html5 성능최적화 방법들

아바게임즈 2019. 2. 11. 13:25


<header style="margin: 0px 0px 10px; padding: 0px; border: 0px; outline: 0px; font-size: 15px; vertical-align: baseline; background: rgb(255, 255, 255); color: rgb(136, 136, 136); font-family: "Helvetica Neue", Helvetica, Verdana, Arial, 나눔고딕, NanumGothic, "맑은 고딕", "Malgun Gothic", sans-serif;">

HTML5 모바일 웹 애플리케이션의 성능 최적화 방법들

<time datetime="2013-06-03T10:38:36+00:00" pubdate="" style="margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: baseline; background: transparent;">2013/06/03</time></header>

HTML5기반 모바일 웹 애플리케이션 또는 서비스를 상품화 시 네이티브 애플리케이션 대비 경쟁력 있는 SW 품질을 달성하기 위해서는 개발된 모바일 웹 애플리케이션의 성능 최적화를 단말 부분과 서버와 연동 부분을 모두 아우르는 최적화가 수행하는 것이 필수적입니다. 단말부터 서버까지를 고려하지 않는 단편적인 성능 개선은 실질적인 애플리케이션 성능 개선효과가 반감이 되기 때문입니다. 예로써, HTML/CSS 렌더링 성능 관점에서 최적화된 HTML, CSS, 자바스크립트를 멋지게 구현하였더라도, 네트워크를 통한 배포 관점에서 이것들이 변경사항이 없음에도 불구하고 단말 상에 caching되지 않거나 내재된 파일들이 병렬로 네트워크를 통해 전송되지 않는다면 전체 성능 관점에서는 매우 심각하게 저하됩니다. 이에 이번 포스팅에서는 단말에서 서버까지 성능에 영향을 주는 단말 단 Web 플랫폼의 핵심인 WebKit 엔진의 핵심구조 및 각종 지연 요소를 분류합니다. 그리고 이를 근간으로 각 지연 요소 별 최적화 방법론에 대해서 실무 경험 위주로 정리하였습니다. 그리고 추가하여 이러한 최적화 시 활용 가능한 오픈소스 프로파일링 도구들을 정리하였습니다.

HTML5 모바일 웹 애플리케이션 플랫폼 내부: WebKit 엔진 중심으로

HTML5 웹 애플리케이션 플랫폼은 그림 1.에서와 같이 다계층 구조로 이루어지고, 다시 구현 및 배포방식에 따라 크게 두 가지 계층으로 구분됩니다.

그림1. 개념적 Web 플랫폼 SW 계층도

회색 음영 처리된 부분으로 단말의 운영체제종류에 따라 구성되는 네이티브 부분과 그 위에서 구동되면서 실제 HTML, CSS, 자바스크립트로 HTML5 애플리케이션 작성 시 필요한 HTML5 애플리케이션 프레임워크 부분입니다. 네이티브 플랫폼 부분은 플랫폼 업체 또는 단말 제조 업체가 단말HW에 탑재하여 배포하는 부분으로 구현 변경이 사실상 불가능한 부분이나 실제 HTML5 애플리케이션 프레임워크를 구축 시 HTML5 애플리케이션의 runtime을 제공하고 각종 성능 최적화 시 필요한 기술 범위에 포함되는 부분으로서 깊은 이해가 필수적입니다.

그림1.에서와 같이 이 두 계층은 WebKit엔진에서 제공하는 DOM의 자바스크립트 바인딩 layer를 중심으로 나뉘게 됩니다. 프로그래밍 관점에서 웹 애플리케이션은 Web 플랫폼에서 제공하는 모든 서비스를 DOM 자바스크립트 바인딩을 통해서 접근한다. HTML5 애플리케이션 프레임워크는 실제 HTML 5 표준에서 제공하는 각종 HTML5 마크업, CSS3 그리고 자바스크립트 API로 바인딩 되는 부분과, 표준 이외에 애플리케이션작성시 필요한 자바스크립트 라이브러리들로 구성 됩니다.

첫 번째로 웹 애플리케이션 플랫폼의 네이티브를 담당하는 부분을 아래 그림2.와 같이 좀더 구체적으로 도시하였습니다. WebKit엔진은 HTML, CSS, 자바스크립트의 파싱, 렌더링, execution을 담당합니다. 네이티브 Web 플랫폼은 크게 운영체제 별로 Widget 및 API를 제공하는 WebView와 HTML, CSS, 자바스크립트를 파싱하고 실행시키는 WebCore와 자바스크립트엔진, 그리고 파싱된 결과를 화면에 실제 렌더링하는 플랫폼 포트로 구성이 됩니다. WebKit자체는 오픈소스로서 상당 부분의 코드를 공개하여 공유 하지만 그림2.에서의 플랫폼 이름 별로 각각의 플랫폼 별도의 구현부가 존재합니다. 플랫폼 별 실질적인 브라우저 및 웹 애플리케이션의 성능 차이는 플랫폼 포트 부분의 제조사별 최적화 정도에 따라 주로 발생합니다. Apple사의 Mac 운영체제와 iOS용 포트는 오픈소스로 공개되어 있지 않습니다.

그림 2. WebKit 기반 네이티브 부분 상세도

본 절에서는 HTML5 웹 애플리케이션 개발 시 성능과 밀접한 관련이 있는 내부구조에 대해서 살펴 보겠습니다. WebKit엔진은 입력받은 HTML과 CSS를 파싱하여 중요한 두 개의 데이터 구조인 DOM 트리와 Render 트리를 생성합니다. DOM 트리는 HTML 다큐먼트를 접근 및 변경 할 수 있도록 표준 규격에 따라서 자바스크립트 객체 형태로 웹 애플리케이션에 제공됩니다. 이러한 DOM 트리는 HTML이 기술한 다큐먼트의 구조를 유지하고 WebKit은 DOM 트리와는 별도로 실제 화면에 렌더링시 사용하기 위하여 Render 트리를 구성합니다. 이는 HTML 파서에서 DOM 트리에 새로운 노드를 붙일때마다 RenderObject를 생성하여 Render 트리에 삽입하여 구성한다. DOM 트리의 각 객체 노드 중 화면에 공간을 차지하고 실제 렌더링이 되는 노드들만이 상응하는 Render 트리의 객체를 생성 시킵니다. CSS 속성 중 display:none통해서 화면의 공간을 차지하지 않게 설정하면 해당 DOM 노드는 계속 유지하지만, 해당 RenderObject는 Render 트리에서 제거되게 됩니다. 이러한 동작 방식은 추후 스크롤 성능 최적화 시 꼭 알아야 할 기본 지식입니다. 스크롤과 같은 연산에 의해서 화면을 갱신할 때는 DOM트리나 Render 트리의 구조의 복잡도 또는 노드 수가 많을 수록 소요시간이 증가하게 됩니다.

<html>
<head>
<title>SK Planet</title>
<style>…</style>
<script>…</script>
</head>
<body>
 <div>
 <span> <a href=“abc.com”>News</a> </span>
 <span>…</span>
 </div>
 </body>
</html>

위 표의 HTML 마크업을 입력으로 하여  WebKit엔진에 의해서 생성된 DOM 트리와 Render 트리를 그림 3.에 도시하였습니다. DOM 트리의 각 노드중에 화면에 실제 표시되는 부분에 해당하는 “News”와 그것의 부모 노드들만으로 구성된 sub트리형태를 구성하는 RenderObject들로 전체Render 트리가 구성되어 있음을 확인할 수 있습니다. 참고로 DOM에서 제공하는 Event Capturing과 Bubbling은 DOM 트리만을 traverse하여 수행합니다.

위와 같이  Render 트리가 구성되면 WebKit엔진은 구성된 Render 트리를 traversing하며 RenderObject의 내용에 따라 화면에 실제 렌더링을 수행하게 됩니다. 이러한 Render 트리의 생성 후에는 사용자의 action또는 자바스크립트등에 의해서 화면 갱신을 수반하는 연산 결과를 필요에 따라 렌더링을 수행합니다. 이러한 렌더링을 위하여 WebKit엔진은 RenderLayer 트리라는 것을 추가적으로 생성합니다. RenderLayer는 일반적으로 화면에 그릴 때 그리기의 속성이 유사하여 한번에 같이 그려낼 때 효율적인 Render 트리의 서브트리들로 분리하여 다시 트리로 구성됩니다. Render 트리에서 RenderLayer 트리를 구성 시 개별RenderLayer의 생성 조건은 아래와 같습니다.

  • 전체 page에 대한 root (최소 한개 기본 생성)
  •  명시적으로 CSS position속성 설정 (relative, absolute, transform)
  •  Transparency 값 설정, overflow, alpha mask, reflection 설정
  •  <canvas>, <video> element

그림 3. DOM 및 Render 트리 생성 예제

최근에 WebKit에 구현된 기술인 HW Accelerated Compositing (AC)은 위와 같이 분리 된 RenderLayer를 기본 단위로 합성을 수행합니다. HW AC는 일반적으로 OpenGL ES를 지원하는 GPU(Graphics Processing Unit)에서 RenderLayer간 고속 compositing을 수행하는 기술입니다. HW AC가 지원되는 WebKit에서는 개별 Render Layer별로 GPU에 의해서 접근되는 텍스쳐 메모리를 별도로 생성하여 매핑하고, 해당 텍스쳐 메모리에 CPU로 해당 RenderLayer에 포함된 콘텐츠를 출력하여 저장합니다. 이렇게 생성된 텍스쳐는 추후에 compositing 연산시 활용이 되며 해당 RenderLayer의 콘텐츠가 invalidate되거나, 메모리 부족으로 텍스쳐가 flush되지 않는 한 추후 렌더링시 해당 RenderLayer의 콘텐츠를 CPU를 통해서 다시 렌더링하지 않고 계속 재활용이 됩니다.

그림 4. RenderLayer 생성 예제

그림4.에서는 설명한 내용의 이해를 돕기 위하여 RenderLayer가 생성되는 절차를 예제를 통하여 도시하였습니다. Root Layer한장은 기본 생성이 되고 rotate class에 적용된 -webkit-transform 속성에 의하여 “world”라는 콘텐츠를 갖는 RenderLayer가 추가로 생성이 되어 트리에 포함되어 크게 두개의 RenderLayer로 구성됩니다. 이렇게 생성된 RenderLayer 트리를 활용하여 실제 화면에 렌더링하는 방식은 그림5.에 나타냈다. 먼저 좌측 방식을 살펴보면 HW AC를 지원하지 않는 WebKit엔진에서는 CPU가 한 장의 canvas (렌더링 결과를 저장하는 메모리로 개념적으로 프레임버퍼로 출력되는 버퍼)를 생성해서 Root RenderLayer와 RenderLayer1을 통해서 최종 출력용 이미지 한 장을 즉시 만들어 냅니다. HW AC가 지원되는 WebKit에서는 각 Render Layer별로 총 두장의canvas를 생성하여 각각에 대해서 별도의 canvas로 렌더링을 수행합니다. 이때 “world”를 포함한 canvas는 GPU의 텍스쳐로 생성이 됩니다. 이렇게 생성된 두 장의 canvas는 GPU를 사용하는 HW compositor를 통하여 화면에 출력할 최종 image한 장을 생성합니다.

그림 5. HW Accelerated Compositing 동작

이 때 성능에 가장 결정적인 영향을 주는 상황은 그림4.의 좌측 상단의 HTML예제에서 구현된 <script> 블락을 통하여 애니매이션효과를 줄 때 명확히 설명 가능합니다. 해당 예제는10msec주기로 incRotateDeg(10)을 호출하여 “world”를 포함한 canvas를 10도씩 추가로 회전시켜 애니메이션을 구성하고자 할때 HW AC를 지원하지 않는 방식은 “Hello”, “world” 두 부분을 전체를 매번 Render 트리를 traversing하여 다시 렌더링하여 최종 image를 만들어내는 반면에 HW AC를 지원하는 WebKit에서는 별도의 렌더링은 발생하지 않고 단순히 “world”를 포함하는 텍스쳐를 GPU를 통하여 회전시킨 이후 compositor로 합성만 해서 최종 image를 만들어냅니다. HW AC를 지원하는 방식은 이러한 애니매이션에 대해 HW AC방식은 지원하지 않는 버전에 비해 수배까지 빠른 성능을 보여주게 됩니다.

지금까지 설명한 내부 동작 방식을 잘 이해하고,  모바일 웹 애플리케이션을 개발할때는 주어진 WebKit의 HW AC의 지원여부를 판별하고 이에 따라 GPU를 최대한 사용하는 방향으로 code를 구현하여야 충분히 빠른 성능을 달성할수 있습니다. 그러나 HW AC방식은 지정된 Render Layer를 텍스쳐라는 추가 메모리를 사용하여 저장하므로 메모리 사용량이 늘어나는 단점이 있습니다. 모바일OS별로 메모리 사용량 개선을 위해서 텍스쳐 Atlas 기법을 도입하기도 하므로 단말 별 상세 분석이 필요합니다.

End-To-End관점 에서 웹 애플리케이션 성능 최적화

모바일 웹 애플리케이션 구동 시 서버에서 단말 단까지 구성되는 지연 요소는 크게 단말에서의 HTML,CSS, 자바스크립트 처리와 서버에서의 처리 지연 그리고 네트워크 전송 부분으로 구성되고 상세하게 W3C에서 개념화하여 도시하였습니다. 본 장에서는 위 세 가지 부분을 아우르는 성능 최적화 방법에 대해서 소개하고, 이를 위하여 사용 가능한 오픈소스 도구를 소개합니다.

산업 현장에서의 성능 최적화 방법은 플랫폼 별로 다양한 경험들의 집합으로 구성이 됩니다. 필자의 경험에 비추어 기반 기술 관점에서는 그것들을 아래와 같은 방식으로 크게 구분이 가능합니다.

  1. 파싱
    • 병렬 자원 적재 극대화
      • document.write() 미사용
      • iframe, CSS @import 미사용
      • 외부 CSS는 외부 JS 이전에 적재
    • 파싱 비용 절감
      • HTML/CSS/자바스크립트 minifying
  2. Layout 및 렌더링
    • Layout 발생 빈도 및 비용 최소화
      • DOM 트리 노드 개수 최소화
      • CSS display property, CSS box model값의  변경 최소화
    • CPU 과도 사용 기능 사용 최소화
      • corner, shadow, background-repeat, gradient 등
  3. Graphics/애니매이션
    • HW AC 지원 플랫폼에서 CSS 2D/3D 애니매이션 효율적 사용
      • 애니매이션 대상 Layer개수 및 크기 최소화
      • 애니매이션 Layer의 콘텐츠 내용 미변경
    • HW AC 미지원 플랫폼에서 애니매이션 사용 최소화
  4. 자바스크립트
    • 자바스크립트 적재 시간 최적화
      • 첫 화면 구성 시 즉시 필요한 자바스크립트와 필요하지 않은 자바스크립트를 분리하여 lazy loading
    • 자바스크립트 수행 코드 수행 시간 짧게 유지
      • 자바스크립트 수행 동안 main UI thread는 중지됨
    • DOM 처리 방식 효율화
      • DOM 연산 결과 caching
      • DOM 변경 시 개별 노드단위 반복 변경 보다는 배칭 작업
      • DOM 노드 변경은 오프라인 에서 수행 (변경노드 떼기->연산-> 붙이기)
  5. 네트워크
    • 네트워크 요청 개수 줄이기
      • CSS sprite 사용
      • DATA URI로 문서에 자원 포함
      • Local storage 및 HTTP cache 적극 활용
      • CSS, 자바스크립트 파일 통합

위와 같은 가이드를 적용하기 위해서는 실제 작성된 애플리케이션을 프로파일링하고, 최적화 작업을 도와주는 도구들의 사용은 필수적입니다. 아래 나열된 리스트는 바로 활용 가능한 오픈소스 도구들에 대해서 특징 및 활용 방식에 대해서 간략히 정리하였습니다.

  • 구글 Page Speed
    구글에서 정한 기술 요건을 기준으로 작성된 애플리케이션 기준 부합 여부 여부를 100점 만점으로 제공하고 실제 적용 가이드라인을 제공하여 매우 유용함
  • 구글 Speed Tracer
    파싱, execution, layout,CSS style recalculation, selector matching, DOM event등 상세 동작정보를 도시화
  • 클로져 Compiler
    자바스크립트 code를 분석 후 minify, dead docde 제거등 최적화 수행 및 Whitespace only, simple optimization, advanced optimization의 3단계 최적화 수준 선택 가능
  • DOM Monster
    Bookmarklet 형태로 제공되는 DOM 구성 내용 상세 분석 및 출력
  • CSS Sprite Generator
    여러장의 image를 한장으로 묶어주는 기능
  • Chrome Developer Tools
    DOM inspection 기능timeline으로 파싱, style calculation, garbage collector, 자바스크립트 수행 정보를 출력WebKit 내부에서 CPU usage profiling 기능

지금까지HTML5 모바일 웹 애플리케이션 플랫폼구조에 상세히 살펴보고 이러한 플랫폼에서 동작하는 웹 애플리케이션의 성능 최적화시 활용 가능한 각종 practice 및 오픈소스 도구를 소개하였습니다.

위에서 나열한 각종 최적화 기술들을 활용하여 네이트브 형태의 T Store의 HTML5버전의 프로토타입을 개발하였습니다.
아래 비디오의 왼쪽의 단말은 오른쪽 단말에 비하여 li 단위의 애니메이션과 속도가 우수합니다.
이는 왼쪽 단말에서는 -webkit-transform 속성을 li에 부여하고 이것을 유지하여서 애니메이션 동안 지속적으로 GPU가속을 받도록 구성을 하였고, 오른쪽 단말은 애니메이션이 시작 시점부터 끝까지 GPU로 애니메이션을 수행하나, 완료 시 -webkit-transform 속성을 제거하여 연속되는 애니메이션 동안 매번 CPU가 개입하여 새롭게 texture를 생성하기 위해 페이팅을 수행하도록 구성하였습니다.
비디오에서 확인가능한 바와 같이 왼쪽의 li의 animation 및 스크롤링이, 오른쪽에 비하여 상당히 부드러움을 알 수 있습니다.

이번 포스팅이 모바일용 HTML5 애플리케이션 플랫폼 또는 애플리케이션 개발 시 부딪칠 각종 기술 이슈에 대해서 폭넓게 이해를 하고 실무 개발에 적용 가능한 레퍼런스로 활용되기를 기대해 봅니다. 다음 포스팅에서는 CSS 2D/3D를 기반으로 Web UI를 저작 시 성능 확보를 위한 각종 팁과 최적화를 수행하는 방법에 대해서 다루고자 합니다.


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함