Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Universal JavaScript
Search
Jerry Hong
October 22, 2016
Technology
2
600
Universal JavaScript
2016 JSDC Topic: Universal JavaScript
Jerry Hong
October 22, 2016
Tweet
Share
More Decks by Jerry Hong
See All by Jerry Hong
從 Functional Programming 的角度看 2021 的 TypeScript
s6323859
2
4.3k
RxJS - The Art of Abstraction
s6323859
5
2.5k
Abstract Thinking - 從 Functional Programming 看見程式之美
s6323859
4
2.6k
RxJS - 封裝程式的藝術
s6323859
0
1.5k
如何「畫圖」寫測試 - RxJS Marble Testing
s6323859
0
1k
Other Decks in Technology
See All in Technology
プロダクト価値を引き上げる、「課題の再定義」という習慣
moeka__c
0
210
extensionとschema
yahonda
1
100
プロダクト観点で考えるデータ基盤の育成戦略 / Growth Strategy of Data Analytics Platforms from a Product Perspective
yamamotoyuta
0
200
20250129 Findy_テスト高活用化
dshirae
0
230
Tech Blog執筆のモチベート向上作戦
imamura_ko_0314
0
740
Redshiftを中心としたAWSでのデータ基盤
mashiike
0
100
Server Side Swift 実践レポート: 2024年に案件で採用して見えた課題と可能性
yusuga
1
420
2025/1/29 BigData-JAWS 勉強会 #28 (re:Invent 2024 re:Cap)/new-feature-preview-q-in-quicksight-scenarios-tried-and-tested
emiki
0
310
DevSecOps入門:Security Development Lifecycleによる開発プロセスのセキュリティ強化
yuriemori
0
230
BLEAでAWSアカウントのセキュリティレベルを向上させよう
koheiyoshikawa
0
130
マルチデータプロダクト開発・運用に耐えるためのデータ組織・アーキテクチャの遷移
mtpooh
0
100
例外処理を理解して、設計段階からエラーを「見つけやすく」「起こりにくく」する
kajitack
12
3.7k
Featured
See All Featured
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Code Review Best Practice
trishagee
65
17k
Being A Developer After 40
akosma
89
590k
How GitHub (no longer) Works
holman
312
140k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.3k
Done Done
chrislema
182
16k
Building Applications with DynamoDB
mza
93
6.2k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
It's Worth the Effort
3n
184
28k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
45
2.3k
Fireside Chat
paigeccino
34
3.2k
Embracing the Ebb and Flow
colly
84
4.5k
Transcript
Universal JavaScript ? 肬禂 SOHO ෟ螲᪠螂 ၒݷ蜤(Jerry-Hong)
Ջ讕ฎ Universal JavaScript ?
Universal JavaScript • ኧ Isomorphic JavaScript Ӟ扃ᘒ㬵 • Isomorphic JavaScript
墋㻌藯ฎ Single Page Application و ݶ᪒ࣁ Client 现 Server Ӥ牧㬵薹究 SPA 癲㬵ጱ皃㮆㺔氂牐 • Universal JavaScript 蚤 Isomorphic JavaScript 磪Ջ讕癩獨牫 • ض藳藳 Single Page Application
Single Page Application (SPA) • አ䜛誢涢 (User Experience) • 翕殷䛑አ纷ୗ玕
• 橕棎ਁ物 AJAX, Client-Side Render, Client-Side Router • ֺৼ物 Gmail, kkbox web player
Server-rendered Server-rendered + AJAX SPA Load Performance Dev Effort User
Experence From: How instagram.com Works
匍ࣁ獮ᒒૡ纷䒍᮷ᥝٍ猋 SPA ጱ樄咳妿涢
螭䷱樄咳螂 SPA 䌕礯牧皃㮆ଉ憎ጱܻࢩ
1. 襑穩犋ᒧ 嘦䋿礓犚觊ࣳጱ䌕礯犋螕ݳ
2. 獮ᒒದ蔩虋矦ॡ盠牧 犋Ꭳ螇ᥝ䋊ߺӞॺ牦
䋿褬Ӥ匍ࣁ 獮ᒒ礍ጱݶ搡玕纷ଶ᩼㬵᩼ṛ牦
• زկ玕
class MyTitle extends Component { render() { return ( <h1>Hello
World</h1> ); } } React زկ
Vue.component('my-title', { render(h) { return ( <h1>Hello World</h1> ); }
}) Vue 2 زկ(JSX)
Vue.component('my-title', { template: '<h1>Hello World</h1>' }) Vue 2 زկ
@Component({ selector: 'my-title', template: '<h1>Hello World</h1>' }) class MyTitle {
} NG 2 زկ
• زկ玕 • 㻌ݻ虻碘窕 • Flux • Redux • Vuex
• CSS class scope • CSS module • web component • vue style scpoed • View 䍅羷ጱು虡玕 • Server-Side Render • Native app
• زկ玕 • 㻌ݻ虻碘窕 • Flux • Redux • Vuex
• CSS Class Scope • CSS module • web component • vue style scpoed • View 䍅羷ጱು虡玕 • Server-Side Render • Native app
• زկ玕 • 㻌ݻ虻碘窕 • Flux • Redux • Vuex
• CSS class scope • CSS module • web component • vue style scpoed • View 䍅羷ጱು虡玕 • Server-Side Render • Native app . . .
ྯॺአጱ薪盢犋䨝癩盄ग़牧疰㮆ࡅ稭ጱމ 2. 獮ᒒದ蔩虋矦ॡ盠牧犋Ꭳ螇ᥝ䋊 ߺӞॺ牦
3. SEO 㺔氂 Universal JavaScript 4. First Time Loading
Universal JavaScript - 犥 React / Redux 傶ֺ
च禊盢 • SPA ᑏ༙ک Server Ӥ吚狶 Template Engine 䁆ᤈ •
SPA మ猟౮Ӟ㮆य़ Function (F)
F(n)
F(n) => HTML
च禊盢 • SPA ᑏ༙ک Server Ӥ䁆ᤈ牧Client 蚤 Server 䨝وአ蟂獤ጱ纷ୗ嘨 •
獮ᒒ礍మ猟౮Ӟ㮆 Function (F) • Ӟ㮆 request 蝱㬵䁆ᤈӞ稞 F 簁盅ࢧ㯽 HTML • ᒫӞ稞 request ԏ盅牧Client ᒒᤈ傶膏 SPA Ӟ膌
ই֜ SPA 硬౮ Universal JS? Բ㮆ྍ詽
None
None
None
None
None
ࢩ傶犋ݢ胼奞拻牧ಅ犥᯿讨硯ࣁ • य़膌ጱྍ詽 (1~ 5) • ଉ蝽憎ጱ㺔氂 • 斃֯ጱ薹究ොဩ
樄咳 Universal JS - Բ㮆ྍ詽
Step 1. 蒂ቘ Router
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
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
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 = ( <Provider store={ store }> <RouterContext { ...renderProps }/> </Provider> ); const content = ReactDOMServer.renderToString(component); ctx.response.type = 'text/html'; ctx.body = `<!DOCTYPE html> ... ${content}...</html>` } });
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 • 磧盅狶梊藮蒂ቘ
Step 2. 蒂ቘ AJAX 㺔氂 • SPA ጱ礍䯤牧౯㮉䨝ࣁزկኞ蝰๗ ComponentDidMount 咳
AJAX • Server Render ݝ䨝䁆ᤈ ComponentWillMount 蚤 Render • Server Render 殾嘦狒 AJAX Response 䁆ᤈ Render
Step 2. 蒂ቘ AJAX 㺔氂 • 薹究ොဩҁ䢔Ӟ҂ • ࣁ Server
Render 獮瞟ڊྯ㮆殷ᶎزկጱ覌眲痀 • redux-async-connect • async-props • ڥአ React-Router ጱ onEnter 痀咳 API (വ萃) • 硬አ universal-router
@fetchData((dispatch, state, routeState, replace) => { return dispatch(getAllArticle()); }) class
Home extends Component { ... } // fetchData(...)(Home)
<Route component={ App }> <Route path="/" component={ Home } onEnter={
Home.onEnter(store) }/> </Route>
// 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; }
Step 3. 蒂ቘ虻碘ݶྍ㺔氂 • 吚౯㮉 Server Render ਠ牧HTML 㯽ࢧ倵薩瑊牧倵薩瑊䁆ᤈਠ JS
䨝 ࣁ Client Render Ӟ稞牧֕種碻 Client ䷱磪ਠ碉虻碘牧䨝蝨౮ Render 犋Ӟ膌
Step 3. 蒂ቘ虻碘ݶྍ㺔氂 • 薹究ොဩ • Server Render 碻牧虻碘लک HTML
• Client Render ԏ獮牧玲ڊ虻碘֢傶䛑አ纷ୗጱ ڡত制眲 (initialState)
const store = createStore(); const childRoutes = createRoute(store); match({ routes:
childRoutes, location: ctx.request.url }, (error, redirectLocation, renderProps) => { ... ctx.body = `<!DOCTYPE html> ... ${content}... <script> window.reduxState = ${JSON.stringify(store.getState()) </script> </html>` });
Step 4. 蒂ቘ 覌眲䲆礯秇奲 㺔氂 • 樄咳 SPA ֵአ webpack
碻牧䨝覌眲䲆礯吚֢ JS ጱ秇奲ֵአ • css-loader • url-loader • NodeJS ䷱旰ဩ斉獈蝡犚䲆礯
Step 4. 蒂ቘ 覌眲䲆礯秇奲 㺔氂 • 薹究ොဩҁ䢔Ӟ҂ • አ webpack
bundle server code (വ萃) • 硯祌ࣁ js Ӿ斉獈瑽䲆 • 瑽䲆ፗ矑妔᪠䕩 • CSS Module物 ے獈 css-modules-require-hook
var nodeExternals = require('webpack-node-externals'); ... module.exports = { ... target:
'node', externals: [nodeExternals()] ... }; Step 4 - Bundle node • 戔ਧ target 傶 node • ے獈 webpack-node- externals hint:ᥝ戔ਧ context 痀
Step 5. 戔ਧ 絑ह虋碍 • ࢩ傶纷ୗ嘨ݶ碻᪒ࣁ Server 蚤 Client牧ࣁ蒂ቘ礓犚㺔氂碻襑ᥝ狅ᆙಅ ࣁ絑ह狶犋ݶ蒂ቘ
• 蝚螂 webpack 戔ਧ絑ह虋碍
new webpack.DefinePlugin({ 'process.env.BROWSER': true })) new webpack.DefinePlugin({ 'process.env.BROWSER': false }))
webpack-server.config.js webpack.config.js
狅ᆙ蝡Բ㮆ྍ詽牧疰ݢ犥ਠ౮ चጱ Universal JavaScript 䌕礯
狶ԧ蝡讕ग़Ԫ眐牧疰傶ԧ薹究 SEO 蚤 First Time Loading 独㻟牫
ٌ䋿 Universal JavaScript ฎ 愆᪃ԧ盅ᒒ MVC ጱ View
ๅঅጱزկ蕕 • 盅ᒒ MVC View ጱزկ蕕㺔氂 • 盅ᒒ樄咳Ո㹓䌕ဳࣁ虻碘牧盄櫞ဳک HTML 奾䯤
• Universal JavaScript • 蚤 Client SPA وአ View牧ᤩ䔶蝁狶অزկ獥獹
Critical Render Path
None
None
None
CSS Critical Render Path • 傶 CSS 㯽蝑蝱ᤈ磧֯玕蒂ቘ • 疥吚獮殷ᶎአکጱ
Style 硯ک head牧㪔皤螛斉獈碉۱ CSS • 㯽翄ጱ㵕眲翕ᒊӞፗ᮷䷱磪盄অጱ薹究ො礯 • Universal JavaScript 斕誫薹究
Universal JavaScript 薹究ොဩ • 䟖አ isomorphic-style-loader • ࣁ Render 獮硩褸殷ᶎጱ
style 㪔लک head for react-router: https://goo.gl/PYYoLL
None
None
None
磧盅...
̽CSS Secret̾ጱ֢ᘏ Lea Verou ࣁ我藳 Ӿ现牧ই֜፡盃 CSS in JS ?
我藳蝫奾物http://www.ituring.com.cn/article/261344
– Lea Verou, CSS Secret ֢ᘏ ̿If all you have
is a hammer, everything looks like a nail.̀
腭瑿藯牧Lea Verou 梊ԧ
㪔犋ฎࢩ傶 ౯㮉磪Ӟ袊ৼ牧ಅ犥፡Ջ讕᮷猟朸ৼ
ᘒฎ JavaScript 胼狶کጱԪ眐ॡग़ԧ 猟ฎӞݣ́ 3D 玢蔭秚͂
ᘒ HTML 蚤 CSS 疰ฎ蝡ݣ 3D 玢蔭秚ጱᔰ
猟ฎ౯㮉獮ᶎጱ CSS-Module
螭磪 React-Native 犖ฎ㮆盄অጱֺৼ
盅㬵౯㮉妔ԧ蝡ݣ 3D 玢蔭秚Ӟ㮆ݷਁ
Universal JavaScript
眤蘛肔肯牧Q&A