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

Universal JavaScript

Jerry Hong
October 22, 2016

Universal JavaScript

2016 JSDC Topic: Universal JavaScript

Jerry Hong

October 22, 2016
Tweet

More Decks by Jerry Hong

Other Decks in Technology

Transcript

  1. Universal JavaScript ?
    肬禂 SOHO
    ෟ螲᪠螂 ၒݷ蜤(Jerry-Hong)

    View Slide

  2. Ջ讕ฎ Universal JavaScript ?

    View Slide

  3. Universal JavaScript
    • ኧ Isomorphic JavaScript Ӟ扃ᘒ㬵
    • Isomorphic JavaScript 墋㻌藯ฎ ಩ Single Page Application و
    ݶ᪒ࣁ Client 现 Server Ӥ牧㬵薹究 SPA 癲㬵ጱ皃㮆㺔氂牐
    • Universal JavaScript 蚤 Isomorphic JavaScript 磪Ջ讕癩獨牫
    • ஑ض藳藳 Single Page Application

    View Slide

  4. Single Page Application (SPA)
    • አ䜛誢涢 (User Experience)
    • 翕殷䛑አ纷ୗ玕
    • 橕棎ਁ物 AJAX, Client-Side Render, Client-Side Router
    • ֺৼ物 Gmail, kkbox web player

    View Slide

  5. Server-rendered Server-rendered + AJAX SPA
    Load Performance
    Dev Effort
    User Experence
    From: How instagram.com Works

    View Slide

  6. 匍ࣁ獮ᒒૡ纷䒍᮷ᥝٍ猋 SPA ጱ樄咳妿涢

    View Slide

  7. 螭䷱樄咳螂 SPA 䌕礯牧皃㮆ଉ憎ጱܻࢩ

    View Slide

  8. 1. 襑穩犋ᒧ
    嘦䋿礓犚觊ࣳጱ䌕礯犋螕ݳ

    View Slide

  9. 2. 獮ᒒದ蔩虋矦ॡ盠牧
    犋Ꭳ螇ᥝ䋊ߺӞॺ牦

    View Slide

  10. 䋿褬Ӥ匍ࣁ
    獮ᒒ໛礍ጱݶ搡玕纷ଶ᩼㬵᩼ṛ牦

    View Slide

  11. • زկ玕

    View Slide

  12. class MyTitle extends Component {
    render() {
    return (
    Hello World
    );
    }
    }
    React زկ

    View Slide

  13. Vue.component('my-title', {
    render(h) {
    return (
    Hello World
    );
    }
    })
    Vue 2 زկ(JSX)

    View Slide

  14. Vue.component('my-title', {
    template: 'Hello World'
    })
    Vue 2 زկ

    View Slide

  15. @Component({
    selector: 'my-title',
    template: 'Hello World'
    })
    class MyTitle { }
    NG 2 زկ

    View Slide

  16. • زկ玕
    • 㻌ݻ虻碘窕
    • Flux
    • Redux
    • Vuex
    • CSS class scope
    • CSS module
    • web component
    • vue style scpoed
    • View 䍅羷ጱು虡玕
    • Server-Side Render
    • Native app

    View Slide

  17. • زկ玕
    • 㻌ݻ虻碘窕
    • Flux
    • Redux
    • Vuex
    • CSS Class Scope
    • CSS module
    • web component
    • vue style scpoed
    • View 䍅羷ጱು虡玕
    • Server-Side Render
    • Native app

    View Slide

  18. • زկ玕
    • 㻌ݻ虻碘窕
    • Flux
    • Redux
    • Vuex
    • CSS class scope
    • CSS module
    • web component
    • vue style scpoed
    • View 䍅羷ጱು虡玕
    • Server-Side Render
    • Native app
    .
    .
    .

    View Slide

  19. ྯॺአጱ薪盢犋䨝癩盄ग़牧疰೴㮆ࡅ稭ጱމ
    2. 獮ᒒದ蔩虋矦ॡ盠牧犋Ꭳ螇ᥝ䋊
    ߺӞॺ牦

    View Slide

  20. 3. SEO 㺔氂
    Universal JavaScript
    4. First Time Loading

    View Slide

  21. Universal JavaScript
    - 犥 React / Redux 傶ֺ

    View Slide

  22. च๜禊盢
    • SPA ᑏ༙ک Server Ӥ吚狶 Template Engine 䁆ᤈ
    • ಩ SPA మ猟౮Ӟ㮆य़ Function (F)

    View Slide

  23. F(n)

    View Slide

  24. F(n) => HTML

    View Slide

  25. च๜禊盢
    • SPA ᑏ༙ک Server Ӥ䁆ᤈ牧Client 蚤 Server 䨝وአ蟂獤ጱ纷ୗ嘨
    • ಩獮ᒒ໛礍మ猟౮Ӟ㮆 Function (F)
    • Ӟ㮆 request 蝱㬵䁆ᤈӞ稞 F 簁盅ࢧ㯽 HTML
    • ᒫӞ稞 request ԏ盅牧Client ᒒᤈ傶膏 SPA Ӟ膌

    View Slide

  26. ই֜಩ SPA 硬౮ Universal JS?
    Բ㮆ྍ詽

    View Slide

  27. View Slide

  28. View Slide

  29. View Slide

  30. View Slide

  31. View Slide

  32. ࢩ傶犋ݢ胼奞拻牧ಅ犥᯿讨硯ࣁ
    • य़膌ጱྍ詽 (1~ 5)
    • ଉ蝽憎ጱ㺔氂
    • 斃֯ጱ薹究ොဩ

    View Slide

  33. 樄咳 Universal JS - Բ㮆ྍ詽

    View Slide

  34. Step 1. 蒂ቘ Router

    View Slide

  35. app
    .use(compress())
    .use(serve('./static')))
    .use(router.routes())
    .use(serverRender)
    .use(errorBoot)
    .listen(process.env.PORT || 8080,
    () => {
    console.log('listen 3000')
    });
    Step 1 - 蒂ቘ Router
    • Server Router 䛑ض蒂ቘ
    覌眲䲆礯现 API

    View Slide

  36. app
    .use(compress())
    .use(serve('./static')))
    .use(router.routes())
    .use(serverRender)
    .use(errorBoot)
    .listen(process.env.PORT || 8080,
    () => {
    console.log('listen 3000')
    });
    Step 1 - 蒂ቘ Router
    • Server Router 䛑ض蒂ቘ
    覌眲䲆礯现 API
    • ٚ蝱獈 Server Render

    View Slide

  37. const store = createStore();
    const childRoutes = createRoute(store);
    match({
    routes: childRoutes,
    location: ctx.request.url
    }, (error, redirectLocation, renderProps) => {
    if (error) { // 500 }
    else if (redirectLocation) { // 300 }
    else if (renderProps) {
    const component = (



    );
    const content = ReactDOMServer.renderToString(component);
    ctx.response.type = 'text/html';
    ctx.body = ` ... ${content}...

    View Slide

  38. app
    .use(compress())
    .use(serve('./static')))
    .use(router.routes())
    .use(serverRender)
    .use(errorBoot)
    .listen(process.env.PORT || 8080,
    () => {
    console.log('listen 3000')
    });
    Step 1 - 蒂ቘ Router
    • Server Router 䛑ض蒂ቘ
    覌眲䲆礯现 API
    • ٚ蝱獈 Server Render
    • 磧盅狶梊藮蒂ቘ

    View Slide

  39. Step 2. 蒂ቘ AJAX 㺔氂
    • SPA ጱ礍䯤牧౯㮉䨝ࣁزկኞ޸蝰๗ ComponentDidMount 咳 AJAX
    • Server Render ݝ䨝䁆ᤈ ComponentWillMount 蚤 Render
    • Server Render ஠殾嘦狒 AJAX Response ಍䁆ᤈ Render

    View Slide

  40. Step 2. 蒂ቘ AJAX 㺔氂
    • 薹究ොဩҁ䢔Ӟ҂
    • ࣁ Server Render 獮瞟ڊྯ㮆殷ᶎزկጱ覌眲痀௔
    • redux-async-connect
    • async-props
    • ڥአ React-Router ጱ onEnter 痀௔咳 API (വ萃)
    • 硬አ universal-router

    View Slide

  41. @fetchData((dispatch, state, routeState, replace) => {
    return dispatch(getAllArticle());
    })
    class Home extends Component {
    ...
    }
    // fetchData(...)(Home)

    View Slide


  42. path="/"
    component={ Home }
    onEnter={ Home.onEnter(store) }/>

    View Slide

  43. // fetchData.js
    export default fetchCall => Component => {
    Component.onEnter = (store) =>
    (nextState, replace, callback) => {
    const result = fetchCall(
    store.dispatch,
    store.getState(),
    nextState,
    replace) || Promise.resolve(true);
    if(typeof window === 'undefined') {
    result.then(() => callback())
    .catch((error) => callback(error))
    } else {
    callback();
    }
    }
    return Component;
    }

    View Slide

  44. Step 3. 蒂ቘ虻碘ݶྍ㺔氂
    • 吚౯㮉 Server Render ਠ牧HTML 㯽ࢧ倵薩瑊牧倵薩瑊䁆ᤈਠ JS 䨝
    ࣁ Client Render Ӟ稞牧֕種碻 Client ䷱磪ਠ碉虻碘牧䨝蝨౮ Render
    犋Ӟ膌

    View Slide

  45. Step 3. 蒂ቘ虻碘ݶྍ㺔氂
    • 薹究ොဩ
    • Server Render 碻牧಩虻碘लک HTML
    • Client Render ԏ獮牧玲ڊ虻碘֢傶䛑አ纷ୗጱ ڡত制眲
    (initialState)

    View Slide

  46. const store = createStore();
    const childRoutes = createRoute(store);
    match({
    routes: childRoutes,
    location: ctx.request.url
    }, (error, redirectLocation, renderProps) => {
    ...
    ctx.body = ` ... ${content}...
    <br/>window.reduxState = ${JSON.stringify(store.getState())
<br/>

    View Slide

  47. Step 4. 蒂ቘ 覌眲䲆礯秇奲 㺔氂
    • 樄咳 SPA ֵአ webpack 碻牧䨝಩覌眲䲆礯吚֢ JS ጱ秇奲ֵአ
    • css-loader
    • url-loader
    • NodeJS ䷱旰ဩ斉獈蝡犚䲆礯

    View Slide

  48. Step 4. 蒂ቘ 覌眲䲆礯秇奲 㺔氂
    • 薹究ොဩҁ䢔Ӟ҂
    • አ webpack bundle server code (വ萃)
    • 硯祌ࣁ js Ӿ斉獈瑽䲆
    • 瑽䲆ፗ矑妔᪠䕩
    • CSS Module物 ے獈 css-modules-require-hook

    View Slide

  49. var nodeExternals =
    require('webpack-node-externals');
    ...
    module.exports = {
    ...
    target: 'node',
    externals: [nodeExternals()]
    ...
    };
    Step 4 - Bundle node
    • 戔ਧ target 傶 node
    • ے獈 webpack-node-
    externals
    hint:ᥝ戔ਧ context 痀௔

    View Slide

  50. Step 5. 戔ਧ 絑ह虋碍
    • ࢩ傶纷ୗ嘨ݶ碻᪒ࣁ Server 蚤 Client牧ࣁ蒂ቘ礓犚㺔氂碻襑ᥝ狅ᆙಅ
    ࣁ絑ह狶犋ݶ蒂ቘ
    • 蝚螂 webpack 戔ਧ絑ह虋碍

    View Slide

  51. new webpack.DefinePlugin({
    'process.env.BROWSER': true
    }))
    new webpack.DefinePlugin({
    'process.env.BROWSER': false
    }))
    webpack-server.config.js webpack.config.js

    View Slide

  52. 狅ᆙ蝡Բ㮆ྍ詽牧疰ݢ犥ਠ౮

    च๜ጱ Universal JavaScript 䌕礯

    View Slide

  53. 狶ԧ蝡讕ग़Ԫ眐牧疰傶ԧ薹究 

    SEO 蚤 First Time Loading 独஑㻟牫

    View Slide

  54. ٌ䋿 Universal JavaScript ฎ
    愆᪃ԧ盅ᒒ MVC ጱ View

    View Slide

  55. ๅঅጱزկ੗蕕
    • 盅ᒒ MVC View ጱزկ੗蕕㺔氂
    • 盅ᒒ樄咳Ո㹓䌕ဳࣁ虻碘牧盄櫞ဳ఺ک HTML 奾䯤
    • Universal JavaScript
    • 蚤 Client SPA وአ View牧ᤩ䔶蝁狶অزկ獥獹

    View Slide

  56. Critical Render Path

    View Slide

  57. View Slide

  58. View Slide

  59. View Slide

  60. CSS Critical Render Path
    • 傶 CSS 㯽蝑蝱ᤈ磧֯玕蒂ቘ
    • 疥吚獮殷ᶎአکጱ Style 硯ک head牧㪔皤螛斉獈碉۱ CSS
    • 㯽翄ጱ㵕眲翕ᒊӞፗ᮷䷱磪盄অጱ薹究ො礯
    • Universal JavaScript 斕誫薹究

    View Slide

  61. Universal JavaScript 薹究ොဩ
    • 䟖አ isomorphic-style-loader
    • ࣁ Render 獮硩褸๜殷ᶎጱ style 㪔लک head
    for react-router: https://goo.gl/PYYoLL

    View Slide

  62. View Slide

  63. View Slide

  64. View Slide

  65. 磧盅...

    View Slide

  66. ̽CSS Secret̾ጱ֢ᘏ Lea Verou ࣁ我藳
    Ӿ൉现牧ই֜፡盃 CSS in JS ?
    我藳蝫奾物http://www.ituring.com.cn/article/261344

    View Slide

  67. – Lea Verou, CSS Secret ֢ᘏ
    ̿If all you have is a hammer, everything looks like a nail.̀

    View Slide

  68. ෎腭瑿藯牧Lea Verou 梊ԧ

    View Slide

  69. 㪔犋ฎࢩ傶

    ౯㮉磪Ӟ಩袊ৼ牧ಅ犥፡Ջ讕᮷猟朸ৼ

    View Slide

  70. ᘒฎ JavaScript 胼狶کጱԪ眐ॡग़ԧ
    猟ฎӞݣ́ 3D 玢蔭秚͂

    View Slide

  71. ᘒ HTML 蚤 CSS
    疰ฎ蝡ݣ 3D 玢蔭秚ጱᔰ๭

    View Slide

  72. 猟ฎ౯㮉獮ᶎ൉ጱ CSS-Module

    View Slide

  73. 螭磪 React-Native 犖ฎ㮆盄অጱֺৼ

    View Slide

  74. 盅㬵౯㮉妔ԧ蝡ݣ 3D 玢蔭秚Ӟ㮆ݷਁ

    View Slide

  75. Universal JavaScript

    View Slide

  76. 眤蘛肔肯牧Q&A

    View Slide