Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Getting Into HNPWA with Vue.js at Google I/O 2017 Extended in ICN, Korea

Getting Into HNPWA with Vue.js at Google I/O 2017 Extended in ICN, Korea

Presentation at Google I/O 2017 Extended in ICN, Korea

Jimmy Moon

June 11, 2017
Tweet

More Decks by Jimmy Moon

Other Decks in Programming

Transcript

  1. GETTING INTO

    View full-size slide

  2. Hacker News ?
    is a social news website focusing on computer science and
    entrepreneurship. running by y combinator, Paul Graham, that have
    many of clones

    View full-size slide

  3. CHECKPOINT
    Progressive Web App
    All of views (Top, New, Best ...)
    Display 30 items per-page for story list views
    90/100 score from Lighthouse
    First Interactive in under 5s via webpagetest(w/ TTI score of LH)

    View full-size slide

  4. AND MORE ...
    Manual inspection of app's timeline (by addy osmani)
    Application Shell pattern (mandatory)
    Best to work cross-browser (optional)
    Supports offline caching of HN data (optional)
    Server-side rendering (optional)

    View full-size slide

  5. JAVASCRIPT FRAMEWORKS

    View full-size slide

  6. React Vue.js Preact Polymer
    CLI for PWA yarn react‑app vue init pwa preact create polymer init
    Service Worker
    Code‑Splitting
    HTML Import
    Preloaded / Prefeched
    SSR

    View full-size slide

  7. PREPARATION
    > npm install -g vue-cli

    View full-size slide

  8. SCAFFOLDING
    > vue init pwa vue-hn-pwa && cd $_ && yarn install

    View full-size slide

  9. FIRST LOOK
    > yarn build && yarn start

    View full-size slide

  10. STORY VIEW
    > yarn add firebase-hackernews

    View full-size slide

  11. Fetch top story
    h
    a
    c
    k
    e
    r
    n
    e
    w
    s
    (
    )
    .
    s
    t
    o
    r
    i
    e
    s
    (
    '
    t
    o
    p
    '
    )
    .
    t
    h
    e
    n
    (
    i
    t
    e
    m
    s =
    > { t
    h
    i
    s
    .
    i
    t
    e
    m
    s = i
    t
    e
    m
    s }
    )

    View full-size slide

  12. MORE VIEWS
    Toolbar, Comment and User profile

    View full-size slide

  13. SERVICE WORKER

    View full-size slide

  14. SWPrecacheWebpackPlugin
    n
    e
    w S
    W
    P
    r
    e
    c
    a
    c
    h
    e
    W
    e
    b
    p
    a
    c
    k
    P
    l
    u
    g
    i
    n
    (
    {
    c
    a
    c
    h
    e
    I
    d
    : '
    m
    y
    -
    v
    u
    e
    -
    a
    p
    p
    '
    ,
    s
    t
    a
    t
    i
    c
    F
    i
    l
    e
    G
    l
    o
    b
    s
    : [
    '
    d
    i
    s
    t
    /
    *
    *
    /
    *
    .
    {
    j
    s
    ,
    h
    t
    m
    l
    ,
    c
    s
    s
    ,
    p
    n
    g
    ,
    s
    v
    g
    ,
    j
    s
    o
    n
    }
    '
    ]
    ,
    .
    .
    .
    r
    u
    n
    t
    i
    m
    e
    C
    a
    c
    h
    i
    n
    g
    : [
    {
    u
    r
    l
    P
    a
    t
    t
    e
    r
    n
    : '
    /
    '
    ,
    h
    a
    n
    d
    l
    e
    r
    : '
    n
    e
    t
    w
    o
    r
    k
    F
    i
    r
    s
    t
    '
    }
    , {
    u
    r
    l
    P
    a
    t
    t
    e
    r
    n
    : /
    \
    /
    (
    t
    o
    p
    |
    n
    e
    w
    |
    s
    h
    o
    w
    |
    a
    s
    k
    |
    j
    o
    b
    s
    )
    /
    ,
    h
    a
    n
    d
    l
    e
    r
    : '
    n
    e
    t
    w
    o
    r
    k
    F
    i
    r
    s
    t
    '
    }
    ]
    }
    )

    View full-size slide

  15. Workbox example
    i
    m
    p
    o
    r
    t
    S
    c
    r
    i
    p
    t
    s
    (
    '
    h
    t
    t
    p
    s
    :
    /
    /
    u
    n
    p
    k
    g
    .
    c
    o
    m
    /
    w
    o
    r
    k
    b
    o
    x
    -
    s
    w
    @
    0
    .
    0
    .
    2
    '
    )
    c
    o
    n
    s
    t w
    o
    r
    k
    b
    o
    x
    S
    W = n
    e
    w W
    o
    r
    k
    b
    o
    x
    S
    W
    (
    {
    c
    l
    i
    e
    n
    t
    s
    C
    l
    a
    i
    m
    : t
    r
    u
    e
    }
    )
    w
    o
    r
    k
    b
    o
    x
    S
    W
    .
    p
    r
    e
    c
    a
    c
    h
    e
    (
    [
    ]
    )
    w
    o
    r
    k
    b
    o
    x
    S
    W
    .
    r
    o
    u
    t
    e
    r
    .
    s
    e
    t
    D
    e
    f
    a
    u
    l
    t
    H
    a
    n
    d
    l
    e
    r
    (
    {
    h
    a
    n
    d
    l
    e
    r
    : w
    o
    r
    k
    b
    o
    x
    S
    W
    .
    s
    t
    r
    a
    t
    e
    g
    i
    e
    s
    .
    s
    t
    a
    l
    e
    W
    h
    i
    l
    e
    R
    e
    v
    a
    l
    i
    d
    a
    t
    e
    (
    )
    }
    )

    View full-size slide

  16. SERVER SIDE RENDERING

    View full-size slide

  17. SERVER SIDE RENDERING
    > yarn add vue-server-renderer

    View full-size slide

  18. rendering sample standalone
    c
    o
    n
    s
    t r
    e
    n
    d
    e
    r
    e
    r = r
    e
    q
    u
    i
    r
    e
    (
    '
    v
    u
    e
    -
    s
    e
    r
    v
    e
    r
    -
    r
    e
    n
    d
    e
    r
    e
    r
    '
    )
    .
    c
    r
    e
    a
    t
    e
    R
    e
    n
    d
    e
    r
    e
    r
    (
    )
    r
    e
    n
    d
    e
    r
    e
    r
    .
    r
    e
    n
    d
    e
    r
    T
    o
    S
    t
    r
    i
    n
    g
    (
    a
    p
    p
    , (
    e
    r
    r
    , h
    t
    m
    l
    ) =
    > {
    i
    f (
    e
    r
    r
    ) t
    h
    r
    o
    w e
    r
    r
    c
    o
    n
    s
    o
    l
    e
    .
    l
    o
    g
    (
    h
    t
    m
    l
    )
    /
    / =
    > <
    d
    i
    v d
    a
    t
    a
    -
    s
    e
    r
    v
    e
    r
    -
    r
    e
    n
    d
    e
    r
    e
    d
    =
    "
    t
    r
    u
    e
    "
    >
    /
    / =
    > h
    e
    l
    l
    o w
    o
    r
    l
    d
    /
    / =
    > <
    /
    d
    i
    v
    >
    }
    )

    View full-size slide

  19. SERVER SIDE RENDERING
    > npm install express --save

    View full-size slide

  20. rendering sample with express
    c
    o
    n
    s
    t s
    e
    r
    v
    e
    r = r
    e
    q
    u
    i
    r
    e
    (
    '
    e
    x
    p
    r
    e
    s
    s
    '
    )
    (
    )
    c
    o
    n
    s
    t r
    e
    n
    d
    e
    r
    e
    r = r
    e
    q
    u
    i
    r
    e
    (
    '
    v
    u
    e
    -
    s
    e
    r
    v
    e
    r
    -
    r
    e
    n
    d
    e
    r
    e
    r
    '
    )
    .
    c
    r
    e
    a
    t
    e
    R
    e
    n
    d
    e
    r
    e
    r
    (
    )
    s
    e
    r
    v
    e
    r
    .
    g
    e
    t
    (
    '
    *
    '
    , (
    r
    e
    q
    , r
    e
    s
    ) =
    > {
    r
    e
    n
    d
    e
    r
    e
    r
    .
    r
    e
    n
    d
    e
    r
    T
    o
    S
    t
    r
    i
    n
    g
    (
    a
    p
    p
    , (
    e
    r
    r
    , h
    t
    m
    l
    ) =
    > {
    .
    .
    .
    r
    e
    s
    .
    e
    n
    d
    (
    `
    .
    .
    .
    <
    b
    o
    d
    y
    >
    $
    {
    h
    t
    m
    l
    }
    <
    /
    b
    o
    d
    y
    >
    .
    .
    .
    `
    )
    }
    )
    }
    )

    View full-size slide

  21. SERVER SIDE RENDERING
    Page Template

    View full-size slide

  22. index.template.html
    <
    !
    D
    O
    C
    T
    Y
    P
    E h
    t
    m
    l
    >
    <
    h
    t
    m
    l l
    a
    n
    g
    =
    "
    e
    n
    "
    >
    <
    h
    e
    a
    d
    >
    <
    t
    i
    t
    l
    e
    >
    H
    e
    l
    l
    o
    <
    /
    t
    i
    t
    l
    e
    >
    <
    /
    h
    e
    a
    d
    >
    <
    b
    o
    d
    y
    >
    <
    !
    -
    -
    v
    u
    e
    -
    s
    s
    r
    -
    o
    u
    t
    l
    e
    t
    -
    -
    >
    <
    /
    b
    o
    d
    y
    >
    <
    /
    h
    t
    m
    l
    >

    View full-size slide

  23. renderer with template
    c
    o
    n
    s
    t r
    e
    n
    d
    e
    r
    e
    r = c
    r
    e
    a
    t
    e
    R
    e
    n
    d
    e
    r
    e
    r
    (
    {
    t
    e
    m
    p
    l
    a
    t
    e
    : r
    e
    q
    u
    i
    r
    e
    (
    '
    f
    s
    '
    )
    .
    r
    e
    a
    d
    F
    i
    l
    e
    S
    y
    n
    c
    (
    '
    .
    /
    i
    n
    d
    e
    x
    .
    t
    e
    m
    p
    l
    a
    t
    e
    .
    h
    t
    m
    l
    '
    , '
    u
    t
    f
    -
    8
    '
    )
    }
    )
    r
    e
    n
    d
    e
    r
    e
    r
    .
    r
    e
    n
    d
    e
    r
    T
    o
    S
    t
    r
    i
    n
    g
    (
    a
    p
    p
    , (
    e
    r
    r
    , h
    t
    m
    l
    ) =
    > {
    /
    / w
    i
    l
    l b
    e t
    h
    e f
    u
    l
    l p
    a
    g
    e w
    i
    t
    h a
    p
    p c
    o
    n
    t
    e
    n
    t i
    n
    j
    e
    c
    t
    e
    d
    c
    o
    n
    s
    o
    l
    e
    .
    l
    o
    g
    (
    h
    t
    m
    l
    )
    }
    )

    View full-size slide

  24. SERVER SIDE RENDERING
    Universal Code

    View full-size slide

  25. s
    r
    c


    ─ c
    o
    m
    p
    o
    n
    e
    n
    t
    s
    │ ├

    ─ F
    o
    o
    .
    v
    u
    e
    │ ├

    ─ B
    a
    r
    .
    v
    u
    e
    │ └

    ─ B
    a
    z
    .
    v
    u
    e


    ─ A
    p
    p
    .
    v
    u
    e


    ─ a
    p
    p
    .
    j
    s # u
    n
    i
    v
    e
    r
    s
    a
    l e
    n
    t
    r
    y


    ─ e
    n
    t
    r
    y
    -
    c
    l
    i
    e
    n
    t
    .
    j
    s # r
    u
    n
    s i
    n b
    r
    o
    w
    s
    e
    r o
    n
    l
    y


    ─ e
    n
    t
    r
    y
    -
    s
    e
    r
    v
    e
    r
    .
    j
    s # r
    u
    n
    s o
    n s
    e
    r
    v
    e
    r o
    n
    l
    y

    View full-size slide

  26. app.js, universal entry
    i
    m
    p
    o
    r
    t V
    u
    e f
    r
    o
    m '
    v
    u
    e
    '
    i
    m
    p
    o
    r
    t A
    p
    p f
    r
    o
    m '
    .
    /
    A
    p
    p
    .
    v
    u
    e
    '
    e
    x
    p
    o
    r
    t f
    u
    n
    c
    t
    i
    o
    n c
    r
    e
    a
    t
    e
    A
    p
    p (
    ) {
    c
    o
    n
    s
    t a
    p
    p = n
    e
    w V
    u
    e
    (
    {
    r
    e
    n
    d
    e
    r
    : h =
    > h
    (
    A
    p
    p
    )
    }
    )
    r
    e
    t
    u
    r
    n { a
    p
    p }
    }

    View full-size slide

  27. entry-client.js
    i
    m
    p
    o
    r
    t { c
    r
    e
    a
    t
    e
    A
    p
    p } f
    r
    o
    m '
    .
    /
    a
    p
    p
    '
    c
    o
    n
    s
    t { a
    p
    p } = c
    r
    e
    a
    t
    e
    A
    p
    p
    (
    )
    /
    / m
    o
    u
    n
    t
    i
    n
    g o
    f v
    u
    e i
    s
    n
    t
    a
    n
    c
    e
    a
    p
    p
    .
    $
    m
    o
    u
    n
    t
    (
    '
    #
    a
    p
    p
    '
    )

    View full-size slide

  28. entry-server.js:
    i
    m
    p
    o
    r
    t { c
    r
    e
    a
    t
    e
    A
    p
    p } f
    r
    o
    m '
    .
    /
    a
    p
    p
    '
    /
    / w
    i
    t
    h
    o
    u
    t m
    o
    u
    n
    t
    i
    n
    g o
    f v
    u
    e i
    s
    n
    t
    a
    n
    c
    e
    e
    x
    p
    o
    r
    t d
    e
    f
    a
    u
    l
    t c
    o
    n
    t
    e
    x
    t =
    > {
    c
    o
    n
    s
    t { a
    p
    p } = c
    r
    e
    a
    t
    e
    A
    p
    p
    (
    )
    r
    e
    t
    u
    r
    n a
    p
    p
    }

    View full-size slide

  29. server.js
    c
    o
    n
    s
    t c
    r
    e
    a
    t
    e
    A
    p
    p = r
    e
    q
    u
    i
    r
    e
    (
    '
    .
    /
    a
    p
    p
    '
    )
    s
    e
    r
    v
    e
    r
    .
    g
    e
    t
    (
    '
    *
    '
    , (
    r
    e
    q
    , r
    e
    s
    ) =
    > {
    c
    o
    n
    s
    t a
    p
    p = c
    r
    e
    a
    t
    e
    A
    p
    p
    (
    )
    r
    e
    n
    d
    e
    r
    e
    r
    .
    r
    e
    n
    d
    e
    r
    T
    o
    S
    t
    r
    i
    n
    g
    (
    a
    p
    p
    , (
    e
    r
    r
    , h
    t
    m
    l
    ) =
    > {
    /
    / h
    a
    n
    d
    l
    e e
    r
    r
    o
    r
    .
    .
    .
    r
    e
    s
    .
    e
    n
    d
    (
    h
    t
    m
    l
    )
    }
    )
    }
    )

    View full-size slide

  30. webpack.client.conf.js
    v
    a
    r w
    e
    b
    p
    a
    c
    k
    C
    o
    n
    f
    i
    g = m
    e
    r
    g
    e
    (
    b
    a
    s
    e
    W
    e
    b
    p
    a
    c
    k
    C
    o
    n
    f
    i
    g
    , {
    e
    n
    t
    r
    y
    : {
    a
    p
    p
    : '
    .
    /
    s
    r
    c
    /
    e
    n
    t
    r
    y
    -
    c
    l
    i
    e
    n
    t
    .
    j
    s
    '
    }
    .
    .
    .
    }
    )

    View full-size slide

  31. webpack.server.conf.js
    v
    a
    r w
    e
    b
    p
    a
    c
    k
    C
    o
    n
    f
    i
    g = m
    e
    r
    g
    e
    (
    b
    a
    s
    e
    W
    e
    b
    p
    a
    c
    k
    C
    o
    n
    f
    i
    g
    , {
    e
    n
    t
    r
    y
    : {
    a
    p
    p
    : '
    .
    /
    s
    r
    c
    /
    e
    n
    t
    r
    y
    -
    s
    e
    r
    v
    e
    r
    .
    j
    s
    '
    }
    .
    .
    .
    }
    )

    View full-size slide

  32. SERVER SIDE RENDERING
    Routing on Server

    View full-size slide

  33. router.js, export generator
    i
    m
    p
    o
    r
    t R
    o
    u
    t
    e
    r f
    r
    o
    m '
    v
    u
    e
    -
    r
    o
    u
    t
    e
    r
    '
    V
    u
    e
    .
    u
    s
    e
    (
    R
    o
    u
    t
    e
    r
    )
    e
    x
    p
    o
    r
    t f
    u
    n
    c
    t
    i
    o
    n c
    r
    e
    a
    t
    e
    R
    o
    u
    t
    e
    r (
    ) {
    r
    e
    t
    u
    r
    n n
    e
    w R
    o
    u
    t
    e
    r
    (
    {
    m
    o
    d
    e
    : '
    h
    i
    s
    t
    o
    r
    y
    '
    ,
    r
    o
    u
    t
    e
    s
    : [
    /
    / .
    .
    .
    ]
    }
    )
    }

    View full-size slide

  34. app.js, create routing
    e
    x
    p
    o
    r
    t f
    u
    n
    c
    t
    i
    o
    n c
    r
    e
    a
    t
    e
    A
    p
    p (
    ) {
    c
    o
    n
    s
    t r
    o
    u
    t
    e
    r = c
    r
    e
    a
    t
    e
    R
    o
    u
    t
    e
    r
    (
    )
    c
    o
    n
    s
    t a
    p
    p = n
    e
    w V
    u
    e
    (
    {
    r
    o
    u
    t
    e
    r
    ,
    r
    e
    n
    d
    e
    r
    : h =
    > h
    (
    A
    p
    p
    )
    }
    )
    r
    e
    t
    u
    r
    n { a
    p
    p
    , r
    o
    u
    t
    e
    r }
    }

    View full-size slide

  35. entry-server.js, matched components
    e
    x
    p
    o
    r
    t d
    e
    f
    a
    u
    l
    t c
    o
    n
    t
    e
    x
    t =
    > {
    r
    e
    t
    u
    r
    n n
    e
    w P
    r
    o
    m
    i
    s
    e
    (
    (
    r
    e
    s
    o
    l
    v
    e
    , r
    e
    j
    e
    c
    t
    ) =
    > {
    c
    o
    n
    s
    t { a
    p
    p
    , r
    o
    u
    t
    e
    r } = c
    r
    e
    a
    t
    e
    A
    p
    p
    (
    )
    r
    o
    u
    t
    e
    r
    .
    p
    u
    s
    h
    (
    c
    o
    n
    t
    e
    x
    t
    .
    u
    r
    l
    ) /
    / f
    r
    o
    m s
    e
    r
    v
    e
    r
    .
    j
    s
    r
    o
    u
    t
    e
    r
    .
    o
    n
    R
    e
    a
    d
    y
    (
    (
    ) =
    > {
    i
    f (
    r
    o
    u
    t
    e
    r
    .
    g
    e
    t
    M
    a
    t
    c
    h
    e
    d
    C
    o
    m
    p
    o
    n
    e
    n
    t
    s
    (
    )
    .
    l
    e
    n
    g
    t
    h > 0
    ) {
    r
    e
    s
    o
    l
    v
    e
    (
    a
    p
    p
    )
    }
    }
    , r
    e
    j
    e
    c
    t
    )
    }
    )
    }

    View full-size slide

  36. server.js, context with pass url
    s
    e
    r
    v
    e
    r
    .
    g
    e
    t
    (
    '
    *
    '
    , (
    r
    e
    q
    , r
    e
    s
    ) =
    > {
    c
    o
    n
    s
    t c
    o
    n
    t
    e
    x
    t = { u
    r
    l
    : r
    e
    q
    .
    u
    r
    l }
    c
    r
    e
    a
    t
    e
    A
    p
    p
    (
    c
    o
    n
    t
    e
    x
    t
    )
    .
    t
    h
    e
    n
    (
    a
    p
    p =
    > {
    r
    e
    n
    d
    e
    r
    e
    r
    .
    r
    e
    n
    d
    e
    r
    T
    o
    S
    t
    r
    i
    n
    g
    (
    a
    p
    p
    , (
    e
    r
    r
    , h
    t
    m
    l
    ) =
    > {
    .
    .
    .
    r
    e
    s
    .
    e
    n
    d
    (
    h
    t
    m
    l
    )
    }
    }
    )
    }
    )

    View full-size slide

  37. SERVER SIDE RENDERING
    Data Pre-Fetching and Hydration

    View full-size slide

  38. vue-hn-mixin.js, sharing data interface
    f
    u
    n
    c
    t
    i
    o
    n i
    n
    s
    t
    a
    l
    l (
    V
    u
    e
    ) {
    V
    u
    e
    .
    m
    i
    x
    i
    n
    (
    {
    b
    e
    f
    o
    r
    e
    C
    r
    e
    a
    t
    e (
    ) {
    c
    o
    n
    s
    t { p
    a
    r
    e
    n
    t
    , h
    n } = t
    h
    i
    s
    .
    $
    o
    p
    t
    i
    o
    n
    s
    i
    f (
    h
    n
    ) {
    t
    h
    i
    s
    .
    $
    h
    n = h
    n
    } e
    l
    s
    e i
    f (
    p
    a
    r
    e
    n
    t &
    & p
    a
    r
    e
    n
    t
    .
    $
    h
    n
    ) {
    t
    h
    i
    s
    .
    $
    h
    n = p
    a
    r
    e
    n
    t
    .
    $
    h
    n
    }
    }
    }
    )
    }

    View full-size slide

  39. app.js, create routing
    i
    m
    p
    o
    r
    t H
    a
    c
    k
    e
    r
    n
    e
    w
    s f
    r
    o
    m '
    .
    /
    m
    i
    x
    i
    n
    s
    /
    v
    u
    e
    -
    h
    n
    -
    m
    i
    x
    i
    n
    '
    V
    u
    e
    .
    u
    s
    e
    (
    H
    a
    c
    k
    e
    r
    n
    e
    w
    s
    )
    e
    x
    p
    o
    r
    t f
    u
    n
    c
    t
    i
    o
    n c
    r
    e
    a
    t
    e
    A
    p
    p (
    ) {
    .
    .
    .
    c
    o
    n
    s
    t h
    n = h
    a
    c
    k
    e
    r
    n
    e
    w
    s
    (
    )
    c
    o
    n
    s
    t a
    p
    p = n
    e
    w V
    u
    e
    (
    {
    .
    .
    .
    h
    n
    }
    )
    r
    e
    t
    u
    r
    n { a
    p
    p
    , r
    o
    u
    t
    e
    r
    , h
    n }
    }

    View full-size slide

  40. router.js, set class method
    f
    u
    n
    c
    t
    i
    o
    n c
    r
    e
    a
    t
    e
    S
    t
    o
    r
    y (
    t
    y
    p
    e
    ) {
    r
    e
    t
    u
    r
    n {
    .
    .
    .
    a
    s
    y
    n
    c
    D
    a
    t
    a (
    { h
    n
    , r
    o
    u
    t
    e }
    ) {
    r
    e
    t
    u
    r
    n h
    n
    .
    s
    t
    o
    r
    i
    e
    s
    (
    t
    y
    p
    e
    , {
    p
    a
    g
    e
    : N
    u
    m
    b
    e
    r
    (
    r
    o
    u
    t
    e
    .
    p
    a
    r
    a
    m
    s
    .
    p
    a
    g
    e |
    | 1
    )
    }
    )
    }
    .
    .
    .
    }
    }

    View full-size slide

  41. entry-server.js, call class method
    r
    e
    t
    u
    r
    n n
    e
    w P
    r
    o
    m
    i
    s
    e
    (
    (
    r
    e
    s
    o
    l
    v
    e
    , r
    e
    j
    e
    c
    t
    ) =
    > {
    c
    o
    n
    s
    t { a
    p
    p
    , r
    o
    u
    t
    e
    r
    , h
    n } = c
    r
    e
    a
    t
    e
    A
    p
    p
    (
    )
    r
    o
    u
    t
    e
    r
    .
    p
    u
    s
    h
    (
    c
    o
    n
    t
    e
    x
    t
    .
    u
    r
    l
    ) /
    / f
    r
    o
    m s
    e
    r
    v
    e
    r
    .
    j
    s
    .
    .
    .
    r
    o
    u
    t
    e
    r
    .
    o
    n
    R
    e
    a
    d
    y
    (
    (
    ) =
    > {
    .
    .
    C
    o
    m
    p
    o
    n
    e
    n
    t
    .
    a
    s
    y
    n
    c
    D
    a
    t
    a
    (
    { h
    n
    ,
    r
    o
    u
    t
    e
    : r
    o
    u
    t
    e
    r
    .
    c
    u
    r
    r
    e
    n
    t
    R
    o
    u
    t
    e }
    )
    }
    )
    .
    t
    h
    e
    n
    (
    (
    ) =
    > {
    /
    / f
    l
    u
    s
    h d
    a
    t
    a f
    o
    r h
    y
    d
    r
    a
    t
    i
    o
    n o
    n c
    l
    i
    n
    e
    t
    c
    o
    n
    t
    e
    x
    t
    .
    s
    t
    a
    t
    e = h
    n
    .
    d
    a
    t
    a
    C
    a
    c
    h
    e
    d
    (
    )
    }
    )
    }
    )

    View full-size slide

  42. entry-client.js, call calss methond
    V
    u
    e
    .
    m
    i
    x
    i
    n
    (
    {
    b
    e
    f
    o
    r
    e
    R
    o
    u
    t
    e
    U
    p
    d
    a
    t
    e (
    t
    o
    , f
    r
    o
    m
    , n
    e
    x
    t
    ) {
    c
    o
    n
    s
    t { a
    s
    y
    n
    c
    D
    a
    t
    a } = t
    h
    i
    s
    .
    $
    o
    p
    t
    i
    o
    n
    s
    i
    f (
    a
    s
    y
    n
    c
    D
    a
    t
    a
    ) {
    a
    s
    y
    n
    c
    D
    a
    t
    a
    (
    { h
    n
    , r
    o
    u
    t
    e
    : t
    o }
    )
    .
    t
    h
    e
    n
    (
    n
    e
    x
    t
    )
    .
    c
    a
    t
    c
    h
    (
    n
    e
    x
    t
    )
    } e
    l
    s
    e {
    n
    e
    x
    t
    (
    )
    }
    }
    }
    )

    View full-size slide

  43. entry-client.js, hydration
    c
    o
    n
    s
    t { a
    p
    p
    , r
    o
    u
    t
    e
    r
    , h
    n } = c
    r
    e
    a
    t
    e
    A
    p
    p
    (
    )
    /
    / h
    y
    d
    r
    a
    t
    i
    n
    g i
    n
    i
    t
    i
    a
    l s
    t
    a
    t
    e i
    n
    t
    o g
    l
    o
    b
    a
    l o
    b
    j
    e
    c
    t o
    n c
    l
    i
    e
    n
    t
    i
    f (
    w
    i
    n
    d
    o
    w
    .
    _
    _
    I
    N
    I
    T
    I
    A
    L
    _
    S
    T
    A
    T
    E
    _
    _
    ) {
    h
    n
    .
    d
    a
    t
    a
    C
    a
    c
    h
    e
    d
    (
    w
    i
    n
    d
    o
    w
    .
    _
    _
    I
    N
    I
    T
    I
    A
    L
    _
    S
    T
    A
    T
    E
    _
    _
    )
    }

    View full-size slide

  44. OPTIMIZATION
    For First interactive time in 5s

    View full-size slide

  45. CODE-SPLITTING
    Reduce download time, Push critical path resource by preload / prefetch

    View full-size slide

  46. LIVE-CODE IMPORTING
    aka, Dead code elimination

    View full-size slide

  47. webpack-bundle-analyzer

    View full-size slide

  48. Include only the features you need
    - `
    i
    m
    p
    o
    r
    t f
    i
    r
    e
    b
    a
    s
    e f
    r
    o
    m '
    f
    i
    r
    e
    b
    a
    s
    e
    '
    + i
    m
    p
    o
    r
    t f
    i
    r
    e
    b
    a
    s
    e f
    r
    o
    m '
    f
    i
    r
    e
    b
    a
    s
    e
    /
    a
    p
    p
    '
    + i
    m
    p
    o
    r
    t '
    f
    i
    r
    e
    b
    a
    s
    e
    /
    d
    a
    t
    a
    b
    a
    s
    e
    '

    View full-size slide

  49. ragingwind/firebase-hackernews/es
    c
    o
    n
    s
    t f
    i
    r
    e
    b
    a
    s
    e = r
    e
    q
    u
    i
    r
    e
    (
    '
    f
    i
    r
    e
    b
    a
    s
    e
    /
    a
    p
    p
    '
    )
    c
    o
    n
    s
    t _ = r
    e
    q
    u
    i
    r
    e
    (
    '
    f
    i
    r
    e
    b
    a
    s
    e
    /
    d
    a
    t
    a
    b
    a
    s
    e
    '
    )
    ;

    View full-size slide

  50. webpack.client.conf.js
    r
    e
    s
    o
    l
    v
    e
    : {
    a
    l
    i
    a
    s
    : {
    '
    f
    i
    r
    e
    b
    a
    s
    e
    -
    h
    a
    c
    k
    e
    r
    n
    e
    w
    s
    '
    : '
    f
    i
    r
    e
    b
    a
    s
    e
    -
    h
    a
    c
    k
    e
    r
    n
    e
    w
    s
    /
    e
    s
    '
    }
    }

    View full-size slide

  51. AND MORE
    Lazy / Async Components
    Extracting Common Chunks
    Ultra Lightweight Frameworks
    Using the Platform

    View full-size slide

  52. AUDIT
    Lighthouse

    View full-size slide

  53. DEPLOYMENT
    Shipping your app on the live server

    View full-size slide

  54. Firebase
    /
    / i
    n
    s
    t
    a
    l
    l f
    i
    r
    e
    b
    a
    s
    e t
    o
    o
    l
    n
    p
    m i
    n
    s
    t
    a
    l
    l -
    g f
    i
    r
    e
    b
    a
    s
    e
    -
    t
    o
    o
    l
    s
    /
    / l
    o
    g
    i
    n i
    n
    t
    o f
    i
    r
    e
    b
    a
    s
    e v
    i
    a f
    i
    r
    e
    b
    a
    s
    e c
    l
    i t
    o
    o
    l
    f
    i
    r
    e
    b
    a
    s
    e l
    o
    g
    i
    n
    /
    / i
    n
    i
    t p
    r
    o
    j
    e
    c
    t
    f
    i
    r
    e
    b
    a
    s
    e i
    n
    i
    t
    /
    / d
    e
    p
    l
    o
    y
    f
    i
    r
    e
    b
    a
    s
    e d
    e
    p
    l
    o
    y -
    -
    o
    n
    l
    y h
    o
    s
    t
    i
    n
    g

    View full-size slide

  55. Web Page Test
    aka, WBT

    View full-size slide

  56. Thanks
    Go make it and submit

    View full-size slide