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
Mike Bild
November 26, 2017
Programming
55
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
110
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
30年振りにコンパイラの定数整数除算を改善した
herumi
9
4.2k
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
280
Detecting Compromised CI with eBPF and Cilium Tetragon
lizrice
0
260
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
340
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
1
270
進化を続けるGo toolsの現在地 / The Current State of Ever-Evolving Go Tools
hond0413
0
260
AIと壁打ちしながら進めるコスト管理
fufuhu
2
1.7k
異なる設計思想のフレームワークを経験して得た学び
amekuhideki
1
520
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.7k
メールのエイリアス機能を履き違えない
isshinfunada
0
250
プロポーザルを書いてもらう
pvcresin
0
580
My Marp Sample
sinoue0108
0
120
Featured
See All Featured
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Design in an AI World
tapps
1
290
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
620
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
1
380
A Soul's Torment
seathinner
6
3.5k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
480
Agile that works and the tools we love
rasmusluckow
331
22k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
970
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