웹솔루션개발 22년 노하우! 해피CGI의 모든것

[해피CGI][cgimall] 모바일 스크롤 컴포넌트 jindo.m.Scroll [1.4.0] 본문

웹프로그램밍 자료실/HTML 자료

[해피CGI][cgimall] 모바일 스크롤 컴포넌트 jindo.m.Scroll [1.4.0]

해피CGI윤실장 2017. 4. 25. 09:47



JMC 스크롤 컴포넌트의 이해: jindo.m.Scroll

스크롤 컴포넌트(jindo.m.Scroll)는 JMC(Jindo Mobile Component)의 컴포넌트 가운데
가장 많이 사용하는 컴포넌트입니다.
이 글에서는 스크롤 컴포넌트의 특징과 사용 방법을 소개할 것입니다.

스크롤 컴포넌트가 필요한 이유

모바일 UI의 대중화

스마트폰의 대중화로 사용자는 기존 PC에서 보던 UI화면보다 위와 아래 고정영역이 있는
일반적인 모바일 UI를 더욱 친숙하게 여기고 있다.

이런 UI를 구성하려면 많은 콘텐츠를 빠르게 스크롤할 수 있는 기능이 필수적이다. 물론,
이런 기능을 데스크톱 브라우저에서 구현하는 방법은 매우 간단하다.
바로 "position:fixed" 속성을 이용하면 위쪽 영역과 아래쪽 영역을 화면에 고정할 수 있다.

하지만 모바일에서는 이 일이 결코 쉬운 일이 아니다.

그림 1 일반적인 모바일 UI

position:fixed 속성 미지원

데스크톱 환경에서는 거의 모든 브라우저가 "position:fixed" 속성을 지원하지만,
모바일 환경에서는 최근에 와서야 "position:fixed" 속성을 지원한다.
iOS 5.0 버전의 Safari와 Android 2.1 버전의 브라우저부터 "position:fixed" 속성을
지원하지만, 정상적으로 동작하려면 iOS 5.0 버전 이상의 Safari와 Android 3.0 버전
이상의 브라우저여야 한다.

그림 2 position:fixed 속성 지원 여부(원본 출처: http://caniuse.com)

그뿐만 아니라 "position:fixed" 속성을 이용해 일반적인 모바일 UI를 만들면,
위쪽과 아래쪽의 고정된 영역에도 스크롤이 표시되어 디자인 제약이 발생한다.

그림 3 Position:fixed를 사용할 경우, 디자인 제약이 발생한다.

브라우저에서 기본으로 제공하는 "position:fixed" 속성만으로는 다양한 모바일 환경에서 동일 UI와 동일 기능을 보장하기 어렵다.

Android에서는 iOS에서보다 스크롤이 유독 느리다.

모바일에서 스크롤을 구현할 때 가장 문제가 되는 부분은 성능이다. 특히, Android에서 빠르고 매끄러운 스크롤을 구현하는 것은 매우 어려운 일이다. 그 이유는 다음과 같다.

GC로 인한 UI 블록 발생

가상 머신(Virtual Machine) 기반의 Android는 주기적으로 메모리를 정리하는 GC(garbage collection)가 발생한다. 이때 순간적으로 블록(block) 현상이 발생하며 이는 UI 성능 지연을 유발한다.

스레드 우선순위

Android에서의 스크롤이 iOS에서보다 느린 근본적인 이유는 낮은 우선순위 때문이다. iOS는 사용자의 입력(touch)이 발생했을 때 'UI 스레드'가 '실시간(RealTime)' 우선순위로 처리한다. 반면, Android는 사용자의 입력(touch)을 '메인 스레드'가 '보통(normal)' 우선순위로 처리한다. 따라서, 아무리 하드웨어가 좋더라도 사용자 입력 인지가 느리기 때문에 UI 반응성이 느리다.

Android에서도 빠르고 매끄러운 스크롤을 구현하려면 다양한 접근법을 가지고 대응해야 한다. 그렇지 않으면 성능 문제에 봉착하게 된다.

다양한 스크롤 컴포넌트

위에서 언급한 이유로 인해 이미 시중에는 많은 스크롤 컴포넌트가 나와 있다. 대표적인 스크롤 컴포넌트로는 iScroll4(http://cubiq.org/iscroll-4) , Sencha Touch(http://www.sencha.com/products/touch) 의 DataView, List 등이 있으며, jQuery 기반의 각종 플러그인도 있다.

하지만 이들 컴포넌트는 다양한 모바일 단말기에 범용적으로 사용하기에는 다소 안전성과 성능이 떨어진다. 특히, 국내에서 생산되는 모바일 단말기에서는 더욱 그 정도가 심하다. 이와 관련해서는 표 2를 참조한다.

JMC 스크롤 컴포넌트(jindo.m.Scroll)

스크롤 컴포넌트 구조

JMC 스크롤 컴포넌트는 빠르고 안정적이며 매끄러운 스크롤을 목표로 구현되었다. JMC 스크롤 컴포넌트의 구조는 비교적 간단하다. 사용자가 보는 View 영역과 내용이 존재하는 Content 영역으로 로 구성되어 있으며, 사용자가 View 영역을 터치하여 콘텐츠를 스크롤하는 방식이다.

그림 4 JMC 스크롤 컴포넌트의 구조

스크롤 애니메이션

최적의 구현 방식

모바일 웹에서 애니메이션을 구현하는 기술에는 JavaScript, CSS3, SVG, Canvas 등 다양한 기술이 존재하지만, JMC 스크롤 컴포넌트는 최적의 성능을 위해, 하드웨어 가속이 가능한 CSS3와 상대적으로 리소스 사용량이 적은 JavaScript 기술을 병행해 사용한다.

다음 표는 CSS3 속성인 'transform:translate' 과 'transform:translate3d' 을 사용하고, TimingFunction과 JavaScript의 setTimeout 함수를 병행하여 애니메이션을 구현했을 때의 특징을 정리한 표이다.

표 1. CSS3와 JavaScript 구현 기술 비교

이동 방식 CSS3 Transform:Translate CSS3 Trnasform:Translate3d
애니메이션 방식 setTimeout을 통한 스크립트 방식 CSS3 TimingFunction을 통한 방식 setTimeout을 통한 스크립트 방식 CSS3 TimingFunction을 통한 방식
애니메이션 품질
하드웨어 가속 미사용 미사용 사용 사용
구현 난이도 어려움 쉬움 어려움 쉬움
리소스 사용량 적음 많음 적음 많음
마크업 영향도 거의 없음 민감함 거의 없음 민감함

하드웨어가 고사양이거나 콘텐츠의 양이 적을 때는 'CSS3 Translate(3d) + CSS3 TimingFunction' 방식을 이용하는 것이 좋고, 하드웨어가 저사양이거나 콘텐츠의 양이 많을 때는 'CSS3 Translate(3d) + setTimeout을 통한 스크립트 방식'을 이용하는 것이 좋다.

반면, 애니메이션 품질 측면에서는 'setTimeout을 통한 스크립트 방식'보다는 'CSS3 TimingFunction 방식'을 선택하는 것이 더 좋다.

모바일 단말기별 차별화

성능과 품질 측면에서는 위 표를 통해 어느 정도 대안을 찾을 수 있지만, 실제 모바일 단말기에서는 단말기별 버그와 하드웨어 가속 지원 여부에 따라 선택할 수 있는 방법이 많이 달라진다. 아래 그림은 하드웨어 가속을 사용하는 CSS3 3D Transform의 지원 여부를 브라우저별로 정리한 표이다.

그림 5 CSS3 3D 지원 여부(원본 출처: http://caniuse.com/#feat=transforms2d)

iOS는 초기부터 하드웨어 가속을 지원했지만, Android는 3.0 버전부터 하드웨어 가속을 지원하기 시작해 Android 4.0 버전이 되어서야 안정적으로 지원한다.

지원하지 않는 모바일 단말기에서 CSS3 3D를 사용하면 렌더링 시 화면이 깜빡이거나 레이아웃이 깨지는 문제가 발생한다. 이럴 때는 오히려 'setTimeout을 통한 스크립트 방식'을 적용하는 것이 더욱 효과적이다.

JMC 스크롤 컴포넌트는 위에서 언급한 점들을 고려하여 구현되었다.

다양한 구현방식을 모바일 단말기 특성에 맞게 적용했기 때문에 대상 단말기에서 최적의 성능과 안전성을 보인다.

다른 컴포넌트와 비교(iScroll4 vs. jindo.m.Scroll)

다음은 전 세계적으로 널리 사용되고 있는 스크롤 컴포넌트인 iScroll4와 JMC 스크롤 컴포넌트를 비교한 내용이다.

표 2. iScroll4와 jindo.m.Scroll 비교

구분 iScroll4 Jindo.m.Scroll
구현방식 CSS3 Translate(3d) + CSS3 TimingFunction, CSS3 Translate(3d) + setTimeout을 통한 스크립트 방식 CSS3 Translate(3d) + CSS3 TimingFunction , CSS3 Translate(3d) + setTimeout을 통한 스크립트 방식
기본 스크롤 방식 CSS3 Translate(3d) + setTimeout을 통한 스크립트 방식 모바일 단말기별로 선별적 적용
안정성 몇몇 Android 단말기에서 스크롤 도중 화면이 하얗게 되거나 깜빡거린다. 국내 모바일 단말기에서 안정적으로 스크롤된다. 또한, 별도 옵션을 통해 단말기 별로 제어가 가능하다
적용범위 모바일, 데스크톱 모바일
기능 콘텍스트(context) 메뉴 및 하이라이트 지원 안 함 Pull Down/Pull Up을 이용한 콘텐츠 업데이트 지원 Snap, Zoom-in 지원 콘텍스트(context) 메뉴 및 하이라이트 지원 Pull Down/Pull Up을 이용한 콘텐츠 업데이트 지원
성능   성능상 차이는 iScroll4와 차이가 없으나 단말기별로 가속도를 다르게 설정해 체감속도를 향상시켰다.

두 가지 구현 방식에서 큰 차이점은 없지만, JMC 스크롤 컴포넌트는 iScroll4에 비해 모바일에 더 최적화되어 있다. 뿐만 아니라, 각각의 단말기 특성에 따라 선별적으로 최적화되어 있기 때문에 제조사가 다양한 Android 계열에서는 iScroll4보다 우수한 성능과 안전성을 보인다.

다음 영상은 갤럭시S2(2.3.6) 단말기에서 iScroll4와 JMC 스크롤 컴포넌트의 성능을 비교한 동영상이다. JMC 스크롤 컴포넌트는 Android에서도 빠르고 부드러운 애니메이션 효과를 지원하고 있다.

JMC 스크롤 컴포넌트 사용하기

세로로 스크롤할 수 있는 간단한 스크롤 페이지를 작성해서 JMC 스크롤 컴포넌트를 이용하는 방법을 설명하겠다.

JMC 다운로드

JMC의 선택 다운로드 페이지에서 Scroll 컴포넌트를 다운로드한다. 컴포넌트를 다운로드할 때에는 의존성 자동 체크를 선택해 의존성이 있는 관련 모듈을 함께 다운로드하도록 설정한다.

그림 6 JMC 선택다운로드

Jindo 프레임워크와 JMC 컴포넌트 파일 추가

JMC는 Jindo 프레임워크 기반으로 개발됐기 때문에 기본적으로 Jindo 프레임워크를 추가해야 한다. 참고로, JMC 선택 다운로드에서는 Jindo 프레임워크까지 다운로드되지는 않는다.

JS 파일 추가

<!-- Jindo 프레임워크 추가 -->  
<script src="http://helloworld.naver.com/js/jindo.all.ns.js"
 charset="utf-8">
</script>

<!-- JMC 선택 다운로드 페이지에서 다운로드한 JMC 추가 -->  
<script src="http://helloworld.naver.com/js/jindo_mobile_component.js"
 charset="utf-8"></script>

HTML 작성

실제 화면에서 보이는 View 영역(<div id="scrollView">)과 스크롤될 내용인 Contents 영역(<ul>)을 구성한다. JMC 스크롤 컴포넌트의 구조는 비교적 간단해서 마크업 또한 간단하다. 기본적인 마크업 형태는 다음과 같다.

스크롤 영역 HTML

<!-- Scroll View -->  
<div id="scrollView">

    <!-- Scroll Contents -->
    <ul>
        <li>… 생략 …</li>
        <li>… 생략 …</li>
        <li>… 생략 …</li>
    </ul>
</div>  

JavaScript 작성

jindo.m.Scroll의 첫 번째 인자로 스크롤을 적용할 영역의 ID와 두 번째 인자로 옵션값을 전달하는 인스턴스를 생성한다. 옵션에 대한 자세한 내용은 레퍼런스 페이지를 참조하기 바란다.

Scroll 컴포넌트 초기화 코드

// 높이가 210px인 JMC 스크롤 컴포넌트를 생성한다.
var oScroll = new jindo.m.Scroll("scrollView", {  
    nHeight : 210
});

전체 코드

구현된 전체 코드는 다음과 같다.

head 코드

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
<title>jindo.m.Scroll</title>  
<!-- Jindo 프레임d워크 추가 -->  
<script src="http://helloworld.naver.com/js/jindo.all.ns.js"
 charset="utf-8"></script>  
<!-- JMC 선택 다운로드에서 다운로드 받은 JMC 추가 -->  
<script src="http://helloworld.naver.com/js/jindo_mobile_component.js"
 charset="utf-8"></script>

body 코드

<!-- Scroll View -->  
<div id="scrollView">  
    <!-- Scroll Contents  -->
    <div>
        <ul>
            <li>
                <p class="scl_tmb">
                    <a href="http://m.news.naver.com/">
                  <img src="http://helloworld.naver.com/../im/ico_news.jpg"
                     alt="네이버 뉴스" width="57" height="57" style="">
                    </a>
                </p>
                <p class="scl_cnt">
                    Scroll List 1<br>
                    <a href="http://m.news.naver.com/" class="scl_link"
                     style="">네이버 뉴스 바로가기</a>
                </p>
            </li>
            <li>...</li>
            <li>...</li>
            <li>...</li>
            ...
        </ul>
    </div>
</div>  
<script type="text/javascript">  
// 높이가 210px인 JMC 스크롤 컴포넌트를 생성한다.
var oScroll = new jindo.m.Scroll("scrollView", {  
    nHeight : 210
});
</script>  

JMC 스크롤 컴포넌트를 사용하면 단 몇 줄 만으로 모바일 단말기에
최적화된 고정 영역의 세로 스크롤 기능을 구현할 수 있다.

마치며

iScroll4, Sencha Touch, jQuery 등 많은 모바일 스크롤 컴포넌트가 시중에 나와 있지만, 각각의 모바일 단말기에 최적화된 성능과 안전성을 보장하는 스크롤 컴포넌트는 찾기 힘들다. 특히 Android 단말기의 점유율이 높은 국내에서 외국산 스크롤 컴포넌트를 사용해 서비스를 운영하기에는 많은 어려움이 있다.

JMC 스크롤 컴포넌트는 시중에 나와 있는 스크롤 컴포넌트 중 가장 서비스에 적합한 컴포넌트라고 단언할 수 있다. 하지만, 이러한 컴포넌트도 실서비스에 아무런 주의 없이 적용하면 기능과 성능에 제약이 생길 수 있다. 특히, 브라우저가 수용할 수 없을 정도의 대용량 콘텐츠를 스크롤할 때는 성능 문제에 직면하게 된다. JMC 스크롤 컴포넌트는 이러한 문제를 해결할수 있는 방법을 지금도 고민하고 있다.

그 대표적인 예가 무한스크롤이다. Pull Down/Pull Up 기능을 이용해 기존 콘텐츠를 제거하고 신규 콘텐츠를 증가하는 식으로 콘텐츠를 일정한 범위로 유지하며 최상의 속도가 나올수 있도록 하는 방식이다. 하지만, 아직은 넘어야 할 산이 많다.

모바일 환경은 급속도로 발전하고 있다. 앱에서 가능하던 기능들이 점차 모바일 웹에서도 가능하게 되고 있다. 스크롤 컴포넌트도 결국 모든 브라우저에서 처리할 수 있는 때가 올 지도 모른다. 하지만, 무턱대고 기다리는 방법은 현실적이지 못하다. 모바일 환경의 발전과 함께 앞으로 변화하는 JMC 스크롤 컴포넌트를 관심있게 지켜봐 주길 바란다.

 

홈페이지바로가기 

Comments