Abhinav Rastogi
Web Developer, Photographer, Designer. Loves Pink Floyd, Coldplay, Beatles. Travelling is fun, science is awesome!
Abhinav Rastogi
@_abhinavrastogi
const async = bundle => (location, cb) => {
bundle(component => {
cb(null, component);
});
};
const routes = {
path: '/about',
getComponent: (location, callback) => {
require.ensure([], function (require) {
var Page = require('./Page.js');
callback(null, Page);
});
}
}
// or
const routes = {
path: '/about',
getComponent: async(require('bundle?lazy!./Page.js'))
}
<html>
<head>
<meta ...>
<link rel="stylesheet" href="styles.css" />
<link rel="preload" as="script" href="vendor.js" />
<link rel="preload" as="script" href="chunk1.js" />
<link rel="preload" as="script" href="chunk2.js" />
</head>
<body>
<div>
... server rendered html ...
</div>
<script src="vendor.js"></script>
<script src="chunk.1.js"></script>
<script src="chunk.2.js"></script>
<script src="chunk.3.js"></script>
</body>
</html>
HTML
CSS
JS download
JS Parse
API call
First Paint +
Full Render
Empty Page
HTML
CSS
JS download
JS Parse
API call
Render Content
First Paint + Render Loaders
Lesser load on server
Better SEO, smaller html
header/footer can load quicker
Still takes time to receive response
html is still large, it can be faster!
JS file is huge
user sees no organic content until JS loads
smaller JS file for init
faster full page render
slightly increased complexity in build system
page navigations slower as JS needs to download on click
Need a smart way to predict next chunk. For most websites a static map can also work
html download is still taking time.
app.use(function (req, res) {
res.set('Content-Type', 'text/html');
let htmlHead = "<html><head><link><style>....<body>";
res.write(htmlHead);
res.flush();
let htmlBody = ReactDOM.renderToString(<App />);
res.write(htmlBody);
res.flush();
let scripts = "<script src='app.bundle.js'></script>";
res.write(scripts);
res.flush();
res.end();
});
But wait, what about gzipping?
HTML
CSS
JS download
JS Parse
API call
Full
Render
Useful First Paint
<body>
<script>
requestAnimationFrame(function () {
performance.mark("first_paint");
});
</script>
<div>
... all content ...
</div>
css and js resources can start downloading within milliseconds
page is ready to render as soon as html is downloaded
Server has to keep connection open with client until download completes
client can download limited number of resources at a time
var fontA = new FontFaceObserver('Roboto', { weight: 400 });
var fontB = new FontFaceObserver('Roboto', { weight: 500 });
Promise.all([fontA.load(), fontB.load()]).then(function () {
document.documentElement.className += ' fonts-loaded';
});
body {
font-size: 14px;
}
body {
font-family: Arial, sans-serif;
letter-spacing: -0.2px;
}
:global .fonts-loaded {
body {
font-family: Roboto, Arial, sans-serif;
letter-spacing: 0;
}
}
By Abhinav Rastogi
Web Developer, Photographer, Designer. Loves Pink Floyd, Coldplay, Beatles. Travelling is fun, science is awesome!