6. AMP가 동작하는 원리
비동기 자바스크립트만 허용
모든 리소스 크기를 정적으로 지정
확장 메커니즘이 렌더링을 차단하지 않도록 함
모든 3P 자바스크립트를 주요 로딩 패스에서 제거
모든 CSS는 인라인이며 50KB까지 제한
효율적인 웹폰트 사용
스타일 재계산 최소화
GPU 가속 애니메이션만 사용 가능하게 함
리소스 로딩 우선순위를 지정
Preconnect API를 사용해 즉시 페이지를 로드
7. AMP가 동작하는 원리
비동기 자바스크립트만 허용
모든 리소스 크기를 정적으로 지정
확장 메커니즘이 렌더링을 차단하지 않도록 함
모든 3P 자바스크립트를 주요 로딩 패스에서 제거
모든 CSS는 인라인이며 50KB까지 제한
효율적인 웹폰트 사용
스타일 재계산 최소화
GPU 가속 애니메이션만 사용 가능하게 함
리소스 로딩 우선순위를 지정
Preconnect API를 사용해 즉시 페이지를 로드
8. 모든 3P 자바스크립트를 주요 로딩 패스에서 제거
AMP는 3P 자바스크립트 실행을 iFrame 내부에서만 허용합니다.
iFrame 내부의 자바스크립트는 부모 페이지의 실행을 차단하지 않고,
스타일 재계산 및 레이아웃 계산이 iFrame 내부에서 일어나기 때문에,
부모 요소에 영향을 주지 않습니다
9. 모든 CSS는 인라인이며 50KB로 제한합니다
CSS는 시간이 지날 수록 늘어나는 경향이 있고,
외부 CSS는 HTTP 요청을 여러번 하게 하여 네트워크 비용을 감수해야합니다.
따라서 AMP에서는 CSS를 인라인으로 넣고, 50KB로 제한합니다.
10. 효율적인 웹폰트 사용
네트워크 이슈로 인해 웹 폰트의 지연 로딩이 발생하는데,
웹 폰트의 로딩이 지연되면 브라우저가 텍스트 렌더링을 위한 폰트 리소스가 무엇인 지 인식하기 전에,
렌더링 트리를 생성합니다.
11. 효율적인 웹폰트 사용
따라서 폰트를 가져오는 과정이 다른 리소스 요청보다 훨씬 뒤로 지연되며,
브라우저에서 리소스를 가져오기 전까지 폰트가 렌더링되지 않을 수 있습니다.
22. DOM 상속구조
EXAMPLE 2: <div>
HTMLDivElement
HTMLElement
Element
Node
EventTarget
DIV요소의 DOM 상속구조
23. DOM 상속구조
EXAMPLE 2: <div>
HTMLDivElement
> Div Element
HTMLElement
> All of HTML element
Element
> represents an Document object
Node
> DOM Interface
EventTarget
> Event Interface
DIV요소의 DOM 상속구조
24. DOM 확장
Example 3: Custom Elements Card
class Card from HTMLElement {
contructor() {
super();
// Inner Element Structure
}
}
customElements.define(‘Card’, Card);
<Card></Card>
DOM를 확장하여 새로운 Card 요소를 생성
29. AMP HTML Lifecycle
State: <NOT BUILT> <NOT UPGRADED> <NOT ATTACHED>
> 아직 어떤 것도 하지 않은 상태
State: <NOT BUILT> <NOT ATTACHED>
> Element의 하위 요소가 준비된 상태
State: <NOT BUILT>
> Shadow DOM이 붙은 상태
State: <Built>
> 요소를 사용 가능한 상태
State: <LAID OUT>
> 화면 내에 배치된 상태
State: <IN VIEWPORT>
> 유저의 뷰포트 내에 해당 요소가 있을 때
custom DOM의 생존주기는 다음과 같다
37. 서비스 워커 등록하기
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// 등록이 성공한다면
console.log(‘서비스 워커 등록 성공: ', registration.scope);
}).catch(function(err) {
// 등록이 실패한 경우 :(
console.log(‘서비스 워커 등록 에러: ', err);
});
});
}
브라우저에서 서비스 워커를 지원하는 경우
38. 서비스 워커 등록하기
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// 등록이 성공한다면
console.log(‘서비스 워커 등록 성공: ', registration.scope);
}).catch(function(err) {
// 등록이 실패한 경우 :(
console.log(‘서비스 워커 등록 에러: ', err);
});
});
}
윈도우가 로딩되면
39. 서비스 워커 등록하기
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// 등록이 성공한다면
console.log(‘서비스 워커 등록 성공: ', registration.scope);
}).catch(function(err) {
// 등록이 실패한 경우 :(
console.log(‘서비스 워커 등록 에러: ', err);
});
});
}
서비스 워커를 등록한다
40. 서비스 워커 등록하기
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js').then(function(registration) {
// 등록이 성공한다면
console.log(‘서비스 워커 등록 성공: ', registration.scope);
}).catch(function(err) {
// 등록이 실패한 경우 :(
console.log(‘서비스 워커 등록 에러: ', err);
});
});
}
브라우저에서 서비스 워커를 지원하는 경우 서비스 워커를 등록한다
41. 서비스 워커 설치
var CACHE_NAME = 'my-site-cache-v1';
var urlsToCache = [
'/',
'/styles/main.css',
'/script/main.js'
];
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
서비스 워커로 수행할 일들을 기록한다.
42. 서비스 워커 설치
var CACHE_NAME = 'my-site-cache-v1';
var urlsToCache = [
'/',
'/styles/main.css',
'/script/main.js'
];
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
캐시할 리소스들
43. 서비스 워커 설치
var CACHE_NAME = 'my-site-cache-v1';
var urlsToCache = [
'/',
'/styles/main.css',
'/script/main.js'
];
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
설치 이벤트가 발생하면
44. 서비스 워커 설치
var CACHE_NAME = 'my-site-cache-v1';
var urlsToCache = [
'/',
'/styles/main.css',
'/script/main.js'
];
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
캐시에 원하는 리소스를 저장한다.
45. 요청 캐시 및 반환
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// 캐시 확인 - 응답 반환
if (response) {
return response;
}
return fetch(event.request);
}
)
);
});
서비스워커 설치 후 서비스워커 내 데이터 받기
46. 서비스 워커
서비스 워커를 사용해 웹 사이트에서 자주 사용될 리소스를 캐싱하고,
백그라운드에서 스크립트를 실행시킬 수 있다.
48. Web app manifest
EXAMPLE: manifest.json
{
"short_name": “My awesome App”,
"name": “My awesome App - for all airplane users”,
"icons": [
{
"src": "launcher-icon-4x.png",
"type": "image/png",
"sizes": "192x192"
}
],
"start_url": “index.html?launcher=true”,
“background_color”: “#2ac1bc”,
“theme_color”: “#2ac1bc”,
"display": “standalone"
}
웹 앱의 정보를 설정합니다.
49. Web app manifest
EXAMPLE: manifest.json
{
"short_name": “My awesome App”, // 유저의 홈화면에서 보일 이름
"name": “My awesome App - for all airplane users”, // 유저가 배너에서 볼 이름
"icons": [
{
"src": "launcher-icon-4x.png",
"type": "image/png",
"sizes": "192x192"
}
],
"start_url": “index.html?launcher=true”,
“background_color”: “#2ac1bc”,
“theme_color”: “#2ac1bc”,
"display": “standalone"
}
웹 앱의 정보를 설정합니다.
50. Web app manifest
EXAMPLE: manifest.json
{
"short_name": “My awesome App”, // 유저의 홈화면에서 보일 이름
"name": “My awesome App - for all airplane users”, // 유저가 배너에서 볼 이름
"icons": [ // 메인 화면에 추가하면 볼 이미지
{
"src": "launcher-icon-4x.png",
"type": "image/png",
"sizes": "192x192"
}
],
"start_url": “index.html?launcher=true”,
“background_color”: “#2ac1bc”,
“theme_color”: “#2ac1bc”,
"display": “standalone"
}
웹 앱의 정보를 설정합니다.
51. Web app manifest
EXAMPLE: manifest.json
{
"short_name": “My awesome App”, // 유저의 홈화면에서 보일 이름
"name": “My awesome App - for all airplane users”, // 유저가 배너에서 볼 이름
"icons": [ // 메인 화면에 추가하면 볼 이미지
{
"src": "launcher-icon-4x.png",
"type": "image/png",
"sizes": "192x192"
}
],
"start_url": “index.html?launcher=true”, // 유저의 웹사이트 접근점
“background_color”: “#2ac1bc”,
“theme_color”: “#2ac1bc”,
"display": “standalone"
}
웹 앱의 정보를 설정합니다.
52. Web app manifest
EXAMPLE: manifest.json
{
"short_name": “My awesome App”, // 유저의 홈화면에서 보일 이름
"name": “My awesome App - for all airplane users”, // 유저가 배너에서 볼 이름
"icons": [ // 메인 화면에 추가하면 볼 이미지
{
"src": "launcher-icon-4x.png",
"type": "image/png",
"sizes": "192x192"
}
],
"start_url": “index.html?launcher=true”, // 유저의 웹사이트 접근점
“background_color”: “#2ac1bc”, // 앱 실행 시 배경 색상
“theme_color”: “#2ac1bc”, // 사이트 테마 색상
"display": “standalone"
}
웹 앱의 정보를 설정합니다.
53. Web app manifest
EXAMPLE: manifest.json
{
"short_name": “My awesome App”, // 유저의 홈화면에서 보일 이름
"name": “My awesome App - for all airplane users”, // 유저가 배너에서 볼 이름
"icons": [ // 메인 화면에 추가하면 볼 이미지
{
"src": "launcher-icon-4x.png",
"type": "image/png",
"sizes": "192x192"
}
],
"start_url": “index.html?launcher=true”, // 유저의 웹사이트 접근점
“background_color”: “#2ac1bc”, // 앱 실행 시 배경 색상
“theme_color”: “#2ac1bc”, // 사이트 테마 색상
"display": “standalone” // 브라우저의 UI 숨김여부
}
웹 앱의 정보를 설정합니다.