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

64
AMP는 어떻게 빠른 성능을 내나? NAVER 김태훈 [email protected]

Upload: tai-hoon-kim

Post on 14-Apr-2017

187 views

Category:

Technology


0 download

TRANSCRIPT

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

AMP는

어떻게 빠른 성능을 내나? NAVER�김태훈�[email protected]

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

about me

김태훈�[email protected]�NAVER�FE플랫폼�

SADI�HTML5�초빙교수NHN�NEXT�WebUI�Basic�겸임교수�Project�Management�Professional(PMP)�

페이스북�프론트엔드개발그룹�운영�http://facebook.com/groups/webfrontend

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

AMP란 무엇인가?

벤치마킹

어떻게 빠른 성능을 내는가?

AMP 인사이드

AMP 현황

AGENDA

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

AMP?

ACCELLERATED�MOBILE�PAGES�by�Google�

웹페이지(특히�정적�페이지)를�더�빠르게�렌더링�하기�위한�방법 퍼포먼스�향상을�위한�구글의�경험과�베스트�프랙티스의�구현체

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

AMPs are just Web Pages!

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

AMP HTML

확장�가능한�HTML�:�AMP�확장�태그�및�속성�사용�

AMP�확장�태그를�통해�<amp-carousel>�같은�컴포넌트�사용�가능�

AMP�확장�태그는�웹�컴포넌트�-�커스텀�엘리먼트�기반�

퍼포먼스를�위한�제약�:�<img>는�<amp-img>로�써야�하는�등등

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

AMP VALIDATION

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

amp.js

AMP�페이지와�리소스�라이프사이클�및�렌더링�타임�제어�

AMP�커스텀�엘리먼트�구현�코드�

웹페이지의�퍼포먼스�향상을�위한�베스트�프랙티스의�구현체�

AMP는�외부�JS를�허용하지�않아요.!�사용자�자바스크립트를�사용하려면�sandbox�iframe에서만�가능

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

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>

Page 10: Google AMP는 어떻게 빠른 성능을 내나?
Page 11: Google AMP는 어떻게 빠른 성능을 내나?
Page 12: Google AMP는 어떻게 빠른 성능을 내나?
Page 13: Google AMP는 어떻게 빠른 성능을 내나?
Page 14: Google AMP는 어떻게 빠른 성능을 내나?
Page 15: Google AMP는 어떻게 빠른 성능을 내나?
Page 16: Google AMP는 어떻게 빠른 성능을 내나?

AMP 컴포넌트를 이용해 HTML을 만들고

AMP JS만 로딩하면

웹페이지의 빠른 렌더링을 보장

+ 구글 검색 결과에서 즉시 로딩(빠르고 멋있게) + 구글 CDN에 캐시

Page 17: Google AMP는 어떻게 빠른 성능을 내나?
Page 18: Google AMP는 어떻게 빠른 성능을 내나?
Page 19: Google AMP는 어떻게 빠른 성능을 내나?
Page 20: Google AMP는 어떻게 빠른 성능을 내나?

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>

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

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-imgamp-pixel amp-video

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

AMP EXTENDED COMPONENT

... 35 more

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

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>

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

AMP EXTENDED COMPONENT/*�AMP�확장�컴포넌트�-�사이드바�*/�

<amp-sidebar id='sidebar' layout="nodisplay" side="right"> ...

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

AMP EXTENDED COMPONENT/*�AMP�확장�컴포넌트�-�lightbox�*/�

<amp-image-lightbox id="lightbox1" layout="nodisplay"></amp-image-lightbox>

Page 26: Google AMP는 어떻게 빠른 성능을 내나?
Page 27: Google AMP는 어떻게 빠른 성능을 내나?

AMP 벤치마킹

네이버�TV연예�AMP�프로토타이핑�

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

AMP 벤치마킹 이슈

비디오�비디오는�잘�붙음.�단,�소스는�https여야�함�placeholder�이미지가�반드시�필요함�

JS�커스텀�JS를�사용�할�수�없음.�댓글�수,�TOP�버튼�동작�안함�sandbox�iframe으로�구현하려고�해�봤지만�보안�문제�등�발생�nClick은�amp-analytics로�대처�가능할지�리서치�필요�

외부�CSS�로딩�허용안함�HTML�헤더에�스타일�삽입�약�4KB�HTML�요소에�인라인�스타일�허용�안함

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

AMP 벤치마킹 TIMELINE

localhost에서network�throttling�4Mb↓,�3Mb↑,�20ms�RTT�로�설정

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

AMP 벤치마킹 NETWORK

AMP�미적용

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

AMP 벤치마킹 NETWORK

AMP�적용

화면에�보이는�리소스를�먼저�다운로드하고�스크롤�바깥의�리소스를�순차적으로�레이지로딩�

Page 32: Google AMP는 어떻게 빠른 성능을 내나?
Page 33: Google AMP는 어떻게 빠른 성능을 내나?
Page 34: Google AMP는 어떻게 빠른 성능을 내나?

HOW AMP SPEEDS UP PERFORMANCE

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

How AMP Speeds Up Performance

비동기�스크립트만�허용�페이지�렌더링을�차단하는�자바스크립트�방지�AMP�JS를�제외한�어떠한�자바스크립트도�허용하지�않음�

모든�리소스의�사이즈를�지정�리소스�다운로드�없이�사이즈와�위치를�계산하고�레이아웃�할�수�있음�

확장�컴포넌트들을�렌더링�차단�없이�실행함�추가적인�HTTP�요청이�있지만�페이지�레이아웃과�렌더링을�차단하지�않음

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

How AMP Speeds Up Performance

써드�파티�자바스크립트를�크리티컬�패스에서�제거�써드파티�자바스크립트를�sandbox�ifame�내부에서만�허용�부모�페이지의�실행을�차단하지�않으며�성능에�영향을�주지�않음�

CSS는�HTML�내부�스타일시트만�허용하고�크기를�제한�HTML�페이지�내부에�style�태그로�삽입하는�형태로만�사용�스타일시트의�크기는�50KB로�제한�

웹폰트를�효율적으로�다운로드�브라우저를�차단하는�어떠한�HTTP�요청도�발생하지�않게�웹폰트�다운로드

Page 37: Google AMP는 어떻게 빠른 성능을 내나?
Page 38: Google AMP는 어떻게 빠른 성능을 내나?

How AMP Speeds Up Performance

스타일�재계산을�최소화�불필요한�레이아웃�방지를�위해�측정을�먼저�수행하고�변경을�나중에�처리�프레임당�스타일�재계산을�한�번만�할�수�있게�최대한�보장�

GPU�가속�애니메이션만�실행�페이지�레이아웃이�발생하지�않는�CSS�애니메이션만�사용�transform,�opacity

Page 39: Google AMP는 어떻게 빠른 성능을 내나?
Page 40: Google AMP는 어떻게 빠른 성능을 내나?

How AMP Speeds Up Performance

리소스�로딩�순서를�제어�다운로드할�리소스들의�우선순위를�계산�현재�가장�중요한�리소스들을�먼저�다운로드�

페이지를�즉시�로드�preconnect�API�미리�가져올�페이지를�뷰포트�만큼만�가져옴

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

INSIDE OF AMP

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

AMP: CUSTOM ELEMENTS

exportfunctionregisterElement(win,name,implementationClass){knownElements[name]=implementationClass;

win.document.registerElement(name,{prototype:createAmpElementProto(win,name),});}

src/custom-element.js

exportfunctioninstallImg(win){registerElement(win,'amp-img',AmpImg);}

builtins/amp-img.js

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

AMP: CUSTOM ELEMENTS

CustomElement

BaseElement HTMLElement.prototype

AmpImg ElementProto

this.implementation_=newAmpImg();

AMP Components = HTML Custom Elements

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

새로운 HTML 타입을 정의하고라이프 사이클을 제어

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

createdCallback커스텀�엘리먼트를�등록할�때�발생�

attachedCallback커스텀�엘리먼트를�DOM에�추가할�때�발생

detachedCallback커스텀�엘리먼트를�DOM에서�제거할�때�발생

attributeChangedCallback커스텀�엘리먼트의�속성을�추가,수정,제거할�때�발생

AMP: CUSTOM ELEMENT

Lifecycle Callbacks

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

firstAttachedCallback 커스텀�엘리먼트를�최초로�DOM에�추가할�때�발생

buildCallback 커스텀�엘리먼트와�자식�엘리먼트를�사용할�수�있을�때�발생

layoutCallback AMP가�커스텀�엘리먼트를�렌더링�할�때�발생

viewportCallback 커스텀�엘리먼트가�뷰포트에�들어오거나�나갈�때�발생.

documentInactiveCallback 문서를�언로드�하기�전�발생

AMP: CUSTOM ELEMENT

AMP's Extended Lifecycle Callbacks

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

AMP: FSM(Finite-State Machine)

AMP는�조건에�따라�하나의�상태를�갖는다�조건이�변하면�다른�상태로�변한다�상태가�변하면�그에�따른�액션을�실행한다

OFF ON

turn on

turn off

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

AMP: FSM(Finite-State Machine)

prerender

paused

inactive

doPass

unload

resume

doPass

doPass

doPass

doPass

doPassdoPass

doPassdoPass

doPass

paused

paused

unload

unload

doPass

doPassvisible

hidden

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

AMP: FSM(Finite-State Machine)doPass = discoverWork + work

applySizesAndMediaQuery

discoverWork

measure

scheduleLayoutOrPreload

setInViewport

calcTaskScore

peek

startLayout

work

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

AMP: FSM(Finite-State Machine)

applySizesAndMediaQuery미디어 쿼리를 적용하고 AMP 사이즈 관련 속성을 파싱

measure리소스의 사이즈와 위치를 측정. 리소스는 READY_FOR_LAYOUT 상태가 됨.

scheduleLayoutOrPreload뷰포트를 확장한 특정 영역안에 있는 리소스들을 레이아웃하기 위한 작업을 스케줄링

setInViewport리소스들이 뷰포트 안에 있는지 밖에 있는지를 계산하고 viewportCallback실행

discoverWork

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

AMP: FSM(Finite-State Machine)

calcTaskScore스케줄링한�작업들의�우선순위를�계산�

1)�어떤�AMP�커스텀�엘리먼트인가?�2)�어떤�작업인가?�3)�뷰포트와�얼마나�가까운가?�

peek우선순위가�가장�높은�작업을�선택�

startLayout선택한�작업�대상의�리소스를�LAYOUT_SCHEDULED�상태로�변경하고�레이아웃을�시작�

예를�들어�리소스가�amp-img라면�src�속성에�이미지�경로를�지정하는�것으로�레이아웃�할�수�있음�

work

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

AMP: SINGLE PASS PROCESS

classPass{constructor(win,handler,opt_defaultDelay){this.handler_;this.defaultDelay_;this.scheduled_;this.nextTime;this.running_;}isPending();schedule(opt_delay);cancel();}

//�수행할�작업을�Pass에�등록�newPass(this.win,()=>this.doPass_());

//�작업�큐의�마지막�실행시간을�기준으로�시간으로�다음�작업시간�계산�letnextPassDelay=(now-this.exec_.getLastDequeueTime())*2;nextPassDelay=Math.max(Math.min(30000,nextPassDelay),5000);

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

AMP: PROMISE

src�설정

layoutComplete�호출

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

AMP: OPTIMIZATION REFLOW

리플로우�

너비,�높이�같이�엘리먼트의�기하학적�구조에�영향을�주는�속성을�변경하면�그�요소의�사이즈와�위치를�다시�계산�

이�요소의�변경에�영향을�받는�다른�요소들의�사이즈와�위치도�다시�계산�

리플로우는�리페인트를�발생,�고비용�수반�가능한�리플로우,�리페인트를�적게�일어나게�하는�것이�좋다

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

AMP: OPTIMIZATION REFLOW

테두리�두께를�변경하고�높이를�변경할�경우�

두께�변경�→�리플로우�→�리페인트�→�높이�변경�→�리플로우�→�리페인트�

두께�변경�작업�저장�→�높이�변경�작업�저장�→�저장된�작업�실행�→리플로우�→�리페인트�

브라우저는�변경�작업들을�모았다가�필요할�경우�한꺼번에�실행

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

AMP: OPTIMIZATION REFLOW

엘리먼트의�사이즈나�위치,�스크롤에�관련된�스타일�속성을�요청한다면?�

브라우저는�요청한�스타일�속성의�값을�정확하게�계산하기�위해�저장되어있는�변경�작업들을�즉시�실행하고�리플로우,�리페인트�한다�

스타일�속성에�접근할�때는�불필요한�리플로우가�일어나지�않게�주의해야�함

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

AMP: OPTIMIZATION REFLOW

//�measure�-�(저장된�변경�작업들이�있다면)�리플로우�발생�varh1=element1.clientHeight;

//�mutate�-�변경�작업�저장�element1.style.height=(h1*2)+'px';

//�measure�-�리플로우�발생�varh2=element2.clientHeight;

//�mutate�-�변경�작업�저장�element2.style.height=(h2*2)+'px';

//�measure�-�리플로우�발생�varh3=element3.clientHeight;

//�mutate�-�변경�작업�저장�element3.style.height=(h3*2)+'px';

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

AMP: OPTIMIZATION REFLOW

//measurevarh1=element1.clientHeight;//(저장된�변경�작업들이�있다면)�리플로우�발생varh2=element2.clientHeight;//�저장된�작업�없음

varh3=element3.clientHeight;//�저장된�작업�없음

//mutateelement1.style.height=(h1*2)+'px';//�변경�작업�저장element2.style.height=(h2*2)+'px';//�변경�작업�저장

element3.style.height=(h3*2)+'px';//�변경�작업�저장

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

NO batching DOM read/write operations

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

batching DOM read/write operations

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

AMP: OPTIMIZATION REFLOW

classVsync{....mutate(mutator){...}measure(measurer){...}run(task,opt_state){...}....}

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

AMP: OPTIMIZATION REFLOW

for(leti=0;i<tasks.length;i++){if(tasks[i].measure){tasks[i].measure(states[i]);}}

for(leti=0;i<tasks.length;i++){if(tasks[i].mutate){tasks[i].mutate(states[i]);}}

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

AMP: OPTIMIZATION REFLOW

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

THANK YOU