모바일 무한 스크롤 개발
DESCRIPTION
TRANSCRIPT
모바일 무한 스크롤 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 되기 전에는 알 수 없다.
<DIV> Width 200px
Original Image W 100 x H 50
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 Tree Paint
CSS Code Styles
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 를 이용합니다.
Browser Cookie
Server
Index = 200 Index 0
Index 201 Index 200
Index 199
Naver Mobile Now
인상적인 반응형 처리 방식 Viewport 기준으로!영역을 벗어 나는 Item 의 Height 는 고정,!자식 요소는 모두 Display none!!다시 영역으로 들어오면!Height 값을 제거 해서 Auto 로 한다.
근본적인 문제 iPhone 은 현재 창 Android 는 새 창으로 Device 분기 Cache 실패 할 경우 History 유지 불가
성능 최적화 패턴 정리
1. 제한된 ELEMENT 만 관리 위치를 유지 해야 하므로 position absolute 필수
소수의 Element 만 관리
Browser Top Offset 1,000px
Height 관리
2. Display None + Height Fixed
height : 100px display : none
height : auto display : block
BOUNDARY CHECK 현재 Viewport 영역을 기준으로 Element 의 위치 값을!얻을 수 있는데 여러가지로 유용하다.
0, 0
Left
Right
Top
Bottom
Element.getBoundingClientRect
영역검사 대상
Index 200
Index 170
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
HTTP Request 가 없다.!PC Browser 에는 없다.!용량이 크다.!예측 할 수 없다.!!
Page Cache!
BrowserCacheDetector Cache 됐을 때와 Cache 실패 했을 때를 구분하는 Module 개발
Click 된 Item 의 Index 저장 위치 Localstorage!Location Hash!Cookie 방식 !
구현 방식 clickLink()!var bIsCachePage = true;!Click 된 Item 의 index 를 LocalStorage 에 저장 !End Page로 이동 뒤로 가기!!pageshow();!bIsCachePage === true ?!LocalStorage 의 index 가 포함되는 page부터 Request!!
몇 가지 테스트 결과
iOS 에서 Cache 된 Page 일 경우 onscroll 과 같은 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배의 노력으로 개발한 최적화가 사용자에게 미비하다면 ?
100% System 성능
일반 개발
최적화 개발
감사합니다.