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 Slide

  2. View Slide

  3. View Slide

  4. View Slide

  5. View Slide

  6. View Slide

  7. 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 Slide

  8. View Slide

  9. View Slide

  10. View Slide

  11. 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 Slide

  12. 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 Slide

  13. JAVASCRIPT FRAMEWORKS

    View Slide

  14. View Slide

  15. View Slide

  16. 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 Slide

  17. Vue.js

    View Slide

  18. PREPARATION
    > npm install -g vue-cli

    View Slide

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

    View Slide

  20. FIRST LOOK
    > yarn build && yarn start

    View Slide

  21. STORY VIEW
    > yarn add firebase-hackernews

    View Slide

  22. View Slide

  23. 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 Slide

  24. MORE VIEWS
    Toolbar, Comment and User profile

    View Slide

  25. SERVICE WORKER

    View Slide

  26. 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 Slide

  27. View Slide

  28. 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 Slide

  29. SERVER SIDE RENDERING

    View Slide

  30. View Slide

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

    View Slide

  32. 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 Slide

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

    View Slide

  34. 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 Slide

  35. SERVER SIDE RENDERING
    Page Template

    View Slide

  36. 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 Slide

  37. 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 Slide

  38. SERVER SIDE RENDERING
    Universal Code

    View Slide

  39. 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 Slide

  40. 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 Slide

  41. 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 Slide

  42. 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 Slide

  43. 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 Slide

  44. 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 Slide

  45. 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 Slide

  46. SERVER SIDE RENDERING
    Routing on Server

    View Slide

  47. 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 Slide

  48. 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 Slide

  49. 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 Slide

  50. 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 Slide

  51. SERVER SIDE RENDERING
    Data Pre-Fetching and Hydration

    View Slide

  52. 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 Slide

  53. 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 Slide

  54. 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 Slide

  55. 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 Slide

  56. 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 Slide

  57. 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 Slide

  58. View Slide

  59. View Slide

  60. View Slide

  61. View Slide

  62. OPTIMIZATION
    For First interactive time in 5s

    View Slide

  63. View Slide

  64. View Slide

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

    View Slide

  66. View Slide

  67. View Slide

  68. View Slide

  69. View Slide

  70. View Slide

  71. LIVE-CODE IMPORTING
    aka, Dead code elimination

    View Slide

  72. webpack-bundle-analyzer

    View Slide

  73. View Slide

  74. 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 Slide

  75. 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 Slide

  76. 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 Slide

  77. View Slide

  78. View Slide

  79. View Slide

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

    View Slide

  81. View Slide

  82. AUDIT
    Lighthouse

    View Slide

  83. DEPLOYMENT
    Shipping your app on the live server

    View Slide

  84. 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 Slide

  85. View Slide

  86. Web Page Test
    aka, WBT

    View Slide

  87. View Slide

  88. View Slide

  89. View Slide

  90. Thanks
    Go make it and submit

    View Slide