모바일 무한 스크롤

NHN Technology Services!
프론트엔드 개발팀 최승학!
JSLounge
http://www.facebook.com/groups/jslounge/!
요구사항
글 목록의 마지막 위치로 오면, 자동으로 다
음 글 목록을 불러옴
요구사항은 간단하고 명확하지만!
일정은 언제나 “검토 후 알려 주겠습니다.” 가 정석
글 목록은 2가지 Type
List & Stream
List Type
이미지 Height 값 고정
Stream Type
반응형 이미지
개발 전 배경 지식
Viewport Size
물리적 해상도 640 x 1136!
Viewport Size 320 x 568
window.devicePixelRatio = 2

(물리적 해상도 / Viewport Size)
반응형 이미지의 Height 값
이미지가 완전히 Load 되기 전에는 알 수 없다.
Original Image W 100 x H 50
<DIV> Width 200px
Width 100%
Height 100px
Viewport Size 는 어떻게 ?
document.documentElement.clientWidth
document.documentElement.clientHeight
알림 영역이나 주소영역등 계산 할 수 없는 영역 때문에

Height 는 정확히 알 수 없습니다.
계산 불가능한 영역

clientHeight()!
Height 계산 방식
Device Rotation 하면 그때 계산!
!
임시로 clientWidth, clientHeight 값 저장!
Device Rotate 발생하면 오차 값을 조정
!
대략적인 필요가 없다면 임의의 값을 더한다.!
Web == Native App

Client

Server
REFLOW
Render Tree 재 계산
HTML
Code

DOM
Tree
Render T
ree

CSS
Code

Styles

Paint
Element 추가,
삭제시 Reflow 지연 이슈
DOM 에 append 후 즉시 제어 불가
DOM 에 append 후 화면에서 위치 값 확인 불가!
!
Android 에서 주로 발생!
setTimeout(), setInterval() 로 일정 시간 지연
BENCHMARKING
분석하세요.!
더 나은 결과 물과 실력 향상을 보장 합니다.
FANCY.COM
MOBILE
Backbone.js 사용!
Load 된 Contents 를 계속 Append
WWW.PINTEREST.COM
PC
제한된 수의 Element 만 유지하면서 처리!
Position Absolute!
Wrapper 의 Height 실시간 수정 (Scroll 되야 하므로)
MOBILE
특별한 것은 발견하지 못했음

단순 Append!
APP
Ajax 호출로 JSON DATA 를 받아서 출력!
!
Card 형태의 Frame 은 고정된 값으로 화면에 출력 되므로 이미지 반
응 형이 아님!
!
Image 가 표시될 사이즈는 API 에 정해져 있다.!
Image 는 Viewport 영역에 들어 오면 Request!
!
Scroll 표시가 없음!
NAVER SOFTWARE
PC
Ajax History 유지!
고정된 Contents Width, Height!
History 유지 방법 ?
Cookie 를 이용합니다.
Cookie
Browser
Index 0

Index = 200

Index 199
Index 200
Index 201

Server
Naver Mobile Now
인상적인 반응형 처리 방식
Viewport 기준으로!
영역을 벗어 나는 Item 의 Height 는 고정,!
자식 요소는 모두 Display none!
!
다시 영역으로 들어오면!
Height 값을 제거 해서 Auto 로 한다.
근본적인 문제
iPhone 은 현재 창 Android 는 새 창으로 Device 분기
Cache 실패 할 경우 History 유지 불가
성능 최적화 패턴 정리
1. 제한된 ELEMENT 만 관리
위치를 유지 해야 하므로 position absolute 필수
Browser Top
Offset 1,000px

소수의
Element 만 관리

Height 관리
2. Display None + Height Fixed
height : 100px
display : none

height : auto
display : block
BOUNDARY CHECK
현재 Viewport 영역을 기준으로 Element 의 위치 값을!
얻을 수 있는데 여러가지로 유용하다.
0, 0
Top
Left
Right
Bottom

Element.getBoundingClientRect
Index 170

영역검사 대상

Index 200
SCROLL END
onscroll() 이벤트 발생 시점을 통일화 시킨다.
Ajax History 유지
일반 적인 상황 ?
Android 와 iOS 를 분기하여 처리 하거나!
별 다른 조치를 하지 않는다.
CACHE
Persistent Cache & Memory Cache
Persistent Cache
PC Cache!
HTML5 Localstorage 도 해당
Persistent Cache가 꽉 차면?
LRU (Least Recently Used)!
LRU-SP (A Size-Adjusted and Popularity-Aware)!
Memory Cache
Page Cache!
HTTP Request 가 없다.!
PC Browser 에는 없다.!
용량이 크다.!
예측 할 수 없다.!
!
BrowserCacheDetector
Cache 됐을 때와 Cache 실패 했을 때를 구분하는 M
odule 개발
Click 된 Item 의 Index 저장 위치
Localstorage!
Location Hash!
Cookie 방식
!
구현 방식
clickLink()!
var bIsCachePage = true;!
Click 된 Item 의 index 를 LocalStorage 에 저장
!
End Page로 이동
뒤로 가기!
!
pageshow();!
bIsCachePage === true ?!
LocalStorage 의 index 가 포함되는 page부터 Reque
st!
!
몇 가지 테스트 결과
iOS 에서 Cache 된 Page 일 경우 onscr
oll 과 같은 window 이벤트가 동작 하지
않는다.
일부 버전에서만 발생하고 상황도 다르다

window.onscroll 가 null 인 상태

다시 등록도 안됨!
!
Touch gesture 를 분석해서 구현한 Touch Scroll 이용!
iOS 주소창 Touch 대응 불가!
Cache 상태일 때 iOS 7에서 동작 안함!
!
해당 이벤트 핸들러를 setInterval() 로 주기적으로 실행!
Element Select 속도 테스트
1,000 개 이상 일 때 selector 속도 테스트!
!
Library Selector 가 상대적으로 많이 느리다.!
!
Native 는 Select 대상 갯수에 비해 상당히 빠름

getElementsByTagName(), querySelectorAll()!
다수의 Element 속성을 변경할
때 실행시간
263ms
1,000 개 정도의 Element Append & Set Style
체감 시간 차이 없음
체감 30초 이상
10,000 개 정도의 Element Append & Set Style
저장 2초
다시 출력 5초
1,000 개 Contents 를 Localstrorage 에 저장했다가
다시 Display
끝으로…
성능 최적화가 모든 상황에서 필요한 것은 아닙니다.
생각하는 것보다 Device 의 성능은 좋습니다.

10배의 노력으로 개발한 최적화가 사용자에게 미비하다면 ?
System 성능
100%

일반 개발
최적화 개발
감사합니다.

모바일 무한 스크롤 개발