SlideShare a Scribd company logo
1 of 62
AMP & PWA
@techhtml
AMP
Accelerated Mobile Pages
AMP
Accelerated Mobile Pages
AMP
웹 페이지를 더 빠르게 렌더링하는 방법
AMP가 동작하는 원리
비동기 자바스크립트만 허용
모든 리소스 크기를 정적으로 지정
확장 메커니즘이 렌더링을 차단하지 않도록 함
모든 3P 자바스크립트를 주요 로딩 패스에서 제거
모든 CSS는 인라인이며 50KB까지 제한
효율적인 웹폰트 사용
스타일 재계산 최소화
GPU 가속 애니메이션만 사용 가능하게 함
리소스 로딩 우선순위를 지정
Preconnect API를 사용해 즉시 페이지를 로드
AMP가 동작하는 원리
비동기 자바스크립트만 허용
모든 리소스 크기를 정적으로 지정
확장 메커니즘이 렌더링을 차단하지 않도록 함
모든 3P 자바스크립트를 주요 로딩 패스에서 제거
모든 CSS는 인라인이며 50KB까지 제한
효율적인 웹폰트 사용
스타일 재계산 최소화
GPU 가속 애니메이션만 사용 가능하게 함
리소스 로딩 우선순위를 지정
Preconnect API를 사용해 즉시 페이지를 로드
모든 3P 자바스크립트를 주요 로딩 패스에서 제거
AMP는 3P 자바스크립트 실행을 iFrame 내부에서만 허용합니다.
iFrame 내부의 자바스크립트는 부모 페이지의 실행을 차단하지 않고,
스타일 재계산 및 레이아웃 계산이 iFrame 내부에서 일어나기 때문에,
부모 요소에 영향을 주지 않습니다
모든 CSS는 인라인이며 50KB로 제한합니다
CSS는 시간이 지날 수록 늘어나는 경향이 있고,

외부 CSS는 HTTP 요청을 여러번 하게 하여 네트워크 비용을 감수해야합니다.
따라서 AMP에서는 CSS를 인라인으로 넣고, 50KB로 제한합니다.
효율적인 웹폰트 사용
네트워크 이슈로 인해 웹 폰트의 지연 로딩이 발생하는데,
웹 폰트의 로딩이 지연되면 브라우저가 텍스트 렌더링을 위한 폰트 리소스가 무엇인 지 인식하기 전에,
렌더링 트리를 생성합니다.
효율적인 웹폰트 사용
따라서 폰트를 가져오는 과정이 다른 리소스 요청보다 훨씬 뒤로 지연되며,
브라우저에서 리소스를 가져오기 전까지 폰트가 렌더링되지 않을 수 있습니다.
애플 공식 홈페이지
아무것도 노출되고 있지 않다
스타일 재계산 최소화
스타일 재계산을 방지하기 위해 Vsync 클래스를 사용해 스타일 속성을 측정하고 변경하여,
재계산하는 과정을 최소화시킨다.
AMP HTML
Web Applications
EXAMPLE 1: Facebook Card
<div class=“card”>
<div class=“profile”>
{img}
{name}
{date} {privacy}
</div>
<div class=“contents”>
<p>
{hash}
{text}
</p>
<div class=“images”>
{img}
</div>
<div class=“modules”>
{Like}
{Comment}
{Share}
</div>
</div>
</div>
Custom Elements
Element Extends
DOM을 확장하여 새 HTML/DOM 요소를 만드는 스펙
DOM 상속구조
EXAMPLE 2: <div>
HTMLDivElement
HTMLElement
Element
Node
EventTarget
DIV요소의 DOM 상속구조
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 상속구조
DOM 확장
Example 3: Custom Elements Card
class Card from HTMLElement {
contructor() {
super();
// Inner Element Structure
}
}
customElements.define(‘Card’, Card);
<Card></Card>
DOM를 확장하여 새로운 Card 요소를 생성
AMP HTML Architecture
AMP HTML
AmpImg
> <amp-img> 요소를 위한 객체
BaseElement
> 모든 AMP HTML 요소의 근간을 이루어 AMP의 라이프사이클을 유지시키는 요소
<amp-img> 요소의 확장구조
AMP HTML
import {BaseElement} from ‘base-element’;
export class AmpImg extends BaseElement {
constructor(element) {
super(element);
}
// do Something
}
<amp-img> 요소의 확장구조
AMP HTML Lifecycle
State: <NOT BUILT> <NOT UPGRADED> <NOT ATTACHED>
State: <NOT BUILT> <NOT ATTACHED>
State: <NOT BUILT>
State: <Built>



State: <LAID OUT>
State: <IN VIEWPORT>
custom DOM 요소의 생존주기는 다음과 같다
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의 생존주기는 다음과 같다
PWA
Progressive Web App
일본에 여행을 가려고 합니다.
비행기 티켓을 끊기 위한 어플리케이션이 필요할까?
과도한 어플리케이션
어플리케이션을 만들 필요가 없는 일회성 서비스조차
어플리케이션으로 도배되고 있는 현실
다시 PWA
Web Application의 극대화
PWA를 시작하는
3가지 구성요소
> 서비스워커
> 웹 앱 메니페스트
> 웹 푸시 알림
서비스 워커
서비스 워커는 브라우저가 백그라운드에서 실행하는 스크립트입니다.
서비스 워커의 동작방식
서비스 워커의 라이프 사이클
서비스 워커 등록하기
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);
    });
  });
}
브라우저에서 서비스 워커를 지원하는 경우
서비스 워커 등록하기
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);
    });
  });
}
윈도우가 로딩되면
서비스 워커 등록하기
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);
    });
  });
}
서비스 워커를 등록한다
서비스 워커 등록하기
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);
    });
  });
}
브라우저에서 서비스 워커를 지원하는 경우 서비스 워커를 등록한다
서비스 워커 설치
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);
      })
  );
});
서비스 워커로 수행할 일들을 기록한다.
서비스 워커 설치
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);
      })
  );
});
캐시할 리소스들
서비스 워커 설치
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);
      })
  );
});
설치 이벤트가 발생하면
서비스 워커 설치
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);
      })
  );
});
캐시에 원하는 리소스를 저장한다.
요청 캐시 및 반환
self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // 캐시 확인 - 응답 반환
        if (response) {
          return response;
        }
        return fetch(event.request);
      }
    )
  );
});
서비스워커 설치 후 서비스워커 내 데이터 받기
서비스 워커
서비스 워커를 사용해 웹 사이트에서 자주 사용될 리소스를 캐싱하고,
백그라운드에서 스크립트를 실행시킬 수 있다.
웹 앱 매니페스트
이 웹 앱의 정보를 알려주는 Manifest 파일입니다.
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"
}
웹 앱의 정보를 설정합니다.
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"
}
웹 앱의 정보를 설정합니다.
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"
}
웹 앱의 정보를 설정합니다.
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"
}
웹 앱의 정보를 설정합니다.
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"
}
웹 앱의 정보를 설정합니다.
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 숨김여부
}
웹 앱의 정보를 설정합니다.
PWA 실행화면
{
“short_name”: “Air Honer”,
“name”: “TEST”,
“icons”: [{
// icon info
}],
“background_color”: “#2196F3”
}
Web app manifest
EXAMPLE: index.html
<link rel=“manifest” href=“/manifest.json”>
웹 앱의 정보를 설정합니다.
웹 푸시 알림
웹으로 제공하는 푸시알림
서버로부터 Push 발송
self.addEventListener('push', event => {
  event.waitUntil(
    // 이벤트를 동작시키고 알림을 보여줍니다.
  );
});
알림 보여주기
self.addEventListener('push', event => {
  event.waitUntil(
    self.registration.showNotification(title, {
    body: 'Are you free tonight?',
    icon: 'images/joe.png',
    vibrate: [200, 100, 200, 100, 200, 100, 400],
    tag: 'request',
    actions: [
      { action: 'yes', title: 'Yes!', icon: 'images/thumb-up.png' },
      { action: 'no', title: 'No', icon: 'images/thumb-down.png' }
    ]
  })
  );
});
여러분,
여러분이 기다리시던
분량조절실패가 드디어 나왔습니다.
코드 살펴보기
분량조절 성공하면 샤샥
NEXT?

AMP & PWA
> https://choumx.github.io/amp-pwa/
> https://goo.gl/sEH3Bo (같은 경로)
Q&A
Thank you
apes0123@gmail.com
@techhtml

More Related Content

Viewers also liked

안형우 - 유지보수하기 쉬운 CSS 전략 [WSConf. Seoul 2016/2017]
안형우 - 유지보수하기 쉬운 CSS 전략 [WSConf. Seoul 2016/2017]안형우 - 유지보수하기 쉬운 CSS 전략 [WSConf. Seoul 2016/2017]
안형우 - 유지보수하기 쉬운 CSS 전략 [WSConf. Seoul 2016/2017]WSConf.
 
윤원진 - 반응형웹디자인(RWD)을 위한 넓고 얕은 지식 [WSConf. Seoul 2016]
윤원진 - 반응형웹디자인(RWD)을 위한 넓고 얕은 지식 [WSConf. Seoul 2016]윤원진 - 반응형웹디자인(RWD)을 위한 넓고 얕은 지식 [WSConf. Seoul 2016]
윤원진 - 반응형웹디자인(RWD)을 위한 넓고 얕은 지식 [WSConf. Seoul 2016]WSConf.
 
배영 - CSS Animation 성능 이론과 실제 적용 사례 [WSConf.Seoul.2017. Vol.2]
배영 - CSS Animation 성능 이론과 실제 적용 사례 [WSConf.Seoul.2017. Vol.2]배영 - CSS Animation 성능 이론과 실제 적용 사례 [WSConf.Seoul.2017. Vol.2]
배영 - CSS Animation 성능 이론과 실제 적용 사례 [WSConf.Seoul.2017. Vol.2]WSConf.
 
지성봉 - HTML5 Document Outline [WSConf.Seoul.2017. Vol.2]
지성봉 - HTML5 Document Outline [WSConf.Seoul.2017. Vol.2]지성봉 - HTML5 Document Outline [WSConf.Seoul.2017. Vol.2]
지성봉 - HTML5 Document Outline [WSConf.Seoul.2017. Vol.2]WSConf.
 
정찬명 - CSS Flex you must konw [WSConf.Seoul.2017. Vol.2]
정찬명 - CSS Flex you must konw [WSConf.Seoul.2017. Vol.2]정찬명 - CSS Flex you must konw [WSConf.Seoul.2017. Vol.2]
정찬명 - CSS Flex you must konw [WSConf.Seoul.2017. Vol.2]WSConf.
 
정찬명 - CSS Selectors in HTML [WSConf. Seoul 2016/2017]
정찬명 - CSS Selectors in HTML [WSConf. Seoul 2016/2017]정찬명 - CSS Selectors in HTML [WSConf. Seoul 2016/2017]
정찬명 - CSS Selectors in HTML [WSConf. Seoul 2016/2017]WSConf.
 

Viewers also liked (6)

안형우 - 유지보수하기 쉬운 CSS 전략 [WSConf. Seoul 2016/2017]
안형우 - 유지보수하기 쉬운 CSS 전략 [WSConf. Seoul 2016/2017]안형우 - 유지보수하기 쉬운 CSS 전략 [WSConf. Seoul 2016/2017]
안형우 - 유지보수하기 쉬운 CSS 전략 [WSConf. Seoul 2016/2017]
 
윤원진 - 반응형웹디자인(RWD)을 위한 넓고 얕은 지식 [WSConf. Seoul 2016]
윤원진 - 반응형웹디자인(RWD)을 위한 넓고 얕은 지식 [WSConf. Seoul 2016]윤원진 - 반응형웹디자인(RWD)을 위한 넓고 얕은 지식 [WSConf. Seoul 2016]
윤원진 - 반응형웹디자인(RWD)을 위한 넓고 얕은 지식 [WSConf. Seoul 2016]
 
배영 - CSS Animation 성능 이론과 실제 적용 사례 [WSConf.Seoul.2017. Vol.2]
배영 - CSS Animation 성능 이론과 실제 적용 사례 [WSConf.Seoul.2017. Vol.2]배영 - CSS Animation 성능 이론과 실제 적용 사례 [WSConf.Seoul.2017. Vol.2]
배영 - CSS Animation 성능 이론과 실제 적용 사례 [WSConf.Seoul.2017. Vol.2]
 
지성봉 - HTML5 Document Outline [WSConf.Seoul.2017. Vol.2]
지성봉 - HTML5 Document Outline [WSConf.Seoul.2017. Vol.2]지성봉 - HTML5 Document Outline [WSConf.Seoul.2017. Vol.2]
지성봉 - HTML5 Document Outline [WSConf.Seoul.2017. Vol.2]
 
정찬명 - CSS Flex you must konw [WSConf.Seoul.2017. Vol.2]
정찬명 - CSS Flex you must konw [WSConf.Seoul.2017. Vol.2]정찬명 - CSS Flex you must konw [WSConf.Seoul.2017. Vol.2]
정찬명 - CSS Flex you must konw [WSConf.Seoul.2017. Vol.2]
 
정찬명 - CSS Selectors in HTML [WSConf. Seoul 2016/2017]
정찬명 - CSS Selectors in HTML [WSConf. Seoul 2016/2017]정찬명 - CSS Selectors in HTML [WSConf. Seoul 2016/2017]
정찬명 - CSS Selectors in HTML [WSConf. Seoul 2016/2017]
 

Similar to 조은 - AMP PWA 101 [WSConf.Seoul.2017. Vol.2]

Vue.js 기초 실습.pptx
Vue.js 기초 실습.pptxVue.js 기초 실습.pptx
Vue.js 기초 실습.pptxwonyong hwang
 
Progressive Web Apps
Progressive Web AppsProgressive Web Apps
Progressive Web Appsjungkees
 
알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web AnimationsChang W. Doh
 
다음 통합검색 로딩 속도 개선 삽질기
다음 통합검색 로딩 속도 개선 삽질기다음 통합검색 로딩 속도 개선 삽질기
다음 통합검색 로딩 속도 개선 삽질기정윤 김
 
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)LanarkSeung
 
자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기Jeado Ko
 
PWA 파헤치기
PWA 파헤치기PWA 파헤치기
PWA 파헤치기SangHun Lee
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs기동 이
 
Meteor React Tutorial 따라하기
Meteor React Tutorial 따라하기Meteor React Tutorial 따라하기
Meteor React Tutorial 따라하기Jiam Seo
 
Front-end Development Process - 어디까지 개선할 수 있나
Front-end Development Process - 어디까지 개선할 수 있나Front-end Development Process - 어디까지 개선할 수 있나
Front-end Development Process - 어디까지 개선할 수 있나JeongHun Byeon
 
Angularjs, ionic, cordova 기반 syrup store app 개발 사례 공유
Angularjs, ionic, cordova 기반 syrup store app 개발 사례 공유Angularjs, ionic, cordova 기반 syrup store app 개발 사례 공유
Angularjs, ionic, cordova 기반 syrup store app 개발 사례 공유Sang Seok Lim
 
20131217 html5
20131217 html520131217 html5
20131217 html5DK Lee
 
Dreamweaver CS5.5 를 이용한 jQueryMobile 개발
Dreamweaver CS5.5 를 이용한 jQueryMobile 개발Dreamweaver CS5.5 를 이용한 jQueryMobile 개발
Dreamweaver CS5.5 를 이용한 jQueryMobile 개발JongKwang Kim
 
하이브리드앱 성능 극복
하이브리드앱 성능 극복하이브리드앱 성능 극복
하이브리드앱 성능 극복sung hwan Park
 
하이브리드앱 성능 극복
하이브리드앱 성능 극복하이브리드앱 성능 극복
하이브리드앱 성능 극복Mu-ik Jeon
 
Polymer따라잡기
Polymer따라잡기Polymer따라잡기
Polymer따라잡기Han Jung Hyun
 
Express framework tutorial
Express framework tutorialExpress framework tutorial
Express framework tutorial우림 류
 

Similar to 조은 - AMP PWA 101 [WSConf.Seoul.2017. Vol.2] (20)

Vue.js 기초 실습.pptx
Vue.js 기초 실습.pptxVue.js 기초 실습.pptx
Vue.js 기초 실습.pptx
 
Progressive Web Apps
Progressive Web AppsProgressive Web Apps
Progressive Web Apps
 
알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations
 
다음 통합검색 로딩 속도 개선 삽질기
다음 통합검색 로딩 속도 개선 삽질기다음 통합검색 로딩 속도 개선 삽질기
다음 통합검색 로딩 속도 개선 삽질기
 
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
 
자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기자바스크립트 프레임워크 살펴보기
자바스크립트 프레임워크 살펴보기
 
PWA 파헤치기
PWA 파헤치기PWA 파헤치기
PWA 파헤치기
 
Nodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjsNodejs, PhantomJS, casperJs, YSlow, expressjs
Nodejs, PhantomJS, casperJs, YSlow, expressjs
 
Meteor React Tutorial 따라하기
Meteor React Tutorial 따라하기Meteor React Tutorial 따라하기
Meteor React Tutorial 따라하기
 
Front-end Development Process - 어디까지 개선할 수 있나
Front-end Development Process - 어디까지 개선할 수 있나Front-end Development Process - 어디까지 개선할 수 있나
Front-end Development Process - 어디까지 개선할 수 있나
 
Nodejs express
Nodejs expressNodejs express
Nodejs express
 
Angularjs, ionic, cordova 기반 syrup store app 개발 사례 공유
Angularjs, ionic, cordova 기반 syrup store app 개발 사례 공유Angularjs, ionic, cordova 기반 syrup store app 개발 사례 공유
Angularjs, ionic, cordova 기반 syrup store app 개발 사례 공유
 
20131217 html5
20131217 html520131217 html5
20131217 html5
 
What's new in IE11
What's new in IE11What's new in IE11
What's new in IE11
 
Dreamweaver CS5.5 를 이용한 jQueryMobile 개발
Dreamweaver CS5.5 를 이용한 jQueryMobile 개발Dreamweaver CS5.5 를 이용한 jQueryMobile 개발
Dreamweaver CS5.5 를 이용한 jQueryMobile 개발
 
하이브리드앱 성능 극복
하이브리드앱 성능 극복하이브리드앱 성능 극복
하이브리드앱 성능 극복
 
하이브리드앱 성능 극복
하이브리드앱 성능 극복하이브리드앱 성능 극복
하이브리드앱 성능 극복
 
요즘웹개발
요즘웹개발요즘웹개발
요즘웹개발
 
Polymer따라잡기
Polymer따라잡기Polymer따라잡기
Polymer따라잡기
 
Express framework tutorial
Express framework tutorialExpress framework tutorial
Express framework tutorial
 

조은 - AMP PWA 101 [WSConf.Seoul.2017. Vol.2]

  • 2.
  • 5. AMP 웹 페이지를 더 빠르게 렌더링하는 방법
  • 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. 효율적인 웹폰트 사용 따라서 폰트를 가져오는 과정이 다른 리소스 요청보다 훨씬 뒤로 지연되며, 브라우저에서 리소스를 가져오기 전까지 폰트가 렌더링되지 않을 수 있습니다.
  • 12. 애플 공식 홈페이지 아무것도 노출되고 있지 않다
  • 13.
  • 14. 스타일 재계산 최소화 스타일 재계산을 방지하기 위해 Vsync 클래스를 사용해 스타일 속성을 측정하고 변경하여, 재계산하는 과정을 최소화시킨다.
  • 17.
  • 18. EXAMPLE 1: Facebook Card <div class=“card”> <div class=“profile”> {img} {name} {date} {privacy} </div> <div class=“contents”> <p> {hash} {text} </p> <div class=“images”> {img} </div> <div class=“modules”> {Like} {Comment} {Share} </div> </div> </div>
  • 19.
  • 21. Element Extends DOM을 확장하여 새 HTML/DOM 요소를 만드는 스펙
  • 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 요소를 생성
  • 26. AMP HTML AmpImg > <amp-img> 요소를 위한 객체 BaseElement > 모든 AMP HTML 요소의 근간을 이루어 AMP의 라이프사이클을 유지시키는 요소 <amp-img> 요소의 확장구조
  • 27. AMP HTML import {BaseElement} from ‘base-element’; export class AmpImg extends BaseElement { constructor(element) { super(element); } // do Something } <amp-img> 요소의 확장구조
  • 28. AMP HTML Lifecycle State: <NOT BUILT> <NOT UPGRADED> <NOT ATTACHED> State: <NOT BUILT> <NOT ATTACHED> State: <NOT BUILT> State: <Built>
 
 State: <LAID OUT> State: <IN VIEWPORT> custom DOM 요소의 생존주기는 다음과 같다
  • 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의 생존주기는 다음과 같다
  • 31. 일본에 여행을 가려고 합니다. 비행기 티켓을 끊기 위한 어플리케이션이 필요할까?
  • 32. 과도한 어플리케이션 어플리케이션을 만들 필요가 없는 일회성 서비스조차 어플리케이션으로 도배되고 있는 현실
  • 34. PWA를 시작하는 3가지 구성요소 > 서비스워커 > 웹 앱 메니페스트 > 웹 푸시 알림
  • 35. 서비스 워커 서비스 워커는 브라우저가 백그라운드에서 실행하는 스크립트입니다.
  • 36. 서비스 워커의 동작방식 서비스 워커의 라이프 사이클
  • 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. 서비스 워커 서비스 워커를 사용해 웹 사이트에서 자주 사용될 리소스를 캐싱하고, 백그라운드에서 스크립트를 실행시킬 수 있다.
  • 47. 웹 앱 매니페스트 이 웹 앱의 정보를 알려주는 Manifest 파일입니다.
  • 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 숨김여부 } 웹 앱의 정보를 설정합니다.
  • 54. PWA 실행화면 { “short_name”: “Air Honer”, “name”: “TEST”, “icons”: [{ // icon info }], “background_color”: “#2196F3” }
  • 55. Web app manifest EXAMPLE: index.html <link rel=“manifest” href=“/manifest.json”> 웹 앱의 정보를 설정합니다.
  • 56. 웹 푸시 알림 웹으로 제공하는 푸시알림
  • 57. 서버로부터 Push 발송 self.addEventListener('push', event => {   event.waitUntil(     // 이벤트를 동작시키고 알림을 보여줍니다.   ); });
  • 58. 알림 보여주기 self.addEventListener('push', event => {   event.waitUntil(     self.registration.showNotification(title, {     body: 'Are you free tonight?',     icon: 'images/joe.png',     vibrate: [200, 100, 200, 100, 200, 100, 400],     tag: 'request',     actions: [       { action: 'yes', title: 'Yes!', icon: 'images/thumb-up.png' },       { action: 'no', title: 'No', icon: 'images/thumb-down.png' }     ]   })   ); });
  • 59. 여러분, 여러분이 기다리시던 분량조절실패가 드디어 나왔습니다. 코드 살펴보기 분량조절 성공하면 샤샥
  • 60. NEXT?
 AMP & PWA > https://choumx.github.io/amp-pwa/ > https://goo.gl/sEH3Bo (같은 경로)
  • 61. Q&A