Titus Woo
I'm an engineer and wannabe designer based in San Francisco!
A serious talk by Titus Woo
import React from 'react'
import Dashboard from './Dashboard'
import { AdBanner } from '@paypalcorp/pp-ad-banner'
const App = () => (
<html>
<head>
<title>Dashboard</title>
</head>
<body>
<AdBanner />
<Dashboard />
</body>
</html>
)
import React from 'react'
import Dashboard from './Dashboard'
import { AdBanner } from '@paypalcorp/pp-ad-banner'
const App = () => (
<html>
<head>
<title>Dashboard</title>
</head>
<body>
<AdBanner />
<Dashboard />
</body>
</html>
)
cash-flow-ad-lg.jpg
cash-flow-ad-sm.jpg
Provides URL for small and large banner images.
Display optimized image based on device
<img srcset="cash-flow-ad-sm.jpg 160w,
cash-flow-ad-lg.jpg 940w"
sizes="(max-width: 160px) 160px,
940px"
src="cash-flow-ad-lg.jpg" />
Include alt text in the ad image
<img srcset="cash-flow-ad-sm.jpg 160w,
cash-flow-ad-lg.jpg 940w"
sizes="(max-width: 160px) 160px,
940px"
src="cash-flow-ad-lg.jpg"
alt="An offer banner. It says, βFacing a cash flow gap? A PayPal business Loan could help. Applyβ¦"
/>
Every team needs to update NPM package and redeploy
Dependency on React
Dependent on React 16
Easy to integrate, at cost of all data orchestration done in the browser
Lots of XHR requests in the browser
{
"html": "",
"css": "",
"js": ""
}
<div id="ad">loading ad...</div>
<script>
fetch('paypal.com/banner-ad')
.then(banner => banner.json())
.then(banner => {
document.getElementById('ad').innerHTML = banner.html
const cssNode = document.createTextNode(banner.css)
const styleNode = document.createElement('style')
styleNode.appendChild(cssNode)
document.head.append(styleNode)
})
</script>
Cold start:
{
"html": "",
"css": "",
"js": ""
}
banner-ad
Node.js
dashboard
Node.js
Every team needs to update NPM package and redeploy
to get new changes
Dependency on React
Dependent on React 16
Easy to integrate, at cost of all data orchestration done in the browser
Lots of XHR requests in the browser
(on 3G simulated connection)
request.get('https://paypal.com/fragments/ad-banner', (e, r, body) => {
const adFragment = JSON.parse(body)
res.send(`
<html>
<head>
<title>Dashboard</title>
<style>${adFragment.css}</style>
</head>
<body>
<h1>PayPal Dashboard</h1>
<div id="ad">${adFragment.html}</div>
<script>${adFragment.js}</script>
</body>
</html>
`)
})
{
"html": "<div id=\"banner-ad-fragment\"><img src=\"paypalobjects.com/ad-banner-lg.jpg\" /></div>",
"css": "#banner-ad-fragment { background-color: gray; }",
"js": "document.getElementById('banner-ad-fragment').addEventListener(() => { console.log('hi') })"
}
fetch('/banner')
{
"html": "<div id=\"banner-ad-fragment\"><img src=\"paypalobjects.com/ad-banner-lg.jpg\" /></div>",
"css": "https://paypalobjects.com/wlke925224s.css",
"js": "https://paypalobjects.com/eesl33t3ls1.js"
}
{
"html": "https://paypalobjects.com/91o4mnzke3.html",
"css": "https://paypalobjects.com/wlke925224s.css",
"js": "https://paypalobjects.com/eesl33t3ls1.js"
}
Cache-Control: public, max-age=31536000 Β
fetch('/header-fragment')
Gotcha!
@tituswoo
By Titus Woo
Learn how we built a micro-frontend architecture which we've deployed at PayPal! It lets us break up large front-end experiences into smaller, technology-agnostic modules that can be imported anywhere in any app at run-time. This lets us redeploy features and UI instantly to dependent teams without them having to redeploy their apps.