Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
AMP는
어떻게 빠른 성능을 내나?
NAVER 김태훈
kishu@navercorp.com
about me
김태훈 kishu@navercorp.com
NAVER FE플랫폼
SADI HTML5 초빙교수

NHN NEXT WebUI Basic 겸임교수
Project Management Professional(PM...
AMP란 무엇인가?
벤치마킹
어떻게 빠른 성능을 내는가?
AMP 인사이드
AMP 현황
AGENDA
AMP?
ACCELLERATED MOBILE PAGES by Google
웹페이지(특히 정적 페이지)를 더 빠르게 렌더링 하기 위한 방법

퍼포먼스 향상을 위한 구글의 경험과 베스트 프랙티스의 구현체
AMPs are just Web Pages!
AMP HTML
확장 가능한 HTML : AMP 확장 태그 및 속성 사용
AMP 확장 태그를 통해 <amp-carousel> 같은 컴포넌트 사용 가능
AMP 확장 태그는 웹 컴포넌트 - 커스텀 엘리먼트 기반
퍼포먼스를 ...
AMP VALIDATION
amp.js
AMP 페이지와 리소스 라이프사이클 및 렌더링 타임 제어
AMP 커스텀 엘리먼트 구현 코드
웹페이지의 퍼포먼스 향상을 위한
베스트 프랙티스의 구현체
AMP는 외부 JS를 허용하지 않아요.!
사용자 자바스크립...
AMP STYLE = CSS
외부 스타일, 엘리먼트 인라인 스타일 허용 안함
문서에 삽입하는 형태의 인라인 스타일만 사용 가능
최대 50KB만 허용
참고
네이버 모바일 메인페이지 스타일 - 총 2개 파일 약 100KB
...
AMP 컴포넌트를 이용해 HTML을 만들고
AMP JS만 로딩하면
웹페이지의 빠른 렌더링을 보장
+ 구글 검색 결과에서 즉시 로딩(빠르고 멋있게)
+ 구글 CDN에 캐시
HELLO AMP!!!
<!doctype html>
<html amp lang="en">
<head>
<meta charset="utf-8">
<title>Hello, AMPs</title>
<link rel="cano...
AMP COMPONENTS
/* AMP 기본 컴포넌트 - 이미지 */
<amp-img src="welcome.jpg" alt="Welcome" height="400" width="800"></amp-img>
/*AMP ...
AMP EXTENDED COMPONENT
... 35 more
AMP EXTENDED COMPONENT
/* AMP 확장 컴포넌트 - 캐러셀 */
<amp-carousel width=300 height=400>
<amp-img src="my-img1.png" width=300 he...
AMP EXTENDED COMPONENT
/* AMP 확장 컴포넌트 - 사이드바 */
<amp-sidebar id='sidebar'
layout="nodisplay"
side="right"> ...
AMP EXTENDED COMPONENT
/* AMP 확장 컴포넌트 - lightbox */
<amp-image-lightbox id="lightbox1"
layout="nodisplay">
</amp-image-lig...
AMP 벤치마킹
네이버 TV연예
AMP 프로토타이핑
AMP 벤치마킹 이슈
비디오
비디오는 잘 붙음. 단, 소스는 https여야 함
placeholder 이미지가 반드시 필요함
JS
커스텀 JS를 사용 할 수 없음. 댓글 수, TOP 버튼 동작 안함
sandbox ifra...
AMP 벤치마킹 TIMELINE
localhost에서

network throttling 4Mb↓, 3Mb↑, 20ms RTT 로 설정
AMP 벤치마킹 NETWORK
AMP 미적용
AMP 벤치마킹 NETWORK
AMP 적용
화면에 보이는 리소스를 먼저 다운로드하고
스크롤 바깥의 리소스를 순차적으로 레이지로딩
HOW AMP
SPEEDS UP
PERFORMANCE
How AMP Speeds Up Performance
비동기 스크립트만 허용
페이지 렌더링을 차단하는 자바스크립트 방지
AMP JS를 제외한 어떠한 자바스크립트도 허용하지 않음
모든 리소스의 사이즈를 지정
리소스 다운로...
How AMP Speeds Up Performance
써드 파티 자바스크립트를 크리티컬 패스에서 제거
써드파티 자바스크립트를 sandbox ifame 내부에서만 허용
부모 페이지의 실행을 차단하지 않으며 성능에 영향을 ...
How AMP Speeds Up Performance
스타일 재계산을 최소화
불필요한 레이아웃 방지를 위해 측정을 먼저 수행하고 변경을 나중에 처리
프레임당 스타일 재계산을 한 번만 할 수 있게 최대한 보장
GPU 가속...
How AMP Speeds Up Performance
리소스 로딩 순서를 제어
다운로드할 리소스들의 우선순위를 계산
현재 가장 중요한 리소스들을 먼저 다운로드
페이지를 즉시 로드
preconnect API
미리 가져올 ...
INSIDE OF AMP
AMP: CUSTOM ELEMENTS
export	function	registerElement(win,	name,	implementationClass)	{	
		knownElements[name]	=	implementa...
AMP: CUSTOM ELEMENTS
Custom	Element
BaseElement HTMLElement.prototype
AmpImg ElementProto	
this.implementation_	=	

new	Am...
새로운 HTML 타입을 정의하고

라이프 사이클을 제어
createdCallback	커스텀 엘리먼트를 등록할 때 발생 	
attachedCallback	커스텀 엘리먼트를 DOM에 추가할 때 발생
detachedCallback	커스텀 엘리먼트를 DOM에서 제거할 때 발생	
a...
firstAttachedCallback 커스텀 엘리먼트를 최초로 DOM에 추가할 때 발생
buildCallback 커스텀 엘리먼트와 자식 엘리먼트를 사용할 수 있을 때 발생
layoutCallback AMP가 커스텀 엘...
AMP: FSM(Finite-State Machine)
AMP는 조건에 따라 하나의 상태를 갖는다
조건이 변하면 다른 상태로 변한다
상태가 변하면 그에 따른 액션을 실행한다
OFF ON
turn on
turn off
AMP: FSM(Finite-State Machine)
prerender
paused
inactive
doPass
unload
resume
doPass
doPass
doPass
doPass
doPassdoPass
doP...
AMP: FSM(Finite-State Machine)
doPass = discoverWork + work
applySizesAndMediaQuery
discoverWork
measure
scheduleLayoutOrP...
AMP: FSM(Finite-State Machine)
applySizesAndMediaQuery
미디어 쿼리를 적용하고 AMP 사이즈 관련 속성을 파싱
measure
리소스의 사이즈와 위치를 측정. 리소스는 READY...
AMP: FSM(Finite-State Machine)
calcTaskScore
스케줄링한 작업들의 우선순위를 계산
1) 어떤 AMP 커스텀 엘리먼트인가? 2) 어떤 작업인가? 3) 뷰포트와 얼마나 가까운가?
peek
...
AMP: SINGLE PASS PROCESS
class	Pass	{	
				constructor(win,	handler,	opt_defaultDelay)	{	
								this.handler_;	
								...
AMP: PROMISE
src 설정
layoutComplete
호출
AMP: OPTIMIZATION REFLOW
리플로우
너비, 높이 같이 엘리먼트의 기하학적 구조에 영향을 주는 속성을 변경하면
그 요소의 사이즈와 위치를 다시 계산
이 요소의 변경에 영향을 받는 다른 요소들의 사이즈와 ...
AMP: OPTIMIZATION REFLOW
테두리 두께를 변경하고 높이를 변경할 경우
두께 변경 → 리플로우 → 리페인트 → 높이 변경 → 리플로우 → 리페인트
두께 변경 작업 저장 → 높이 변경 작업 저장 → 저장된...
AMP: OPTIMIZATION REFLOW
엘리먼트의 사이즈나 위치, 스크롤에 관련된
스타일 속성을 요청한다면?
브라우저는
요청한 스타일 속성의 값을 정확하게 계산하기 위해
저장되어있는 변경 작업들을 즉시 실행하고 리...
AMP: OPTIMIZATION REFLOW
// measure - (저장된 변경 작업들이 있다면) 리플로우 발생
var	h1	=	element1.clientHeight;	
// mutate - 변경 작업 저장
elem...
AMP: OPTIMIZATION REFLOW
//	measure	
var	h1	=	element1.clientHeight;	//(저장된 변경 작업들이 있다면) 리플로우 발생	
var	h2	=	element2.client...
NO batching DOM read/write operations
batching DOM read/write operations
AMP: OPTIMIZATION REFLOW
class	Vsync	{	
				..	
				..	
				mutate(mutator)	{	...	}	
				measure(measurer)	{	...	}	
				ru...
AMP: OPTIMIZATION REFLOW
for	(let	i	=	0;	i	<	tasks.length;	i++)	{	
				if	(tasks[i].measure)	{	
								tasks[i].measure(s...
AMP: OPTIMIZATION REFLOW
THANK YOU
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Google AMP는 어떻게 빠른 성능을 내나?
Upcoming SlideShare
Loading in …5
×

6

Share

Download to read offline

Google AMP는 어떻게 빠른 성능을 내나?

Download to read offline

AMP는 어떻게 빠른 성능을 내나?

Related Books

Free with a 30 day trial from Scribd

See all

Google AMP는 어떻게 빠른 성능을 내나?

  1. 1. AMP는 어떻게 빠른 성능을 내나? NAVER 김태훈 kishu@navercorp.com
  2. 2. about me 김태훈 kishu@navercorp.com NAVER FE플랫폼 SADI HTML5 초빙교수
 NHN NEXT WebUI Basic 겸임교수 Project Management Professional(PMP) 페이스북 프론트엔드개발그룹 운영 http://facebook.com/groups/webfrontend
  3. 3. AMP란 무엇인가? 벤치마킹 어떻게 빠른 성능을 내는가? AMP 인사이드 AMP 현황 AGENDA
  4. 4. AMP? ACCELLERATED MOBILE PAGES by Google 웹페이지(특히 정적 페이지)를 더 빠르게 렌더링 하기 위한 방법
 퍼포먼스 향상을 위한 구글의 경험과 베스트 프랙티스의 구현체
  5. 5. AMPs are just Web Pages!
  6. 6. AMP HTML 확장 가능한 HTML : AMP 확장 태그 및 속성 사용 AMP 확장 태그를 통해 <amp-carousel> 같은 컴포넌트 사용 가능 AMP 확장 태그는 웹 컴포넌트 - 커스텀 엘리먼트 기반 퍼포먼스를 위한 제약 : <img>는 <amp-img>로 써야 하는 등등
  7. 7. AMP VALIDATION
  8. 8. amp.js AMP 페이지와 리소스 라이프사이클 및 렌더링 타임 제어 AMP 커스텀 엘리먼트 구현 코드 웹페이지의 퍼포먼스 향상을 위한 베스트 프랙티스의 구현체 AMP는 외부 JS를 허용하지 않아요.! 사용자 자바스크립트를 사용하려면 sandbox iframe에서만 가능
  9. 9. AMP STYLE = CSS 외부 스타일, 엘리먼트 인라인 스타일 허용 안함 문서에 삽입하는 형태의 인라인 스타일만 사용 가능 최대 50KB만 허용 참고 네이버 모바일 메인페이지 스타일 - 총 2개 파일 약 100KB 네이버 모바일 뉴스 홈 - 총 2개 파일 약 67KB 네이비 모바일 뉴스 엔드 - 총 8개 파일 약 50KB <style amp-custom> /* any custom style goes here */ body { background-color: white; } amp-img { background-color: gray; border: 1px solid black; } </style>
  10. 10. AMP 컴포넌트를 이용해 HTML을 만들고 AMP JS만 로딩하면 웹페이지의 빠른 렌더링을 보장 + 구글 검색 결과에서 즉시 로딩(빠르고 멋있게) + 구글 CDN에 캐시
  11. 11. HELLO AMP!!! <!doctype html> <html amp lang="en"> <head> <meta charset="utf-8"> <title>Hello, AMPs</title> <link rel="canonical" href="http://example.ampproject.org/article-metadata.html" /> <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"> <style amp-boilerplate>body{ ... }</style> <script async src="https://cdn.ampproject.org/v0.js"></script> </head> <body> <h1>Welcome to the mobile web</h1> </body> </html>
  12. 12. AMP COMPONENTS /* AMP 기본 컴포넌트 - 이미지 */ <amp-img src="welcome.jpg" alt="Welcome" height="400" width="800"></amp-img> /*AMP 기본 컴포넌트 - 비디오 */ <amp-video width=400 height=300 src="https://yourhost.com/videos/myvideo.mp4" poster="myvideo-poster.jpg"> </amp-video> amp-ad amp-embed amp-img amp-pixel amp-video
  13. 13. AMP EXTENDED COMPONENT ... 35 more
  14. 14. AMP EXTENDED COMPONENT /* AMP 확장 컴포넌트 - 캐러셀 */ <amp-carousel width=300 height=400> <amp-img src="my-img1.png" width=300 height=400></amp-img> <amp-img src="my-img2.png" width=300 height=400></amp-img> <amp-img src="my-img3.png" width=300 height=400></amp-img> </amp-carousel>
  15. 15. AMP EXTENDED COMPONENT /* AMP 확장 컴포넌트 - 사이드바 */ <amp-sidebar id='sidebar' layout="nodisplay" side="right"> ...
  16. 16. AMP EXTENDED COMPONENT /* AMP 확장 컴포넌트 - lightbox */ <amp-image-lightbox id="lightbox1" layout="nodisplay"> </amp-image-lightbox>
  17. 17. AMP 벤치마킹 네이버 TV연예 AMP 프로토타이핑
  18. 18. AMP 벤치마킹 이슈 비디오 비디오는 잘 붙음. 단, 소스는 https여야 함 placeholder 이미지가 반드시 필요함 JS 커스텀 JS를 사용 할 수 없음. 댓글 수, TOP 버튼 동작 안함 sandbox iframe으로 구현하려고 해 봤지만 보안 문제 등 발생 nClick은 amp-analytics로 대처 가능할지 리서치 필요 외부 CSS 로딩 허용안함 HTML 헤더에 스타일 삽입 약 4KB HTML 요소에 인라인 스타일 허용 안함
  19. 19. AMP 벤치마킹 TIMELINE localhost에서
 network throttling 4Mb↓, 3Mb↑, 20ms RTT 로 설정
  20. 20. AMP 벤치마킹 NETWORK AMP 미적용
  21. 21. AMP 벤치마킹 NETWORK AMP 적용 화면에 보이는 리소스를 먼저 다운로드하고 스크롤 바깥의 리소스를 순차적으로 레이지로딩
  22. 22. HOW AMP SPEEDS UP PERFORMANCE
  23. 23. How AMP Speeds Up Performance 비동기 스크립트만 허용 페이지 렌더링을 차단하는 자바스크립트 방지 AMP JS를 제외한 어떠한 자바스크립트도 허용하지 않음 모든 리소스의 사이즈를 지정 리소스 다운로드 없이 사이즈와 위치를 계산하고 레이아웃 할 수 있음 확장 컴포넌트들을 렌더링 차단 없이 실행함 추가적인 HTTP 요청이 있지만 페이지 레이아웃과 렌더링을 차단하지 않음
  24. 24. How AMP Speeds Up Performance 써드 파티 자바스크립트를 크리티컬 패스에서 제거 써드파티 자바스크립트를 sandbox ifame 내부에서만 허용 부모 페이지의 실행을 차단하지 않으며 성능에 영향을 주지 않음 CSS는 HTML 내부 스타일시트만 허용하고 크기를 제한 HTML 페이지 내부에 style 태그로 삽입하는 형태로만 사용 스타일시트의 크기는 50KB로 제한 웹폰트를 효율적으로 다운로드 브라우저를 차단하는 어떠한 HTTP 요청도 발생하지 않게 웹폰트 다운로드
  25. 25. How AMP Speeds Up Performance 스타일 재계산을 최소화 불필요한 레이아웃 방지를 위해 측정을 먼저 수행하고 변경을 나중에 처리 프레임당 스타일 재계산을 한 번만 할 수 있게 최대한 보장 GPU 가속 애니메이션만 실행 페이지 레이아웃이 발생하지 않는 CSS 애니메이션만 사용 transform, opacity
  26. 26. How AMP Speeds Up Performance 리소스 로딩 순서를 제어 다운로드할 리소스들의 우선순위를 계산 현재 가장 중요한 리소스들을 먼저 다운로드 페이지를 즉시 로드 preconnect API 미리 가져올 페이지를 뷰포트 만큼만 가져옴
  27. 27. INSIDE OF AMP
  28. 28. AMP: CUSTOM ELEMENTS export function registerElement(win, name, implementationClass) { knownElements[name] = implementationClass; win.document.registerElement(name, { prototype: createAmpElementProto(win, name), }); } src/custom-element.js export function installImg(win) { registerElement(win, 'amp-img', AmpImg); } builtins/amp-img.js
  29. 29. AMP: CUSTOM ELEMENTS Custom Element BaseElement HTMLElement.prototype AmpImg ElementProto this.implementation_ = 
 new AmpImg(); AMP Components = HTML Custom Elements
  30. 30. 새로운 HTML 타입을 정의하고
 라이프 사이클을 제어
  31. 31. createdCallback 커스텀 엘리먼트를 등록할 때 발생 attachedCallback 커스텀 엘리먼트를 DOM에 추가할 때 발생 detachedCallback 커스텀 엘리먼트를 DOM에서 제거할 때 발생 attributeChangedCallback 커스텀 엘리먼트의 속성을 추가,수정,제거할 때 발생 AMP: CUSTOM ELEMENT Lifecycle Callbacks
  32. 32. firstAttachedCallback 커스텀 엘리먼트를 최초로 DOM에 추가할 때 발생 buildCallback 커스텀 엘리먼트와 자식 엘리먼트를 사용할 수 있을 때 발생 layoutCallback AMP가 커스텀 엘리먼트를 렌더링 할 때 발생 viewportCallback 커스텀 엘리먼트가 뷰포트에 들어오거나 나갈 때 발생. documentInactiveCallback 문서를 언로드 하기 전 발생 AMP: CUSTOM ELEMENT AMP's Extended Lifecycle Callbacks
  33. 33. AMP: FSM(Finite-State Machine) AMP는 조건에 따라 하나의 상태를 갖는다 조건이 변하면 다른 상태로 변한다 상태가 변하면 그에 따른 액션을 실행한다 OFF ON turn on turn off
  34. 34. AMP: FSM(Finite-State Machine) prerender paused inactive doPass unload resume doPass doPass doPass doPass doPassdoPass doPass doPass doPass paused paused unload unload doPass doPassvisible hidden
  35. 35. AMP: FSM(Finite-State Machine) doPass = discoverWork + work applySizesAndMediaQuery discoverWork measure scheduleLayoutOrPreload setInViewport calcTaskScore peek startLayout work
  36. 36. AMP: FSM(Finite-State Machine) applySizesAndMediaQuery 미디어 쿼리를 적용하고 AMP 사이즈 관련 속성을 파싱 measure 리소스의 사이즈와 위치를 측정. 리소스는 READY_FOR_LAYOUT 상태가 됨. scheduleLayoutOrPreload 뷰포트를 확장한 특정 영역안에 있는 리소스들을 레이아웃하기 위한 작업을 스케줄링 setInViewport 리소스들이 뷰포트 안에 있는지 밖에 있는지를 계산하고 viewportCallback실행 discoverWork
  37. 37. AMP: FSM(Finite-State Machine) calcTaskScore 스케줄링한 작업들의 우선순위를 계산 1) 어떤 AMP 커스텀 엘리먼트인가? 2) 어떤 작업인가? 3) 뷰포트와 얼마나 가까운가? peek 우선순위가 가장 높은 작업을 선택 startLayout 선택한 작업 대상의 리소스를 LAYOUT_SCHEDULED 상태로 변경하고 레이아웃을 시작 예를 들어 리소스가 amp-img라면 src 속성에 이미지 경로를 지정하는 것으로 레이아웃 할 수 있음 work
  38. 38. AMP: SINGLE PASS PROCESS class Pass { constructor(win, handler, opt_defaultDelay) { this.handler_; this.defaultDelay_; this.scheduled_; this.nextTime; this.running_; } isPending(); schedule(opt_delay); cancel(); } // 수행할 작업을 Pass에 등록 new Pass(this.win, () => this.doPass_()); // 작업 큐의 마지막 실행시간을 기준으로 시간으로 다음 작업시간 계산 let nextPassDelay = (now - this.exec_.getLastDequeueTime()) * 2; nextPassDelay = Math.max(Math.min(30000, nextPassDelay), 5000);
  39. 39. AMP: PROMISE src 설정 layoutComplete 호출
  40. 40. AMP: OPTIMIZATION REFLOW 리플로우 너비, 높이 같이 엘리먼트의 기하학적 구조에 영향을 주는 속성을 변경하면 그 요소의 사이즈와 위치를 다시 계산 이 요소의 변경에 영향을 받는 다른 요소들의 사이즈와 위치도 다시 계산 리플로우는 리페인트를 발생, 고비용 수반 가능한 리플로우, 리페인트를 적게 일어나게 하는 것이 좋다
  41. 41. AMP: OPTIMIZATION REFLOW 테두리 두께를 변경하고 높이를 변경할 경우 두께 변경 → 리플로우 → 리페인트 → 높이 변경 → 리플로우 → 리페인트 두께 변경 작업 저장 → 높이 변경 작업 저장 → 저장된 작업 실행 →리플로우 → 리페인트 브라우저는 변경 작업들을 모았다가 필요할 경우 한꺼번에 실행
  42. 42. AMP: OPTIMIZATION REFLOW 엘리먼트의 사이즈나 위치, 스크롤에 관련된 스타일 속성을 요청한다면? 브라우저는 요청한 스타일 속성의 값을 정확하게 계산하기 위해 저장되어있는 변경 작업들을 즉시 실행하고 리플로우, 리페인트 한다 스타일 속성에 접근할 때는 불필요한 리플로우가 일어나지 않게 주의해야 함
  43. 43. AMP: OPTIMIZATION REFLOW // measure - (저장된 변경 작업들이 있다면) 리플로우 발생 var h1 = element1.clientHeight; // mutate - 변경 작업 저장 element1.style.height = (h1 * 2) + 'px'; // measure - 리플로우 발생 var h2 = element2.clientHeight; // mutate - 변경 작업 저장 element2.style.height = (h2 * 2) + 'px'; // measure - 리플로우 발생 var h3 = element3.clientHeight; // mutate - 변경 작업 저장 element3.style.height = (h3 * 2) + 'px';
  44. 44. AMP: OPTIMIZATION REFLOW // measure var h1 = element1.clientHeight; //(저장된 변경 작업들이 있다면) 리플로우 발생 var h2 = element2.clientHeight; // 저장된 작업 없음 var h3 = element3.clientHeight; // 저장된 작업 없음 // mutate element1.style.height = (h1 * 2) + 'px'; // 변경 작업 저장 element2.style.height = (h2 * 2) + 'px'; // 변경 작업 저장 element3.style.height = (h3 * 2) + 'px'; // 변경 작업 저장
  45. 45. NO batching DOM read/write operations
  46. 46. batching DOM read/write operations
  47. 47. AMP: OPTIMIZATION REFLOW class Vsync { .. .. mutate(mutator) { ... } measure(measurer) { ... } run(task, opt_state) { ... } .. .. }
  48. 48. AMP: OPTIMIZATION REFLOW for (let i = 0; i < tasks.length; i++) { if (tasks[i].measure) { tasks[i].measure(states[i]); } } for (let i = 0; i < tasks.length; i++) { if (tasks[i].mutate) { tasks[i].mutate(states[i]); } }
  49. 49. AMP: OPTIMIZATION REFLOW
  50. 50. THANK YOU
  • junylee165

    Jun. 27, 2017
  • biztalk72

    May. 10, 2017
  • Parkwookyun

    Feb. 20, 2017
  • cwdoh

    Dec. 7, 2016
  • miraccoccoa

    Oct. 25, 2016
  • hyuntaeklee399

    Oct. 2, 2016

AMP는 어떻게 빠른 성능을 내나?

Views

Total views

706

On Slideshare

0

From embeds

0

Number of embeds

6

Actions

Downloads

16

Shares

0

Comments

0

Likes

6

×