6. AMP HTML
확장 가능한 HTML : AMP 확장 태그 및 속성 사용
AMP 확장 태그를 통해 <amp-carousel> 같은 컴포넌트 사용 가능
AMP 확장 태그는 웹 컴포넌트 - 커스텀 엘리먼트 기반
퍼포먼스를 위한 제약 : <img>는 <amp-img>로 써야 하는 등등
8. amp.js
AMP 페이지와 리소스 라이프사이클 및 렌더링 타임 제어
AMP 커스텀 엘리먼트 구현 코드
웹페이지의 퍼포먼스 향상을 위한
베스트 프랙티스의 구현체
AMP는 외부 JS를 허용하지 않아요.!
사용자 자바스크립트를 사용하려면 sandbox iframe에서만 가능
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>
16. AMP 컴포넌트를 이용해 HTML을 만들고
AMP JS만 로딩하면
웹페이지의 빠른 렌더링을 보장
+ 구글 검색 결과에서 즉시 로딩(빠르고 멋있게)
+ 구글 CDN에 캐시
28. AMP 벤치마킹 이슈
비디오
비디오는 잘 붙음. 단, 소스는 https여야 함
placeholder 이미지가 반드시 필요함
JS
커스텀 JS를 사용 할 수 없음. 댓글 수, TOP 버튼 동작 안함
sandbox iframe으로 구현하려고 해 봤지만 보안 문제 등 발생
nClick은 amp-analytics로 대처 가능할지 리서치 필요
외부 CSS 로딩 허용안함
HTML 헤더에 스타일 삽입 약 4KB
HTML 요소에 인라인 스타일 허용 안함
35. How AMP Speeds Up Performance
비동기 스크립트만 허용
페이지 렌더링을 차단하는 자바스크립트 방지
AMP JS를 제외한 어떠한 자바스크립트도 허용하지 않음
모든 리소스의 사이즈를 지정
리소스 다운로드 없이 사이즈와 위치를 계산하고 레이아웃 할 수 있음
확장 컴포넌트들을 렌더링 차단 없이 실행함
추가적인 HTTP 요청이 있지만 페이지 레이아웃과 렌더링을 차단하지 않음
36. How AMP Speeds Up Performance
써드 파티 자바스크립트를 크리티컬 패스에서 제거
써드파티 자바스크립트를 sandbox ifame 내부에서만 허용
부모 페이지의 실행을 차단하지 않으며 성능에 영향을 주지 않음
CSS는 HTML 내부 스타일시트만 허용하고 크기를 제한
HTML 페이지 내부에 style 태그로 삽입하는 형태로만 사용
스타일시트의 크기는 50KB로 제한
웹폰트를 효율적으로 다운로드
브라우저를 차단하는 어떠한 HTTP 요청도 발생하지 않게 웹폰트 다운로드
38. How AMP Speeds Up Performance
스타일 재계산을 최소화
불필요한 레이아웃 방지를 위해 측정을 먼저 수행하고 변경을 나중에 처리
프레임당 스타일 재계산을 한 번만 할 수 있게 최대한 보장
GPU 가속 애니메이션만 실행
페이지 레이아웃이 발생하지 않는 CSS 애니메이션만 사용
transform, opacity
40. How AMP Speeds Up Performance
리소스 로딩 순서를 제어
다운로드할 리소스들의 우선순위를 계산
현재 가장 중요한 리소스들을 먼저 다운로드
페이지를 즉시 로드
preconnect API
미리 가져올 페이지를 뷰포트 만큼만 가져옴
45. createdCallback 커스텀 엘리먼트를 등록할 때 발생
attachedCallback 커스텀 엘리먼트를 DOM에 추가할 때 발생
detachedCallback 커스텀 엘리먼트를 DOM에서 제거할 때 발생
attributeChangedCallback 커스텀 엘리먼트의 속성을 추가,수정,제거할 때 발생
AMP: CUSTOM ELEMENT
Lifecycle Callbacks
46. firstAttachedCallback 커스텀 엘리먼트를 최초로 DOM에 추가할 때 발생
buildCallback 커스텀 엘리먼트와 자식 엘리먼트를 사용할 수 있을 때 발생
layoutCallback AMP가 커스텀 엘리먼트를 렌더링 할 때 발생
viewportCallback 커스텀 엘리먼트가 뷰포트에 들어오거나 나갈 때 발생.
documentInactiveCallback 문서를 언로드 하기 전 발생
AMP: CUSTOM ELEMENT
AMP's Extended Lifecycle Callbacks
49. AMP: FSM(Finite-State Machine)
doPass = discoverWork + work
applySizesAndMediaQuery
discoverWork
measure
scheduleLayoutOrPreload
setInViewport
calcTaskScore
peek
startLayout
work
50. AMP: FSM(Finite-State Machine)
applySizesAndMediaQuery
미디어 쿼리를 적용하고 AMP 사이즈 관련 속성을 파싱
measure
리소스의 사이즈와 위치를 측정. 리소스는 READY_FOR_LAYOUT 상태가 됨.
scheduleLayoutOrPreload
뷰포트를 확장한 특정 영역안에 있는 리소스들을
레이아웃하기 위한 작업을 스케줄링
setInViewport
리소스들이 뷰포트 안에 있는지 밖에 있는지를 계산하고 viewportCallback실행
discoverWork
51. AMP: FSM(Finite-State Machine)
calcTaskScore
스케줄링한 작업들의 우선순위를 계산
1) 어떤 AMP 커스텀 엘리먼트인가? 2) 어떤 작업인가? 3) 뷰포트와 얼마나 가까운가?
peek
우선순위가 가장 높은 작업을 선택
startLayout
선택한 작업 대상의 리소스를 LAYOUT_SCHEDULED 상태로 변경하고 레이아웃을 시작
예를 들어 리소스가 amp-img라면 src 속성에 이미지 경로를 지정하는 것으로 레이아웃 할 수 있음
work
52. 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);
54. AMP: OPTIMIZATION REFLOW
리플로우
너비, 높이 같이 엘리먼트의 기하학적 구조에 영향을 주는 속성을 변경하면
그 요소의 사이즈와 위치를 다시 계산
이 요소의 변경에 영향을 받는 다른 요소들의 사이즈와 위치도 다시 계산
리플로우는 리페인트를 발생, 고비용 수반
가능한 리플로우, 리페인트를 적게 일어나게 하는 것이 좋다
55. AMP: OPTIMIZATION REFLOW
테두리 두께를 변경하고 높이를 변경할 경우
두께 변경 → 리플로우 → 리페인트 → 높이 변경 → 리플로우 → 리페인트
두께 변경 작업 저장 → 높이 변경 작업 저장 → 저장된 작업 실행 →리플로우 → 리페인트
브라우저는 변경 작업들을 모았다가 필요할 경우 한꺼번에 실행
56. AMP: OPTIMIZATION REFLOW
엘리먼트의 사이즈나 위치, 스크롤에 관련된
스타일 속성을 요청한다면?
브라우저는
요청한 스타일 속성의 값을 정확하게 계산하기 위해
저장되어있는 변경 작업들을 즉시 실행하고 리플로우, 리페인트 한다
스타일 속성에 접근할 때는
불필요한 리플로우가 일어나지 않게 주의해야 함
57. 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';
58. 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'; // 변경 작업 저장