12. 주요 구성요소
컴포넌트
eg 유틸리티 모음
MovableCoord 사용자의 동작을 가상 좌표계의 논리적 좌표로 변경
Flicking 플리킹 UI를 구현
in niteGrid 콘텐츠가 있는 카드 엘리먼트를 그리드 레이아웃에 무한으로 배치
Visible 엘리먼트가 기준 엘리먼트나 뷰포트 안에 보이는지 확인
jQuery
확장 플러그인
persist 웹 페이지의 현재 상태를 JSON 형식으로 저장하는 캐시 인터페이스
pre xCss CSS 벤더 프리픽스를 지원하지 않는 일부 jQuery 버전을 사용할 때 제조사 접두어를 지원
animate jQuery.animate() 메서드를 확장해 transform과 3D 가속을 지원
pause / resume jQuery.animate()로 실행한 애니메이션을 일시 정지 및 재실행
이벤트
rotate 모바일 기기의 회전을 감지하는 이벤트
scrollend 스크롤의 마지막 시점을 감지하는 이벤트
13. Is yet another
library?
이미 오랜시간 개발되어온 네이버의 공통 라이브러리 를 보유
빠른 이슈 대응과 내부 니즈(UI/UX/기능) 충족을 목표
(2004)
(2010)
(2011)
Jindo
Jindo Component
Jindo Mobile Component
▪ [2011 deview]
▪ [2014 deview]
모바일 웹UI 개발, 아직도 맨땅에 삽질부터 하십니까?
자바스크립트 라이브러리 개발/운영 경험기
14. 그러나...
외부 레퍼런스 부족, 교육비용 필요, 외부 호환성 부족
빠른 변화에 민첩한 대응의 어려움
개발자들의 long term 커리어 및 발전 기여 부족
아쉽지만, fade-out 결정
16. 기본 원칙
1) 기존 오픈소스 활용
기본적으로 좋은 오픈소스가 있다면, 사용한다.
필요한 경우 커스터마이징 한다.
2) 직접 개발하는 경우
이미 있지만, 기능/성능이 아쉬운 경우 그리고 전략적 기술확보가 필요한 경우
필요한 기능을 가진 라이브러리가 없는 경우
17. 도전적인 문제들
충분한 브라우저 커버리지
old IE 버전부터 최신 기술을 지원하는 브라우저까지
다양한 모바일 환경과 OS 지원
어떤 환경과 조건에서도 최대한의 성능발휘
안정성 확보
글로벌 사용자/컨트리뷰터 확보를 통한 경쟁력
네이버 서비스만이 아닌 웹 생태계 도움을 주는 라이브러리
19. 사례#1: 불편한 사용자 경험
긴 동적 목록형 컨텐츠를 스크롤해서 보다가,
해당 컨텐츠를 보고 다시 돌아왔더니
목록 처음으로 이동 되어버려서
보고있던 곳까지 다시 스크롤 해서
이동하다보면... !@#!@@#!
20. (Back-Forward)?BFCache
이전 페이지로 복귀 시, 벗어나기전 상태 값을 브라우저가 다시 복원하는 캐시
벗어나기 전 상태는 많은 것을 포함:
페이지의 스크롤 위치
동적으로 구성된 컨텐츠의 구성형태
자바스크립트의 특정 상태 값, 등등
지원환경:
iOS Safari 4.x+는 지원
Android 4.4+ stock &
Chrome(스크롤 위치만 지원) 미지원
21. $.persist()
현재 페이지를 벗어나기 직전 상태에 대한 '데이터 저장/복원' 캐시 인터페이스
캐시 저장소는 → 순으로 사용Web Storage history.replaceState()
첫번째 시도
BFCache의 복원 처리와 유사하도록 이벤트로 처리
// 이벤트 바인딩을 통해 캐시 데이터를 얻어온다.
$(window).on("persist", function(event, state) { ... });
22. 그러나...
데이터 복원 시점이 서비스 마다 다름
복원 이벤트 발생 시점과 복원 데이터 사용 시점의 불일치
API 형태로 변경 바꾸자
// 원하는 시점에 API 호출을 통해 캐시 데이터를 핸들링 한다.
$.persist("CACHEKEY"); // getter
$.persist("CACHEKEY", data); // setter
그 외에도...
브라우저 마다 다른 저장
Private mode 에서 Web Storage 사용 이슈 ( )
quota limit
Safari
23. 사례#2: 기능성 부족
애니메이션을 쉽게 구현할 수 있는 .
하지만, 크로스 브라우징 이슈로 'transform' 속성 지원되지 않음
jQuery.animate()
$el.animate({ transform: "translate3d(0,200,0)" }, 1000);
비슷한 문제 해결을 위해 이미
/ 플러그인 존재jquery.transit jquery.transform
그러나,
.animate() 인터페이스 및 기능 미약
transform3d 미지원
24. 개발시 고민들
1) 오픈소스 fork/contributing 형태로 접근
jquery.transit은 .transit()를 사용. .animate()과는 다른 인터페이스
jquery.transfrom은 (동치 좌표계) matrix를 transform 으로 바꾸는 방
식은 적용하는데 차후 transform3d 를 고려했을때 쉽지 않은 선택
▪ [참고] Understanding the CSS Transforms Matrix
2) 인터페이스와 상대 값의 처리는?
기존 transform 사용 방법과 동일하게 처리 필요
상대 값 처리를 위한 '+=, -='등의 표현식을 사용할 수 있어야 한다.
25. 3) 생각했던 것 보다 transform 고려 요소가 많다.
적용 순서에 따라 계산되어야 한다.
체이닝 시 상대 값에 따른 계산
체이닝으로 절대 값 지정 시 이전 값의 초기화
.animate({transform: "scale(2) rotate(45deg) translateX(100px)"}) //(1)
.animate({transform: "rotate(45deg) translateX(100px) scale(2)"}) //(2)
.animate({transform: "translateX(100px) scale(2) rotate(45deg)"}) //(3)
$elem
.animate({transform: "scale(2) rotate(45deg) translateX(100px)"}) //(1)
.animate({transform: "+=translateX(100px) +=rotate(45deg)"}); //(2)
$elem
.animate({transform: "scale(2) rotate(45deg) translateX(100px)"}) //(1)
.animate({transform: "translateX(100px)"}); //(2)
26. transform 순서 유지를 위한 노력
단순 matrix 연산을 통해서는 완벽한 중간값 처리가 어렵고,
근본적으로는 아주 복잡한 matrix 연산을 적용해야 한다.
Matrix 연산은 최소화하고 브라우저의 transform 연산을 활용하는 방식을
적용하여 자연스러운 애니메이션을 이끌어 냈으나, 일부 상황(오히려 움직임이
매우 적은)에서는 애니메이션 중 약간 부자연스러움
이런 이유들로 인해 유명한 라이브러리들(ex. )도 transform 순서
는 고려해 주지 못한다.
→ 순서에 따른 계산 부분은 결국 사용자의 몫
Velocity.js
▪ [참고] jQuery 애니메이션은 어떻게 작동하는가? - / /기본 심화 응용
28. eg.Flicking
패널을 쓸어 넘김 형태로 이동하는 플리킹 UI를 구현
Why?
흔하게 많은 곳에서 사용되어지는 UI/UX
빠른 이슈 대응을 필요
높은 브라우저 커버리지
지속적인 성능 요소들의 개선을 빠르게 적용
터치 제스처는 를 활용Hammer.js
29. 렌더링 성능 향상
패널의 이동 성능을 높이기 위해 하드웨어 가속을 적용
일반적으론 layer hack인 CSS 3d 속성
(ex. translateZ(0))을 통해 적용
보다 효율적인 ' '를 적용:
미래에 변경이 발생할 속성에 대해 브라우저에 힌
트를 주면 사전에 최적화를 통한 렌더링 성능향상
효율적인 리소스의 관리
(ex. GPU 메모리의 사용을 적절히 관리해 과도한
composite layer 생성을 제한)https://www.youtube.com/watch?v=jTRe1tvFYdE
will-change
▪ [Hello world] 하드웨어 가속에 대한 이해와 적용
30. 시행착오
will-change
처음엔 패널을 이동하기 직전 설정하고 이동 후 제거
많은 곳 에서 브라우저가 holding 하고 있을수 있는 리소스를 release 하기
위해 사용후 속성을 제거하라고 권고 ( )
속성의 설정과 제거가 반복해서 단시간에 이루어지는 형태는 부적합
→ 프레임별 rasterization 비용이 크게 증가
Always Remove will-change
31. 시행착오 (cont'd)
Stacking order로 인해 페이지 내 의도하지 않은 하드웨어 가속
(composite layer 생성) 적용
방지를 위해 플리킹 요소는 적절하다고 판단되는 'z-index:2000' 로 설정
▪ [참고] Understanding CSS z-index
36. 성능향상
DOM Recycling
일정한 노드만을 유지해 성능향상
뷰포트 밖의 요소는 제거
물리적 DOM과 논리적 데이터로 분리
이미지 포함 카드의 경우,
올바른 크기를 구하기 위해
이미지의 complete 속성을
비동기로 확인
37. 시행착오
스크롤 시 DOM의 내용의 변경 비용을 줄이기 위해
각각의 카드 요소들을 하드웨어 가속을 통해 별도 레이어로 처리
그러나,
카드 UI 특성상 컨텐츠가 매번 변경되어야 하므로, composite layer의 컨텐
츠를 매번 업데이트 하는 비용이 성능저하 요인이 됨
하드웨어 가속은 무조건 좋은 것이 아니다. 상황에 맞게 적용을 고려해야 한다.
▪ [2014 deview]
▪ [Hello world]
네이버 모바일 홈을 움직이는 반응형 무한스크롤의 비밀
네이버 쇼핑의 새로운 카드형 UI 라이브러리, eg.In niteGrid
40. 환경 구분
1) 하드웨어 가속 환경에 대한 white list
수년간 직접적인 테스트를 통한 단말기 구분
// 하드웨어 가속 사용이 적절한 단말기 여부를 반환
eg.isHWAccelerable();
https://naver.github.io/egjs/latest/doc/eg.html#isHWAccelerable
2) Transition 속성 사용환경 구분
// CSS transition 사용이 적절한 환경 여부를 반환
eg.isTransitional();
https://naver.github.io/egjs/latest/doc/eg.html#isTransitional
41. 안정성 확보 방안들
기본 고려 사항들
브라우저 호환성
다양한 환경(모바일,테블릿, 데스크탑) 호환성
성능
목표
일관된 코드 품질 유지
지속적이며 끊김없는 테스트 수행을 목표
모든 코드에는 unit test가 존재해야 한다.
42. 레거시 브라우저
믿기지 않겠지만, 아직도 예전 브라우저를
사용하는 수(줄어들고 있긴 하지만)는 적지않다.
네이버 메인 접속 브라우저 점유율 (2016/09 기준)
IE 7,8: 약 8% 내외
Android 2.3.x ~ 4.3.x: 약 6.5% 내외
국내 전체 점유율은? (IE8 약 1%) (참고: )StatCounter 2015/09 ~ 2016/09
필요한 시점까지는 지원필요
43. 코드 스타일 유지하기
(부제: 너는 나 나는 너)
코드 스타일 검사 ( - 향후, ESLint로 전환 예정)
코드 정적 검사 ( )
개발자간 에디터와 IDE 등에서의 코드 스타일 유지 ( )
JSCS
https://github.com/naver/egjs/blob/master/.jscsrc
JSHint
https://github.com/naver/egjs/blob/master/.jshintrc
EditorCon g
https://github.com/naver/egjs/blob/master/.editorcon g
44. 자동화된 테스트
Total test cases: 3,591 (93% coverage)
Commit/Push 마다
commit hook( )을 통한 linting
CI( )를 통한 push 단위별 검증
husky
TravisCI
https://github.com/naver/egjs/tree/master/test/unit
45. 실 환경 수동 QA
163개의 수동 테스트 케이스를 통한 검증
실적용 후에는 네이버의 수많은 사용자들을 통해 검증된다.
https://github.com/naver/egjs/tree/master/test/manual
46. Road Map
ES6/7 전환
다양한 프레임워크(Angular, React)에서 모듈 형태 지원
jQuery 의존성 제거
PlainJS(VanillaJS) 로의 전환, 의존성을 줄여 사용환경 개선
( [참고] )
모듈에 따라 개별 라이브러리로 분리
light 하게 그리고 기능 중심적 발전과 사용성 증대
Is jQuery Still Relevant?
47. 맺으며
아직은 갈길이 멀다.
여러분들의 적극적인 참여를 통해 같이 발전하는 라이브러리를 목표
github repo를 통해 모든 activity가 공개
PR은 언제나 환영
전세계에 있는 모든 개발자들, 웹 개발에 기여하고자 한다.
아직 국내 FE 오픈소스들 중 두드러지는 성공 케이스가 없다.
유명 오픈소스들의 best practice를 도입, 참고하고 있다.