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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
軽量Java基盤の設計 DIコンテナに頼らない、長期保守と1秒起動の実現 JJUG CCC 2026 Spring
macha64
0
510
Lessons from Spec-Driven Development
simas
PRO
0
190
JJUG CCC 2026 Spring: JSpecify で実現する Kotlin フレンドリーな Java API 設計
ternbusty
1
160
過去最大のMCPアップデート! 2026-07-28 RC版の謎に迫る
licux
6
280
AIチームを指揮するOSS「TAKT」活用術 / How to Use “TAKT,” an OSS Tool for Orchestrating AI Teams
nrslib
6
890
Technical Debt: Understanding it Rightly, Engaging it Rightly #LaravelLiveJP
shogogg
0
220
Oxcを導入して開発体験が向上した話
yug1224
4
310
AI時代のUIはどこへ行く?その2!
yusukebe
21
7.1k
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
230
AutonomyとControlのあいだ:Graflowで記述するAIエージェント協調
myui
0
120
ローカルLLMを使ってB2Bサービスを作っていての学び
yaotti
0
170
ADKを使って簡単にAIエージェントを作ってみよう
k1mu21
0
260
Featured
See All Featured
Large-scale JavaScript Application Architecture
addyosmani
515
110k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
140
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.3k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
Abbi's Birthday
coloredviolet
2
8k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
250
A designer walks into a library…
pauljervisheath
211
24k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
290
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
SEO for Brand Visibility & Recognition
aleyda
0
4.6k
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