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 and Progressive Web Apps with ReactJS
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Mike Bild
November 26, 2017
Programming
53
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Universal and Progressive Web Apps with ReactJS
Mike Bild
November 26, 2017
More Decks by Mike Bild
See All by Mike Bild
Introduction Data-Apps with Python
mikebild
0
100
Python & Pandas in a Nutshell
mikebild
0
260
Data Management with GraphQL
mikebild
2
150
Functions-as-a-Service with Linklet
mikebild
2
330
Other Decks in Programming
See All in Programming
過去最大のMCPアップデート! 2026-07-28 RC版の謎に迫る
licux
6
280
Snowflake Summitでの新機能 CoCo / CoWork / snowflake-summit-2026-overall-what-new-coco
tatsuhiro
1
120
Signal Forms: Beyond the Basics @ngBaguette 2026 in Paris
manfredsteyer
PRO
0
240
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
230
net-httpのHTTP/2対応について
naruse
0
480
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
120
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
120
キャリア迷子上等 ─ "ない道"は自分で作ればいい
16bitidol
3
2k
JavaDoc 再入門
nagise
0
330
並列実装の現場、2ヶ月間実務でAIを使い倒したAIもPCも私も限界が近い
ming_ayami
0
130
Creating Composable Callables in Contemporary C++
rollbear
0
110
CSC307 Lecture 17
javiergs
PRO
0
320
Featured
See All Featured
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
120k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
2
850
Reality Check: Gamification 10 Years Later
codingconduct
0
2.2k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.8k
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
62
54k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
1.7k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
610
Test your architecture with Archunit
thirion
1
2.3k
Typedesign – Prime Four
hannesfritz
42
3.1k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
What's in a price? How to price your products and services
michaelherold
247
13k
エンジニアに許された特別な時間の終わり
watany
107
250k
Transcript
REACT JS UNIVERSAL WEB APP
UNIVERSAL WEB APP + REACTJS TODAY ▸ Web-Development ▸ Universal
Web Apps + ReactJS ▸ Demo ▸ Resources ▸ Bonus
UNIVERSAL WEB APP + REACTJS DECADES OF WEB-DEVELOPMENT ▸ Server
Side Rendering ▸ Single Page Apps ▸ Universal Web Apps ▸ Progressive Web Apps ▸ Demo
UNIVERSAL WEB APP + REACTJS SERVER-SIDE-RENDERING (CLASSIC) ▸ Facebook, GitHub
etc. - great success stories ▸ Perl / PHP / Rails & more MVC Frameworks ▸ Many Round-Trips ▸ Mixed Code & Structure
UNIVERSAL WEB APP + REACTJS SINGLE PAGE APP (CLIENT RENDERING)
Empty index.html <script src> </script> JS React execution Page interaction
UNIVERSAL WEB APP + REACTJS SPA - RECAP ▸ SEO
▸ Routing ▸ JavaScript / Web Security ▸ Initial data fetching ++ - - ▸ Logged in User Context ▸ Static WebSite Deployment ▸ Scalability
UNIVERSAL WEB APP + REACTJS UNIVERSAL WEB APP (SERVER +
CLIENT RENDERING) SSR <script src> </script> JS React execution Page interaction
UNIVERSAL WEB APP + REACTJS UWA - RECAP ▸ Slower
Time To First Byte ▸ Server Runtime ▸ Scalability ++ - - ▸ Logged out User Context ▸ Rendered earlier ▸ Less page flicker ▸ JavaScript / Web Security
UNIVERSAL WEB APP + REACTJS NEXT? PROGRESSIVE WEB APPLICATIONS ▸
HTTPS + Service-Worker ▸ Faster content more reliable (prefetch, cache, offline) ▸ Environment integration (Homescreen, Push-Notifications) ▸ Tooling (Googles Lighthouse) ▸ Browsers?
UNIVERSAL WEB APP + REACTJS @REACT16 + SERVER SIDE RENDERER
▸ Simplified and more Efficient ▸ ReactDOM.hydrate - no checksum markup validation ▸ ReactDOM.renderToNodeStream - async Renderer
UNIVERSAL WEB APP + REACTJS UWA FLOW Shared JavaScript /
ES6 / ES7 ReactJS Component ./dist/client.js WebPack.Client.Config NodeJS router.get(/, …) {renderToString} from 'react-dom/server' index.html WebPack.Server.Config {renderToNodeStream} from 'react-dom/server' @REACT15 / @REACT16
UNIVERSAL WEB APP + REACTJS NEXT? PROGRESSIVE WEB APPLICATIONS PREFETCH
RESOURCES CACHE ASSETS OFFLINE ACCESS PUSH NOTIFICATIONS
UNIVERSAL WEB APP + REACTJS RESOURCE PREFETCH + CACHE ASSETS
var CACHE_NAME = 'pwa-cache-v__TIMESTAMP__'; self.addEventListener('activate', event => { var cacheWhitelist = [CACHE_NAME]; event.waitUntil( caches.keys().then(keyList => Promise.all( keyList.map(key => { if (!cacheWhitelist.includes(key)) { console.log(`Deleting cache: ${key}`); return caches.delete(key); } }) ) ) ); }); self.addEventListener('install', event => { event.waitUntil( caches.open(CACHE_NAME).then(cache => fetch('assets-manifest.json', {headers: {'Content-Type': 'application/json'}}) .then(res => res.json()) .then(assets => cache.addAll(assets)) .then(() => console.log('Cached')) ) ); }); self.addEventListener('fetch', function(event) { event.respondWith(caches.match(event.request).then(response => response || fetch(event.request))); }); CACHE TIMESTAMP SERVICE WORKER
UNIVERSAL WEB APP + REACTJS ASSETS-MANIFEST (JSON) [ "/", "/main.js",
"/main.css", "/logo.png", "https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,300,400italic,600,200,600italic,700,900", "https://fonts.gstatic.com/s/sourcesanspro/v10/ODelI1aHBYDBqgeIAH2zlJbPFduIYtoLzwST68uhz_Y.woff2", "https://fonts.gstatic.com/s/sourcesanspro/v10/toadOcfmlt9b38dHJxOBGJkF8H8ye47wsfpWywda8og.woff2", "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css", "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/fonts/fontawesome-webfont.woff2?v=4.6.3", "https://cdnjs.cloudflare.com/ajax/libs/normalize/7.0.0/normalize.min.css" ] CONFIGURABLE ASSET AND RESOURCE LIST
UNIVERSAL WEB APP + REACTJS PWA-APP-MANIFEST { "name": "UWA-PWA", "short_name":
"UWA-PWA", "start_url": "/?homescreen=1", "display": "standalone", "theme_color": "aliceblue", "background_color": "gray", "description": "My React-Universal-App", "icons": [{ "src": "homescreen.png", "sizes": "48x48", "type": "image/png" }], "related_applications": [{ "platform": "web", "id": "UWA-PWA" }] } ADD TO HOMESCREEN SPLASHSCREEN
UNIVERSAL WEB APP + REACTJS SERVER import express from 'express'
const app = express() app.use(express.static(__dirname + '/statics')) app.listen(8080, () => console.log(`Listen on 8080`)) NODEJS + EXPRESSJS + @REACT15 / REACT16
UNIVERSAL WEB APP + REACTJS COMPONENTS import React from 'react'
export default class HelloWorld extends React.PureComponent { render() { return ( <div>Hello, {this.props.greeting}</div> ) } } @REACT15 / @REACT16
UNIVERSAL WEB APP + REACTJS SERVER + REACT import React
from 'react' import {renderToString} from 'react-dom/server' import HelloWorld from ‚../components/HelloWorld' app.get('/', (req, res) => { const initialData = 'Universal Web App' const html = renderToString(<HelloWorld />) res.send(renderUniversalPageWithData(html, initialData)) }) @REACT15
UNIVERSAL REACTJS SERVER HTML TEMPLATE function renderUniversalPageWithData(html, initialData) { return
( `<html> <head lang="de"> <meta charset="UTF-8"> <title>ReactJS SSR</title> </head> <body> <div id="root">${html}</div> </body> <script> window.__INITIAL_STATE__ = ${JSON.stringify(initialData)}; </script> <script src="/bundle.js"></script> </html>` ) } @REACT15
UNIVERSAL WEB APP + REACTJS SERVER + REACT import React
from 'react' import {renderToNodeStream} from 'react-dom/server' import HelloWorld from '../components/HelloWorld' app.get('/', (req, res) => { renderToNodeStream( <Html initialData={JSON.stringify(initialData)}> <HelloWorld {...initialData} /> </Html> ).pipe(res); }) @REACT16
UNIVERSAL REACTJS SERVER HTML TEMPLATE import React from 'react' const
Html = props => ( <html> <head> <title>ReactJS SSR</title> </head> <body> <div id="root">{props.children}</div> <script id="initial-data" type="text/plain" data-json={props.initialData} /> <script src="/bundle.js" /> </body> </html> ) export default Html @REACT16
UNIVERSAL WEB APP + REACTJS CLIENT import React from 'react'
import {render} from 'react-dom' import HelloWorld from ‚../components/HelloWorld' const initialData = window.__INITIAL_STATE__ render( <HelloWorld {...initialData} />, document.getElementById('root') ) @REACT15
UNIVERSAL WEB APP + REACTJS CLIENT import React from 'react'
import {hydrate} from 'react-dom' import HelloWorld from '../components/HelloWorld' const initialData = JSON.parse( document.getElementById('initial-data').getAttribute('data-json') ) hydrate( <HelloWorld {...initialData} />, document.getElementById('root') ) @REACT16
UNIVERSAL WEB APP + REACTJS UWA + REACT ROUTER4 ▸
Server - StaticRouter ▸ Client - BrowserRouter ▸ Routes
UNIVERSAL WEB APP + REACTJS THANK YOU! QUESTIONS SOFTWARE ENGINEER
// FREELANCER // WORKSHOPS @MIKEBILD @MIKEBILD ASK ME ABOUT UWA & PWA
UNIVERSAL WEB APP + REACTJS RESOURCES ▸ Reunify UWA +
PWA https://www.reunify.run ▸ Reunify Code and Issues on GitHub https://github.com/CodeCommission/reunify ▸ Reunify News on Twitter https://twitter.com/reunify_run