Ember with Fastboot & Embroider
Fast Track
suchitadoshi
suchitadoshi1987
suchita009
suchita009#4368
xinganwang
xg-wang
xinganwang
xg-wang#5846
Who are we?
Thomas
xinganwang
xg-wang
xinganwang
xg-wang#5846
Who are we?
Suchita
image credits:
http://www.themarketingsage.com/wp-content/uploads/2015/08/about-me-leon-severan-we-buy-houses.jpg
suchitadoshi
suchitadoshi1987
suchita009
suchita009#4368
Gardening
Cricket
Mechanical
Keyboards ❤️
Who are we?
Suchita
image credits:
https://i.gifer.com/CVU.gif
Gardening
Who are we?
Suchita
image credits:
https://i.gifer.com/CVU.gif
Journey from octane and beyond
Know the team their requirements
Know the team their requirements
Server side rendering powered by FastBoot
JOURNEY FROM OCTANE AND BEYOND
Know the team their requirements
Server side rendering powered by FastBoot
Build time optimization with Embroider
Journey from octane and beyond
Know the team their requirements
Server side rendering powered by FastBoot
Build time optimization with Embroider
Roadmap for FastBoot
Journey from octane and beyond
Zöe
An enthusiastic Ember developer.
works at
An awesome company that uses Ember JS
team status
Recently upgraded to Ember Octane
image credits:
https://media.slid.es/uploads/1278854/images/8238706/PinClipart.com_company-clipart_11891.png
Requirements
Requirements
Faster content to the end user
image credits:
https://i.gifer.com/41C.gif
Requirements
Faster content to the end user
Improved user engagement
image credits:
https://i.gifer.com/41C.gif
https://qph.fs.quoracdn.net/main-qimg-e980c1173022b1e27482699556c1afce
Requirements
Faster content to the end user
Improved user engagement
Improved search indexing
image credits:
https://i.gifer.com/41C.gif
https://qph.fs.quoracdn.net/main-qimg-e980c1173022b1e27482699556c1afce
https://images.squarespace-cdn.com/content/v1/sign.gif
Server side rendering
(SSR)
What is SSR?
SSR Solution for Ember JS
ember install ember-cli-fastboot
mental model
Core web vitals
image credits:
web.dev/vitals/
Core web vitals
- Reports the render time of the largest image or text block visible within the viewport.
- Determines when the main content of the page has finished rendering on the screen
- Helps reassure the user that the page is useful
image credits:
web.dev/vitals/
before fastboot
after fastboot
before fastboot
after fastboot
before fastboot
after fastboot
before fastboot
after fastboot
Before fastboot
after fastboot
LCP
app js
api requests
vendor js
HTML + CSS
HTML + CSS
LCP
vendor js
app js
Before fastboot
Before fastboot
Before fastboot
after fastboot
after fastboot
Shoebox
📦
Shoebox
Shoebox
Shoebox
Shoebox
Shoebox
Shoebox
Shoebox
Shoebox
Changes needed for fastboot
ember install ember-cli-fastboot
ember s
Changes needed for fastboot
ember install ember-cli-fastboot
EXPERIMENTAL_RENDER_MODE_SERIALIZE=true ember s
"devDependencies": {
"ember-cli": "~3.24.0",
"ember-cli-app-version": "^4.0.0",
"ember-cli-babel": "^7.23.0",
"ember-cli-terser": "^4.0.1",
"ember-concurrency": "^2.0.1",
"ember-data": "~3.25.0",
"ember-data-storefront": "^0.18.0",
"ember-fetch": "^8.0.2",
"ember-load-initializers": "^2.1.2",
}
import RESTAdapter from '@ember-data/adapter/rest';
import FastbootAdapter from 'ember-data-storefront/mixins/fastboot-adapter';
export default class AppAdapter extends RESTAdapter.extend(FastbootAdapter) {
handleResponse(status, headers, payload) {
if (this.isInvalid(...arguments)) {
if (typeof payload === 'string') {
payload = JSON.parse(payload);
}
}
return super.handleResponse(status, headers, payload);
}
}
package.json
adapters/appAdapter.js
recap
Faster content to the end user
Improved user engagement
Improved search indexing
image credits:
https://i.gifer.com/41C.gif
https://qph.fs.quoracdn.net/main-qimg-e980c1173022b1e27482699556c1afce
https://images.squarespace-cdn.com/content/v1/sign.gif
recap
Faster content to the end user
Improved user engagement
Improved search indexing
image credits:
https://i.gifer.com/41C.gif
https://qph.fs.quoracdn.net/main-qimg-e980c1173022b1e27482699556c1afce
https://images.squarespace-cdn.com/content/v1/sign.gif
recap
Faster content to the end user
Improved user engagement
Improved search indexing
image credits:
https://i.gifer.com/41C.gif
https://qph.fs.quoracdn.net/main-qimg-e980c1173022b1e27482699556c1afce
https://images.squarespace-cdn.com/content/v1/sign.gif
recap
Faster content to the end user
Improved user engagement
Improved search indexing
image credits:
https://i.gifer.com/41C.gif
https://qph.fs.quoracdn.net/main-qimg-e980c1173022b1e27482699556c1afce
https://images.squarespace-cdn.com/content/v1/sign.gif
image credits:
https://media2.giphy.com/media/3o6Mbl0kpk4i9G2GCQ/source.gif
media credits:
https://www.nick.com/
😄new Requirements
- 📈 We will build more pages!
- 🤔 Which means more JavaScript...
- 🚢 Can we ship only the JavaScript of the initial page?
OPTIMIZING THE BUILD 🚧
EMBROIDER
a modern build system for EmberJS apps
✂️CODE SPLITTING
🌲TREE SHAKING
Let's add Embroider
yarn add --dev @embroider/core @embroider/compat @embroider/webpack @embroider/router
// ember-cli-build.js
const { Webpack } = require('@embroider/webpack');
const EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function (defaults) {
let app = new EmberApp(defaults, {});
return require('@embroider/compat').compatBuild(app, Webpack, {
staticAddonTestSupportTrees: true,
staticAddonTrees: true,
staticHelpers: true,
staticComponents: true,
splitAtRoutes: [
'editor',
'settings',
'register',
'login',
'articles',
'profile'
],
});
};
// app/router.js
import EmberRouter from '@embroider/router';
import config from 'ember-realworld/config/environment';
export default class Router extends EmberRouter {
location = config.locationType;
rootURL = config.rootURL;
}
Router.map(function () {
this.route('editor', function () {
this.route('edit', { path: ':id' });
});
this.route('settings');
this.route('register');
this.route('login');
this.route('articles', function () {
this.route('article', { path: ':id' });
});
this.route('profile', { path: 'profile/:id' }, function () {
this.route('favorites');
});
});
🔥Dynamic import()
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { htmlSafe } from '@ember/template';
export default class ArticleContentComponent extends Component {
@tracked marked = null;
constructor() {
super(...arguments);
import('marked').then((module) => {
this.marked = module.default;
});
}
get safeMarkup() {
return htmlSafe(this.marked?.(this.args.article.body));
}
}
Can i use it today🤔
yeees🚀
Impact of enabling Embroider on a LinkedIn application
faster speed⚡
Impact of enabling Embroider on a LinkedIn application
Initial JavaScript | Transferred Size | Parsed Size |
---|---|---|
Classic (baseline) | 1.77MB | 9.25MB |
Embroider | 1.15MB(-35%) | 5.03MB(-46%) |
Loading Time | Estimated improvement | Percentage |
---|---|---|
Total page load time | -256ms [-400ms to -140ms] | -6.89% [-10.75% to -3.77%] |
Time to JS execution | -258ms [-342ms to -197ms] | -12.69% [-16.83% to -9.72%] |
cpuThrottleRate: 4, network: fast-3g
Tracerbench: Controlled Performance Benchmarking Tool
Faster build speed⚡
Impact of enabling Embroider on a LinkedIn application
Build Time | Cold Start | Warm Start | Live Reload |
---|---|---|---|
Classic (baseline) | 139s | 80s | 3.5s |
Embroider | 59s (-58%) | 58s (-28%) | 0.7s(-80%) |
✂️ Less code shipped to users
🚀 Faster page load time
⚡ Faster build speed
recap
image credits:
https://media2.giphy.com/media/3o6Mbl0kpk4i9G2GCQ/source.gif
Fastboot roadmap
- Leverage worker threads
- Streaming the initial HTML
- Enable Rehydration by default
- Testing story, improved DX
- And more...
- Preload splitted chunks in FastBoot
Resources
ONe more thing...
image credits:
https://i1.wp.com/www.smartprix.com/bytes/wp-content/uploads/2020/11/ShrillWildFruitfly-size_restricted.gif
fastboot meetup
image credits:
https://media3.giphy.com/media/IeXz4ljIbZHS1BUkR3/giphy.gif
Fast Track Ember with Fastboot & Embroider
By Suchita Doshi
Fast Track Ember with Fastboot & Embroider
- 719