SlideShare a Scribd company logo
1 of 185
Download to read offline
FUTURE-PROOFING
YOUR JAVASCRIPT
FRAMEWORK
DECISIONApril 5, 2019
JOHN RIVIELLO
@JohnRiv
2
?
GOAL:
Position your team so
the eventual transition
off the framework will
involve the least
amount of friction
Future-Proofing Your JavaScript Framework Decision - @JohnRiv4
“BEACH SAND” BY JOSH SORENSON LICENSED BY PEXELS.COM
Future-Proofing Your JavaScript Framework Decision - @JohnRiv5
“SACRIFICIAL ARCHITECTURE”
https://martinfowler.com/bliki/SacrificialArchitecture.html
“Thinking now about
things that can make it
easier to replace when
the time comes.”
- MARTIN FOWLER
Future-Proofing Your JavaScript Framework Decision - @JohnRiv6
1.REDUX
2.PERPETUAL CSS
3.DEMO PAGES
4.A FRAMEWORK FOR
CHOOSING YOUR FRAMEWORK
PATTERNS & TOOLS
REDUX
Future-Proofing Your JavaScript Framework Decision - @JohnRiv8
UNIDIRECTIONAL
DATA FLOWhttps://redux.js.org/basics/data-flow
Future-Proofing Your JavaScript Framework Decision - @JohnRiv9
PREDICTABLE
STATE MUTATIONShttps://redux.js.org/introduction/motivation
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 0
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 3
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 8
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 9
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 0
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 1
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 2
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
log('OPEN_MODAL',

'PAUSE_PERSON',

'ABC1234');
Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 3
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 4
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 5
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 6
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 7
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
{
…
modal: {
isOpen: false,
}
…
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 8
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
{
…
modal: {
isOpen: true,
type: 'PAUSE_PERSON',
}
…
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 9
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 0
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 1
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 2
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 3
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 4
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
{
viewState: {
modal: {
isOpen: true,
type: 'PAUSE_PERSON',
displayName: 'Max',
}
}
…
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 5
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 6
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 7
{
type: 'OPEN_MODAL',
payload: {
type: 'PAUSE_PERSON'
id: 'ABC1234',
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 8
Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 9
Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 0
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 1
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 2
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 3
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 4
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 5
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 6
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 7
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 8
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 9
{
type: 'MODAL_SUBMIT',
payload: { … }
}
POST /pause/ABC1234
Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 0
{
type: 'MODAL_SUBMIT',
payload: { … }
}
log('MODAL_SUBMIT',

'PAUSE_PERSON',

'ABC1234');
Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 1
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 2
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 3
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 4
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 5
{
type: 'MODAL_SUBMIT',
payload: { … }
}
{
…
modal: {
isOpen: true,
type: 'PAUSE_PERSON',

status: 'READY',
}
…
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 6
{
type: 'MODAL_SUBMIT',
payload: { … }
}
{
…
modal: {
isOpen: true,
type: 'PAUSE_PERSON',

status: 'BUSY',
}
…
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 7
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 8
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 9
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 0
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 1
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 2
{
type: 'MODAL_SUBMIT',
payload: { … }
}
{
viewState: {
modal: {
isOpen: true,
type: 'PAUSE_PERSON',
status: 'BUSY',
}
}
…
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 3
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 4
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 5
{
type: 'MODAL_SUBMIT',
payload: { … }
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 6
Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 7
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 8
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 9
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 0
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 1
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 2
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 3
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 4
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 5
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 6
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 7
POST /pause/ABC1234
200 OK
{ … data … }
log('MODAL_SUCCESS',

'PAUSE_PERSON',

'ABC1234');
Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 8
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 9
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 0
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 1
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 2
POST /pause/ABC1234
200 OK
{ … data … }
{
…
modal: {
isOpen: true,
type: 'PAUSE_PERSON',

status: 'BUSY',
}
…
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 3
POST /pause/ABC1234
200 OK
{ … data … }
{
…
modal: {
isOpen: true,
type: 'PAUSE_PERSON',

status: 'SUCCESS',
}
…
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 4
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 5
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 6
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 7
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 8
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 9
POST /pause/ABC1234
200 OK
{ … data … }
{
viewState: {
modal: {
isOpen: true,
type: 'PAUSE_PERSON',
status: 'SUCCESS',
}
}
…
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 0
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 1
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 2
POST /pause/ABC1234
200 OK
{ … data … }
Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 3
Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 4
Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 5
Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 6
Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 7
client-core
src/
actions/
constants/
data/
epics/
helpers/
middleware/
reducers/
selectors/
store/
index.js
dist/
es5-client-core.js
Future-Proofing Your JavaScript Framework Decision - @JohnRiv
src/
actions/
constants/
data/
epics/
helpers/
middleware/
reducers/
selectors/
store/
index.js
dist/
es5-client-core.js
9 8
client-core
src/actions/index.js
export { default as account } from './account';
export { default as app } from './app';
...
account.js
app.js
…
index.js
…
src/actions/account.js
export function functionOne({
...
return {
/* object */
};
}
export function functionTwo({
...
return {
/* object */
};
}
...
export default {
functionOne,
functionTwo,
...
};
Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 9
client-core
src/
actions/
constants/
data/
epics/
helpers/
middleware/
reducers/
selectors/
store/
index.js
dist/
es5-client-core.js
index.js
import * as _actions from './src/actions';
import * as _constants from './src/constants';
import * as _data from './src/data';
import * as _epics from './src/epics';
import * as _helpers from './src/helpers';
import * as _middleware from './src/middleware';
import * as _reducer from './src/reducers';
import * as _selectors from './src/selectors';
import * as _store from './src/store';
export const actions = _actions;
export const constants = _constants;
export const data = _data;
export const epics = _epics;
export const helpers = _helpers;
export const middleware = _middleware;
export const reducers = _reducer;
export const selectors = _selectors;
export const store = _store;
src/actions/index.js
export { default as account } from './account';
export { default as app } from './app';
...
src/actions/account.js
export function functionOne({
...
return {
/* object */
};
}
export function functionTwo({
...
return {
/* object */
};
}
...
export default {
functionOne,
Future-Proofing Your JavaScript Framework Decision - @JohnRiv
src/actions/account.js
export function functionOne({
...
return {
/* object */
};
}
export function functionTwo({
...
return {
/* object */
};
}
...
export default {
functionOne,
1 0 0
client-core
src/
actions/
constants/
data/
epics/
helpers/
middleware/
reducers/
selectors/
store/
index.js
dist/
es5-client-core.js
index.js
import * as _actions from './src/actions';
import * as _constants from './src/constants';
import * as _data from './src/data';
import * as _epics from './src/epics';
import * as _helpers from './src/helpers';
import * as _middleware from './src/middleware';
import * as _reducer from './src/reducers';
import * as _selectors from './src/selectors';
import * as _store from './src/store';
export const actions = _actions;
export const constants = _constants;
export const data = _data;
export const epics = _epics;
export const helpers = _helpers;
export const middleware = _middleware;
export const reducers = _reducer;
export const selectors = _selectors;
export const store = _store;
src/actions/index.js
export { default as account } from './account';
export { default as app } from './app';
...
import clientCore from 'client-core'
import {actions as coreActions} from 'client-core'
import {account as accountActions} from 'client-core/actions'
import {functionOne as f1} from 'client-core/actions/account'
Allows for multiple ways to import the code
Future-Proofing Your JavaScript Framework Decision - @JohnRiv
src/actions/account.js
export function functionOne({
...
return {
/* object */
};
}
export function functionTwo({
...
return {
/* object */
};
}
...
export default {
functionOne,
src/
actions/
constants/
data/
epics/
helpers/
middleware/
reducers/
selectors/
store/
index.js
dist/
es5-client-core.js
1 0 1
client-core
index.js
import * as _actions from './src/actions';
import * as _constants from './src/constants';
import * as _data from './src/data';
import * as _epics from './src/epics';
import * as _helpers from './src/helpers';
import * as _middleware from './src/middleware';
import * as _reducer from './src/reducers';
import * as _selectors from './src/selectors';
import * as _store from './src/store';
export const actions = _actions;
export const constants = _constants;
export const data = _data;
export const epics = _epics;
export const helpers = _helpers;
export const middleware = _middleware;
export const reducers = _reducer;
export const selectors = _selectors;
export const store = _store;
src/actions/index.js
export { default as account } from './account';
export { default as app } from ‘./app';
...
import clientCore from 'client-core'
import {actions as coreActions} from 'client-core'
import {account as accountActions} from 'client-core/actions'
import {functionOne as f1} from 'client-core/actions/account'
Allows for multiple ways to import the code
= UMD Module+
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 0 2
YOU MIGHT NOT
NEED REDUX
¯_ _/¯
git clone --depth 1 -b template-no-redux —single-branch
https://github.com/Polymer/pwa-starter-kit my-app
https://pwa-starter-kit.polymer-project.org/
NO-REDUX TEMPLATE:
git clone --depth 1 -b template-no-redux —single-branch
https://github.com/Polymer/pwa-starter-kit my-app
PERPETUAL CSS
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 0 5
CSS: SO MANY OPTIONS
COMPONENT-SPECIFIC
•CSS-in-JS
•Shadow DOM
REUSABLE CLASSES
•OOCSS
•SMACSS
•BEM
THEMING WITH VARIABLES
•Sass / Less / Stylus
•Post CSS
•CSS Custom Properties
•CSS Shadow Parts
UTILITY CLASSES /
FUNCTIONAL CSS / ATOMIC CSS
•Atomizer
•Tachyons
•Tailwind
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 0 6
STANDARD APPROACH VS UTILITY CLASSES
.standard {
color: red;
float: left;
}
<div class="standard">
Standard Approach
</div>
.text-red {
color: red;
}
.float-left {
float: left;
}
<div class="text-red float-left">
Utility Classes Approach
</div>
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 0 7
Example adapted from https://tailwindcss.com/docs/what-is-tailwind/
<div class="bg-white mx-auto max-w-sm shadow-lg rounded-lg overflow-hidden">
<div class="sm:flex sm:items-center px-6 py-4">
<img class="block h-16 sm:h-24 rounded-full mx-auto mb-4 sm:mb-0 sm:mr-4 sm:ml-0"
src="johnriv.jpg" alt="">
<div class="text-center sm:text-left sm:flex-grow">
<div class="mb-4">
<p class="text-xl leading-tight">John Riviello</p>
<p class="text-sm leading-tight text-grey-dark">Maker of web things</p>
</div>
<div>
<button class="text-xs font-semibold rounded-full px-4 py-1 leading-normal bg-
white border border-purple text-purple hover:bg-purple hover:text-white">Message</
button></div></div></div></div>
😱
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 0 9
Tweet source: https://twitter.com/sindresorhus/status/1089075390327316480
© JOHN RIVIELLO
© JOHN RIVIELLO
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 2
“MAN SITTING ON GRASS FIELD” BY PIXABAY LICENSED BY CC0
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 3
Tweet source: https://twitter.com/dan_abramov/status/1089208929572319232
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 4
“WHITE AND GREY KITTEN SMELLING WHITE DAISY FLOWER” BY ALEX BARGAIN LICENSED BY PEXELS.COM
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 5
CSS:
😁 Easy to add 📈
😬 Hard to remove
SOLUTION?
TAILWIND AND…
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 6
Purgecss
https://www.purgecss.com
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 7
CSSSTATS.COM RESULTS
Current Web App Tailwind + PurgeCSS
RULES 6,260 289
SELECTORS 8,422 336
DECLARATIONS 29,100 440
PROPERTIES 171 129
FONT-SIZE 1,939 13
WIDTH 682 20
HEIGHT 578 12
COLOR 2,322 44
🤔
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 9
USING TAILWIND
“HELLO WORLD”
npm install tailwindcss --save-dev
styles.css:
@tailwind base; /* Collection of CSS Reset rules */
@tailwind components; /* Container Styles */
@tailwind utilities; /* Classes you’ll use */
npx tailwind build styles.css -o output.css
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 0
USING TAILWIND
OUTPUT.CSS FROM @TAILWIND COMPONENTS:
.container {
width: 100%;
}
@media (min-width: 640px) {
.container {
max-width: 640px;
}
}
@media (min-width: 768px) {
.container {
max-width: 768px;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1024px;
}
}
@media (min-width: 1280px) {
.container {
max-width: 1280px;
}
}
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 1
USING TAILWIND
OUTPUT.CSS FROM @TAILWIND COMPONENTS:
.container {
width: 100%;
}
@media (min-width: 640px) {
.container {
max-width: 640px;
}
}
@media (min-width: 768px) {
.container {
max-width: 768px;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1024px;
}
}
@media (min-width: 1280px) {
.container {
max-width: 1280px;
}
}
Markup in your HTML:
<div class="container">
container content
</div>
container content
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 2
USING TAILWIND
OUTPUT.CSS FROM @TAILWIND COMPONENTS:
.container {
width: 100%;
}
@media (min-width: 640px) {
.container {
max-width: 640px;
}
}
@media (min-width: 768px) {
.container {
max-width: 768px;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1024px;
}
}
@media (min-width: 1280px) {
.container {
max-width: 1280px;
}
}
Markup in your HTML:
<div class="container mx-auto">
container content
</div>
container content
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 3
USING TAILWIND
OUTPUT.CSS FROM @TAILWIND COMPONENTS:
.container {
width: 100%;
}
@media (min-width: 640px) {
.container {
max-width: 640px;
}
}
@media (min-width: 768px) {
.container {
max-width: 768px;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1024px;
}
}
@media (min-width: 1280px) {
.container {
max-width: 1280px;
}
}
Markup in your HTML:
<div class="container mx-auto px-8">
container content
</div>
container content
Future-Proofing Your JavaScript Framework Decision - @JohnRiv
Markup in your HTML:
<div class="container">
container content
</div>
OUTPUT.CSS FROM @TAILWIND COMPONENTS:
.container {
width: 100%;
margin-right: auto;
margin-left: auto;
padding-right: 2rem;
padding-left: 2rem;
}
@media (min-width: 640px) {
.container {
max-width: 640px;
}
}
@media (min-width: 768px) {
.container {
max-width: 768px;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1024px;
}
}
...
1 2 4
USING TAILWIND
container content
tailwind.config.js:
module.exports = {
theme: {
container: {
center: true,
padding: '2rem',
},
}
}
OR SET IN CONFIGURATION:
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 5
USING TAILWIND
OUTPUT.CSS FROM @TAILWIND UTILITIES:
.appearance-none {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.bg-fixed {
background-attachment: fixed;
}
.bg-local {
background-attachment: local;
}
.bg-scroll {
background-attachment: scroll;
}
.bg-bottom {
background-position: bottom;
}
.bg-center {
background-position: center;
}
.bg-left {
background-position: left;
}
.bg-left-bottom {
background-position: left bottom;
}
.bg-left-top {
background-position: left top;
}
.bg-right {
background-position: right;
}
.bg-right-bottom {
background-position: right bottom;
}
.bg-right-top {
background-position: right top;
}
.bg-top {
background-position: top;
}
.bg-repeat {
background-repeat: repeat;
}
.bg-no-repeat {
background-repeat: no-repeat;
}
.bg-repeat-x {
background-repeat: repeat-x;
}
.bg-repeat-y {
background-repeat: repeat-y;
} ...
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 6
USING TAILWIND
OUTPUT.CSS FROM @TAILWIND UTILITIES - RESPONSIVE VARIANTS:
@media (min-width: 640px) {
.sm:appearance-none {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.sm:bg-fixed {
background-attachment: fixed;
}
.sm:bg-local {
background-attachment: local;
}
.sm:bg-scroll {
background-attachment: scroll;
}
.sm:bg-bottom {
background-position: bottom;
}
.sm:bg-center {
background-position: center;
}
.sm:bg-left {
background-position: left;
}
.sm:bg-left-bottom {
background-position: left bottom;
}
.sm:bg-left-top {
background-position: left top;
}
.sm:bg-right {
background-position: right;
}
.sm:bg-right-bottom {
background-position: right bottom;
}
.sm:bg-right-top {
background-position: right top;
}
.sm:bg-top {
background-position: top;
}
.sm:bg-repeat {
background-repeat: repeat;
}
.sm:bg-no-repeat {
background-repeat: no-repeat;
}
.sm:bg-repeat-x {
background-repeat: repeat-x;
}
.sm:bg-repeat-y {
background-repeat: repeat-y;
} ...
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 7
USING TAILWIND
OUTPUT.CSS FROM @TAILWIND UTILITIES - RESPONSIVE VARIANTS:
@media (min-width: 640px) {
.sm:appearance-none {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.sm:bg-fixed {
background-attachment: fixed;
}
.sm:bg-local {
background-attachment: local;
}
.sm:bg-scroll {
background-attachment: scroll;
}
.sm:bg-bottom {
background-position: bottom;
}
.tablet:bg-center {
background-position: center;
}
.sm:bg-left {
background-position: left;
}
.sm:bg-left-bottom {
background-position: left bottom;
}
.sm:bg-left-top {
background-position: left top;
}
.sm:bg-right {
background-position: right;
}
.sm:bg-right-bottom {
background-position: right bottom;
}
.tablet:bg-right-top {
background-position: right top;
}
.tablet:bg-top {
background-position: top;
}
.tablet:bg-repeat {
background-repeat: repeat;
}
.tablet:bg-no-repeat {
background-repeat: no-repeat;
}
.tablet:bg-repeat-x {
background-repeat: repeat-x;
}
.tablet:bg-repeat-y {
background-repeat: repeat-y;
} ...
tailwind.config.js:
module.exports = {
theme: {
screens: {
'tablet': '640px',
// => @media (min-width: 640px) { ... }
'laptop': '1024px',
// => @media (min-width: 1024px) { ... }
'desktop': '1280px',
// => @media (min-width: 1280px) { ... }
}
}
}
CAN MODIFY IN CONFIGURATION:
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 8
USING TAILWIND
OUTPUT.CSS FROM @TAILWIND UTILITIES - DEFAULT COLOR PALETTE:
.bg-transparent {
background-color: transparent;
}
.bg-black {
background-color: #000;
}
.bg-white {
background-color: #fff;
}
.bg-gray-100 {
background-color: #f7fafc;
}
.bg-gray-200 {
background-color: #edf2f7;
}
.bg-gray-300 {
background-color: #e2e8f0;
}
.bg-gray-400 {
background-color: #cbd5e0;
}
.bg-gray-500 {
background-color: #a0aec0;
}
.bg-gray-600 {
background-color: #718096;
}
.bg-gray-700 {
background-color: #4a5568;
}
.bg-gray-800 {
background-color: #2d3748;
}
.bg-gray-900 {
background-color: #1a202c;
}
.bg-red-100 {
background-color: #fff5f5;
}
.bg-red-200 {
background-color: #fed7d7;
}
.bg-red-300 {
background-color: #feb2b2;
}
.bg-red-400 {
background-color: #fc8181;
}
.bg-red-500 {
background-color: #f56565;
}
.bg-red-600 {
background-color: #e53e3e;
} ... MANY, MANY MORE!
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 9
USING TAILWIND
OUTPUT.CSS FROM @TAILWIND UTILITIES - CUSTOMIZED COLOR PALETTE:
.bg-transparent {
background-color: transparent;
}
.bg-black {
background-color: #000;
}
.bg-white {
background-color: #fff;
}
.bg-gray-100 {
background-color: #f7fafc;
}
.bg-gray-200 {
background-color: #edf2f7;
}
.bg-gray-300 {
background-color: #e2e8f0;
}
.bg-indigo {
background-color: #5c6ac4;
}
.bg-blue {
background-color: #007ace;
}
.bg-red {
background-color: #de3618;
}
tailwind.config.js:
module.exports = {
theme: {
colors: {
indigo: '#5c6ac4',
blue: '#007ace',
red: '#de3618',
}
}
}
CAN MODIFY IN
CONFIGURATION:
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 3 0
USING TAILWIND
OUTPUT.CSS FROM @TAILWIND UTILITIES - STATE VARIANTS:
.bg-transparent {
background-color: transparent;
}
.bg-black {
background-color: #000;
}
.bg-white {
background-color: #fff;
}
.bg-gray-100 {
background-color: #f7fafc;
}
.bg-gray-200 {
background-color: #edf2f7;
}
.bg-gray-300 {
background-color: #e2e8f0;
}
.bg-indigo {
background-color: #5c6ac4;
}
.bg-blue {
background-color: #007ace;
}
.bg-red {
background-color: #de3618;
}
.hover:bg-indigo:hover {
background-color: #5c6ac4;
}
.hover:bg-blue:hover {
background-color: #007ace;
}
.hover:bg-red:hover {
background-color: #de3618;
}
.focus:bg-indigo:focus {
background-color: #5c6ac4;
}
.focus:bg-blue:focus {
background-color: #007ace;
}
.focus:bg-red:focus {
background-color: #de3618;
}
tailwind.config.js:
module.exports = {
theme: {
colors: {
indigo: '#5c6ac4',
blue: '#007ace',
red: '#de3618',
}
}
}
CAN MODIFY IN
CONFIGURATION:
Future-Proofing Your JavaScript Framework Decision - @JohnRiv
OUTPUT.CSS FROM @TAILWIND UTILITIES - STATE VARIANTS:
.bg-transparent {
background-color: transparent;
}
.bg-black {
background-color: #000;
}
.bg-white {
background-color: #fff;
}
.bg-gray-100 {
background-color: #f7fafc;
}
.bg-gray-200 {
background-color: #edf2f7;
}
.bg-gray-300 {
background-color: #e2e8f0;
}
Ooh pretty colors!
1 3 1
USING TAILWIND
.bg-indigo {
background-color: #5c6ac4;
}
.bg-blue {
background-color: #007ace;
}
.bg-red {
background-color: #de3618;
}
.hover:bg-indigo:hover {
background-color: #5c6ac4;
}
.hover:bg-blue:hover {
background-color: #007ace;
}
.hover:bg-red:hover {
background-color: #de3618;
}
.focus:bg-indigo:focus {
background-color: #5c6ac4;
}
.focus:bg-blue:focus {
background-color: #007ace;
}
.focus:bg-red:focus {
background-color: #de3618;
}
tailwind.config.js:
module.exports = {
theme: {
colors: {
indigo: '#5c6ac4',
blue: '#007ace',
red: '#de3618',
}
}
}
CAN MODIFY IN
CONFIGURATION:
Markup in your HTML:
<button class="bg-indigo
hover:bg-blue focus:bg-red">
Ooh pretty colors!
</button>
Future-Proofing Your JavaScript Framework Decision - @JohnRiv
OUTPUT.CSS FROM @TAILWIND UTILITIES - STATE VARIANTS:
.bg-transparent {
background-color: transparent;
}
.bg-black {
background-color: #000;
}
.bg-white {
background-color: #fff;
}
.bg-gray-100 {
background-color: #f7fafc;
}
.bg-gray-200 {
background-color: #edf2f7;
}
.bg-gray-300 {
background-color: #e2e8f0;
}
Ooh pretty colors!
1 3 2
USING TAILWIND
.bg-indigo {
background-color: #5c6ac4;
}
.bg-blue {
background-color: #007ace;
}
.bg-red {
background-color: #de3618;
}
.hover:bg-indigo:hover {
background-color: #5c6ac4;
}
.hover:bg-blue:hover {
background-color: #007ace;
}
.hover:bg-red:hover {
background-color: #de3618;
}
.focus:bg-indigo:focus {
background-color: #5c6ac4;
}
.focus:bg-blue:focus {
background-color: #007ace;
}
.focus:bg-red:focus {
background-color: #de3618;
}
tailwind.config.js:
module.exports = {
theme: {
colors: {
indigo: '#5c6ac4',
blue: '#007ace',
red: '#de3618',
}
}
}
CAN MODIFY IN
CONFIGURATION:
Markup in your HTML:
<button class="bg-indigo
hover:bg-blue focus:bg-red">
Ooh pretty colors!
</button>
Future-Proofing Your JavaScript Framework Decision - @JohnRiv
OUTPUT.CSS FROM @TAILWIND UTILITIES - STATE VARIANTS:
.bg-transparent {
background-color: transparent;
}
.bg-black {
background-color: #000;
}
.bg-white {
background-color: #fff;
}
.bg-gray-100 {
background-color: #f7fafc;
}
.bg-gray-200 {
background-color: #edf2f7;
}
.bg-gray-300 {
background-color: #e2e8f0;
}
Ooh pretty colors!
1 3 3
USING TAILWIND
.bg-indigo {
background-color: #5c6ac4;
}
.bg-blue {
background-color: #007ace;
}
.bg-red {
background-color: #de3618;
}
.hover:bg-indigo:hover {
background-color: #5c6ac4;
}
.hover:bg-blue:hover {
background-color: #007ace;
}
.hover:bg-red:hover {
background-color: #de3618;
}
.focus:bg-indigo:focus {
background-color: #5c6ac4;
}
.focus:bg-blue:focus {
background-color: #007ace;
}
.focus:bg-red:focus {
background-color: #de3618;
}
tailwind.config.js:
module.exports = {
theme: {
colors: {
indigo: '#5c6ac4',
blue: '#007ace',
red: '#de3618',
}
}
}
CAN MODIFY IN
CONFIGURATION:
Markup in your HTML:
<button class="bg-indigo
hover:bg-blue focus:bg-red">
Ooh pretty colors!
</button>
Future-Proofing Your JavaScript Framework Decision - @JohnRiv
YOUR CSS FUTURE?
1 3 4
Purgecss =+
LINKS
• Tailwind Docs: https://next.tailwindcss.com/
• PurgeCSS: https://www.purgecss.com/
• Tailwind Container: https://next.tailwindcss.com/docs/container/
• Tailwind Configuration: https://next.tailwindcss.com/docs/configuration
• Tailwind Responsive Design: https://next.tailwindcss.com/docs/responsive-design
• Tailwind Colors: https://next.tailwindcss.com/docs/colors
• Tailwind State Variants: https://next.tailwindcss.com/docs/state-variants/
📉
DEMO PAGES
DDD
DEMO
DRIVEN
DEVELOPMENT
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 3 8
https://react-styleguidist.js.org/examples/basic/
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 3 9
https://react-styleguidist.js.org/docs/documenting.html
A FRAMEWORK
FOR CHOOSING
YOUR
FRAMEWORK
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 1
“LANDSCAPE PHOTOGRAPHY OF FACTORY” BY PIXABAY LICENSED BY CC0
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 2
ANALYTIC
HIERARCHY
PROCESS
by Thomas L. Saaty
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 3
ANALYTIC HIERARCHY PROCESS (AHP)
Goal:
Criteria:
Alternatives:
CHOOSE THE MOST
SUITABLE LEADER
CHARISMA
RAMÓN
EDUCATIONEXPERIENCE INTEGRITY
KATE PAUL
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 4
ANALYTIC HIERARCHY PROCESS (AHP)
Goal:
Criteria:
Alternatives:
CHOOSE THE MOST
SUITABLE LEADER
CHARISMA
RAMÓN
EDUCATIONEXPERIENCE INTEGRITY
KATE PAUL
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 5
AHP FUNDAMENTAL SCALE FOR PAIRWISE COMPARISONS
Intensity of
Importance
Definition Explanation
1 Equal importance Two elements contribute equally to the
objective
3 Moderate importance
Experience and judgement moderately
favor one element over another
5 Strong importance
Experience and judgement strongly
favor one element over another
7 Very strong importance
One element is favored very strongly
over another; its dominance is
demonstrated in practice
9 Extreme importance
The evidence favoring one element 

over another is of the highest possible
order of affirmation
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Pairwise_comparisons
Intensities of 2, 4, 6, and 8 can be used to express intermediate values. 1.1, 1.2, 1.3, etc. can be used for elements that are very close in importance.
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 6
AHP PAIRWISE SCORING
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Alternatives_vs._criteria
Alternatives compared with respect to EXPERIENCE
RAMÓN 1 KATE 4
RAMÓN 4 PAUL 1
KATE 9 PAUL 1
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 7
AHP RECIPROCAL SCORING
EXPERIENCE RAMÓN KATE PAUL
RAMÓN 1 1/4 4
KATE 4 1 9
PAUL 1/4 1/9 1
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Alternatives_vs._criteria
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 8
AHP MATRIX PRIORITY CALCULATIONS
EXPERIENCE RAMÓN KATE PAUL PRIORITY
RAMÓN 1 1/4 4 0.2 1 7
KATE 4 1 9 0.7 1 7
PAUL 1/4 1/9 1 0.066
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Alternatives_vs._criteria
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 9
AHP MATRIX PRIORITY CALCULATIONS
EXPERIENCE RAMÓN KATE PAUL PRIORITY
RAMÓN 1 1/4 4 0.2 1 7
KATE 4 1 9 0.7 1 7
PAUL 1/4 1/9 1 0.066
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Alternatives_vs._criteria
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 0
ANALYTIC HIERARCHY PROCESS (AHP)
Goal:
Criteria:
Alternatives:
CHOOSE THE MOST
SUITABLE LEADER
CHARISMA
RAMÓN
EDUCATIONEXPERIENCE INTEGRITY
KATE PAUL
0.217 0.717 0.066
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 1
ANALYTIC HIERARCHY PROCESS (AHP)
Goal:
Criteria:
Alternatives:
CHOOSE THE MOST
SUITABLE LEADER
CHARISMA
RAMÓN
EDUCATIONEXPERIENCE INTEGRITY
KATE PAUL
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 2
ANALYTIC HIERARCHY PROCESS (AHP)
Goal:
Criteria:
Alternatives:
CHOOSE THE MOST
SUITABLE LEADER
EDUCATIONEXPERIENCE INTEGRITYCHARISMA
RAMÓN KATE PAUL
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 3
ANALYTIC HIERARCHY PROCESS (AHP)
Goal:
Criteria:
Alternatives:
CHOOSE THE MOST
SUITABLE LEADER
CHARISMAEDUCATIONEXPERIENCE
RAMÓN
INTEGRITY
KATE PAUL
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 4
ANALYTIC HIERARCHY PROCESS (AHP)
Goal:
Criteria:
Alternatives:
CHOOSE THE MOST
SUITABLE LEADER
CHARISMAEDUCATIONEXPERIENCE
RAMÓN
INTEGRITY
KATE PAUL
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 5
AHP MATRIX PRIORITY CALCULATIONS
CRITERIA EXPERIENCE EDUCATION CHARISMA INTEGRITY PRIORITY
EXPERIENCE 1 4 3 7 0.547
EDUCATION 1/4 1 1/3 3 0.127
CHARISMA 1/3 3 1 5 0.270
INTEGRITY 1/7 1/3 1/5 1 0.056
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Criteria_vs._the_Goal
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 6
ANALYTIC HIERARCHY PROCESS (AHP)
Goal:
Criteria:
Alternatives:
CHOOSE THE MOST
SUITABLE LEADER
CHARISMA
RAMÓN
EDUCATIONEXPERIENCE INTEGRITY
KATE PAUL
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 7
AHP MATRIX PRIORITY CALCULATIONS
CRITERIA EXPERIENCE EDUCATION CHARISMA INTEGRITY PRIORITY
EXPERIENCE 1 4 3 7 0.547
EDUCATION 1/4 1 1/3 3 0.127
CHARISMA 1/3 3 1 5 0.270
INTEGRITY 1/7 1/3 1/5 1 0.056
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Criteria_vs._the_Goal
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 8
ANALYTIC HIERARCHY PROCESS (AHP)
Goal:
Criteria:
Alternatives:
CHOOSE THE MOST
SUITABLE LEADER
CHARISMA
RAMÓN
EDUCATIONEXPERIENCE INTEGRITY
KATE PAUL
0.547
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 9
AHP MATRIX PRIORITY CALCULATIONS
EXPERIENCE RAMÓN KATE PAUL PRIORITY
RAMÓN 1 1/4 4 0.2 1 7
KATE 4 1 9 0.7 1 7
PAUL 1/4 1/9 1 0.066
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Alternatives_vs._criteria
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 0
ANALYTIC HIERARCHY PROCESS (AHP)
Goal:
Criteria:
Alternatives:
CHOOSE THE MOST
SUITABLE LEADER
CHARISMA
RAMÓN
EDUCATIONEXPERIENCE INTEGRITY
KATE PAUL
0.547
0.217 0.717 0.066
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 1
AHP FINAL PRIORITY CALCULATIONS
EXPERIENCE PRIORITY
PRIORITY

vs. GOAL
PRIORITY with
respect to
EXPERIENCE
RAMÓN 0.2 1 7
KATE 0.7 1 7
PAUL 0.066
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 2
ANALYTIC HIERARCHY PROCESS (AHP)
Goal:
Criteria:
Alternatives:
CHOOSE THE MOST
SUITABLE LEADER
CHARISMA
RAMÓN
EDUCATIONEXPERIENCE INTEGRITY
KATE PAUL
0.547
0.217 0.717 0.066
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 3
AHP FINAL PRIORITY CALCULATIONS
EXPERIENCE PRIORITY
PRIORITY

vs. GOAL
PRIORITY with
respect to
EXPERIENCE
RAMÓN 0.2 1 7 0.547
KATE 0.7 1 7 0.547
PAUL 0.066 0.547
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 4
AHP FINAL PRIORITY CALCULATIONS
EXPERIENCE PRIORITY
PRIORITY

vs. GOAL
PRIORITY with
respect to
EXPERIENCE
RAMÓN 0.2 1 7 0.547
KATE 0.7 1 7 0.547
PAUL 0.066 0.547
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
x
x
x
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 5
AHP FINAL PRIORITY CALCULATIONS
EXPERIENCE PRIORITY
PRIORITY

vs. GOAL
PRIORITY with
respect to
EXPERIENCE
RAMÓN 0.2 1 7 0.547 0.1 1 9
KATE 0.7 1 7 0.547 0.392
PAUL 0.066 0.547 0.036
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
x
x
x
=
=
=
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 6
AHP FINAL PRIORITY CALCULATIONS
EXPERIENCE PRIORITY
PRIORITY

vs. GOAL
PRIORITY with
respect to
EXPERIENCE
RAMÓN 0.2 1 7 0.547 0.1 1 9
KATE 0.7 1 7 0.547 0.392
PAUL 0.066 0.547 0.036
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
x
x
x
=
=
=
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 7
AHP FINAL PRIORITY CALCULATIONS
CANDIDATE
PRIORITY with
respect to
EXPERIENCE
PRIORITY with
respect to
EDUCATION
PRIORITY with
respect to
CHARISMA
PRIORITY with
respect to
INTEGRITY
PRIORITY with
respect to
GOAL
RAMÓN
KATE
PAUL
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 8
AHP FINAL PRIORITY CALCULATIONS
CANDIDATE
PRIORITY with
respect to
EXPERIENCE
PRIORITY with
respect to
EDUCATION
PRIORITY with
respect to
CHARISMA
PRIORITY with
respect to
INTEGRITY
PRIORITY with
respect to
GOAL
RAMÓN 0.1 1 9
KATE 0.392
PAUL 0.036
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 9
AHP FINAL PRIORITY CALCULATIONS
CANDIDATE
PRIORITY with
respect to
EXPERIENCE
PRIORITY with
respect to
EDUCATION
PRIORITY with
respect to
CHARISMA
PRIORITY with
respect to
INTEGRITY
PRIORITY with
respect to
GOAL
RAMÓN 0.1 1 9 0.024 0.201 0.015
KATE 0.392 0.010 0.052 0.038
PAUL 0.036 0.093 0.017 0.004
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 0
AHP FINAL PRIORITY CALCULATIONS
CANDIDATE
PRIORITY with
respect to
EXPERIENCE
PRIORITY with
respect to
EDUCATION
PRIORITY with
respect to
CHARISMA
PRIORITY with
respect to
INTEGRITY
PRIORITY with
respect to
GOAL
RAMÓN 0.1 1 9 0.024 0.201 0.015
KATE 0.392 0.010 0.052 0.038
PAUL 0.036 0.093 0.017 0.004
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
=
=
=
+
+
+
+
+
+
+
+
+
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 1
AHP FINAL PRIORITY CALCULATIONS
CANDIDATE
PRIORITY with
respect to
EXPERIENCE
PRIORITY with
respect to
EDUCATION
PRIORITY with
respect to
CHARISMA
PRIORITY with
respect to
INTEGRITY
PRIORITY with
respect to
GOAL
RAMÓN 0.1 1 9 0.024 0.201 0.015 0.358
KATE 0.392 0.010 0.052 0.038 0.492
PAUL 0.036 0.093 0.017 0.004 0.149
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
=
=
=
+
+
+
+
+
+
+
+
+
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 2
AHP FINAL PRIORITY CALCULATIONS
CANDIDATE
PRIORITY with
respect to
EXPERIENCE
PRIORITY with
respect to
EDUCATION
PRIORITY with
respect to
CHARISMA
PRIORITY with
respect to
INTEGRITY
PRIORITY with
respect to
GOAL
RAMÓN 0.1 1 9 0.024 0.201 0.015 0.358
KATE 0.392 0.010 0.052 0.038 0.492
PAUL 0.036 0.093 0.017 0.004 0.149
https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
=
=
=
+
+
+
+
+
+
+
+
+
“SURVEY ICON” BY PIXABAY LICENSED BY CC0
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 4
“FOUR PERSON HOLDING BULB LIGHT DECORS” BY RAWPIXEL.COM LICENSED BY PEXELS.COM
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 5
“HAWAII HANA ROAD” BY PIXABAY LICENSED BY CC0
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 6
“WELCOME TO HANA” BY KIRT EDBLOM LICENSED BY CC BY-SA 2.0
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 7
“HANA BEACH PARK” BY TRAVIS THURSTON LICENSED BY CC BY-SA 3.0
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 8
“HANA BEACH PARK” BY TRAVIS THURSTON LICENSED BY CC BY-SA 3.0
IT’S THE
JOURNEY,
NOT THE
DESTINATION
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 9
“HANA BEACH PARK” BY TRAVIS THURSTON LICENSED BY CC BY-SA 3.0
IT’S THE
JOURNEY,
AND THE
DESTINATION
HOW DID OUR
TEAM DECIDE?
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 8 1
OUR JS FRAMEWORK CRITERIA
•Community
•Performance
•Redux compatibility
•Web Components support
•Localization
•Developer Productivity
•Hybrid App Support
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 8 2
OUR JS FRAMEWORK CRITERIA (WEIGHTED)
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 8 3
OUR JS FRAMEWORK DECISION
Option 1:
Option 2:
Option 3:
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 8 4
OUR JS FRAMEWORK DECISION
Option 1:
Option 2:
Option 3:
Try it with your team!
http://github.com/ComcastSamples/ahp-tool
Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 8 5
TAKEAWAYS
• Build with a Sacrificial Architecture
• Use Redux (or similar unidirectional data flow)
• Use Tailwind with PurgeCSS
• Demo Driven Development
• Use the Analytic Hierarchy Process for decisions
LINKS
• https://redux.js.org/
• https://redux-observable.js.org/
• https://tailwindcss.com
• https://www.purgecss.com/
• http://github.com/ComcastSamples/ahp-tool
THANK YOU!
Please send comments,
questions, or feedback
to me at @JohnRiv

More Related Content

Similar to Future-Proofing Your JavaScript Framework Decision

GraphConnect 2014 SF: From Zero to Graph in 120: Scale
GraphConnect 2014 SF: From Zero to Graph in 120: ScaleGraphConnect 2014 SF: From Zero to Graph in 120: Scale
GraphConnect 2014 SF: From Zero to Graph in 120: ScaleNeo4j
 
5 Things about fastAPI I wish we had known beforehand
5 Things about fastAPI I wish we had known beforehand5 Things about fastAPI I wish we had known beforehand
5 Things about fastAPI I wish we had known beforehandAlexander Hendorf
 
Reactive microservices with Micronaut - Greach 2018
Reactive microservices with Micronaut - Greach 2018Reactive microservices with Micronaut - Greach 2018
Reactive microservices with Micronaut - Greach 2018Alvaro Sanchez-Mariscal
 
Socket applications
Socket applicationsSocket applications
Socket applicationsJoão Moura
 
Java API for JSON Binding - Introduction and update
Java API for JSON Binding - Introduction and updateJava API for JSON Binding - Introduction and update
Java API for JSON Binding - Introduction and updateMartin Grebac
 
RESS – Responsive Webdesign and Server Side Components
RESS – Responsive Webdesign and Server Side ComponentsRESS – Responsive Webdesign and Server Side Components
RESS – Responsive Webdesign and Server Side ComponentsSven Wolfermann
 
Torquebox Asheville.rb April 2011
Torquebox Asheville.rb April 2011Torquebox Asheville.rb April 2011
Torquebox Asheville.rb April 2011Lance Ball
 
Lagergren jvmls-2014-final
Lagergren jvmls-2014-finalLagergren jvmls-2014-final
Lagergren jvmls-2014-finalMarcus Lagergren
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreEngineor
 
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analystsMeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analystsSimo Ahava
 
Migrate Early, Migrate Often: JDK release cadence strategies
Migrate Early, Migrate Often: JDK release cadence strategiesMigrate Early, Migrate Often: JDK release cadence strategies
Migrate Early, Migrate Often: JDK release cadence strategiesDanHeidinga
 
The Server Side of Responsive Web Design
The Server Side of Responsive Web DesignThe Server Side of Responsive Web Design
The Server Side of Responsive Web DesignDave Olsen
 
There is something about JavaScript - Choose Forum 2014
There is something about JavaScript - Choose Forum 2014There is something about JavaScript - Choose Forum 2014
There is something about JavaScript - Choose Forum 2014jbandi
 
Webpack & EcmaScript 6 (Webelement #32)
Webpack & EcmaScript 6 (Webelement #32)Webpack & EcmaScript 6 (Webelement #32)
Webpack & EcmaScript 6 (Webelement #32)srigi
 
Construindo aplicações com HTML5, WebSockets, e Java EE 7
Construindo aplicações com HTML5, WebSockets, e Java EE 7Construindo aplicações com HTML5, WebSockets, e Java EE 7
Construindo aplicações com HTML5, WebSockets, e Java EE 7Bruno Borges
 
Rolando Santamaría Masó - Simplicity meets scalability - code.talks 2015
Rolando Santamaría Masó - Simplicity meets scalability - code.talks 2015Rolando Santamaría Masó - Simplicity meets scalability - code.talks 2015
Rolando Santamaría Masó - Simplicity meets scalability - code.talks 2015AboutYouGmbH
 
Working with disconnected data in Windows Store apps
Working with disconnected data in Windows Store appsWorking with disconnected data in Windows Store apps
Working with disconnected data in Windows Store appsAlex Casquete
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVCAlive Kuo
 

Similar to Future-Proofing Your JavaScript Framework Decision (20)

GraphConnect 2014 SF: From Zero to Graph in 120: Scale
GraphConnect 2014 SF: From Zero to Graph in 120: ScaleGraphConnect 2014 SF: From Zero to Graph in 120: Scale
GraphConnect 2014 SF: From Zero to Graph in 120: Scale
 
5 Things about fastAPI I wish we had known beforehand
5 Things about fastAPI I wish we had known beforehand5 Things about fastAPI I wish we had known beforehand
5 Things about fastAPI I wish we had known beforehand
 
Reactive microservices with Micronaut - Greach 2018
Reactive microservices with Micronaut - Greach 2018Reactive microservices with Micronaut - Greach 2018
Reactive microservices with Micronaut - Greach 2018
 
ConSol_IBM_webcast_quarkus_the_blue_hedgehog_of_java_web_frameworks
ConSol_IBM_webcast_quarkus_the_blue_hedgehog_of_java_web_frameworksConSol_IBM_webcast_quarkus_the_blue_hedgehog_of_java_web_frameworks
ConSol_IBM_webcast_quarkus_the_blue_hedgehog_of_java_web_frameworks
 
Socket applications
Socket applicationsSocket applications
Socket applications
 
Coding Your Way to Java 12
Coding Your Way to Java 12Coding Your Way to Java 12
Coding Your Way to Java 12
 
Java API for JSON Binding - Introduction and update
Java API for JSON Binding - Introduction and updateJava API for JSON Binding - Introduction and update
Java API for JSON Binding - Introduction and update
 
RESS – Responsive Webdesign and Server Side Components
RESS – Responsive Webdesign and Server Side ComponentsRESS – Responsive Webdesign and Server Side Components
RESS – Responsive Webdesign and Server Side Components
 
Torquebox Asheville.rb April 2011
Torquebox Asheville.rb April 2011Torquebox Asheville.rb April 2011
Torquebox Asheville.rb April 2011
 
Lagergren jvmls-2014-final
Lagergren jvmls-2014-finalLagergren jvmls-2014-final
Lagergren jvmls-2014-final
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack Encore
 
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analystsMeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
 
Migrate Early, Migrate Often: JDK release cadence strategies
Migrate Early, Migrate Often: JDK release cadence strategiesMigrate Early, Migrate Often: JDK release cadence strategies
Migrate Early, Migrate Often: JDK release cadence strategies
 
The Server Side of Responsive Web Design
The Server Side of Responsive Web DesignThe Server Side of Responsive Web Design
The Server Side of Responsive Web Design
 
There is something about JavaScript - Choose Forum 2014
There is something about JavaScript - Choose Forum 2014There is something about JavaScript - Choose Forum 2014
There is something about JavaScript - Choose Forum 2014
 
Webpack & EcmaScript 6 (Webelement #32)
Webpack & EcmaScript 6 (Webelement #32)Webpack & EcmaScript 6 (Webelement #32)
Webpack & EcmaScript 6 (Webelement #32)
 
Construindo aplicações com HTML5, WebSockets, e Java EE 7
Construindo aplicações com HTML5, WebSockets, e Java EE 7Construindo aplicações com HTML5, WebSockets, e Java EE 7
Construindo aplicações com HTML5, WebSockets, e Java EE 7
 
Rolando Santamaría Masó - Simplicity meets scalability - code.talks 2015
Rolando Santamaría Masó - Simplicity meets scalability - code.talks 2015Rolando Santamaría Masó - Simplicity meets scalability - code.talks 2015
Rolando Santamaría Masó - Simplicity meets scalability - code.talks 2015
 
Working with disconnected data in Windows Store apps
Working with disconnected data in Windows Store appsWorking with disconnected data in Windows Store apps
Working with disconnected data in Windows Store apps
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
 

More from John Riviello

The Decision Buy-In Algorithm
The Decision Buy-In AlgorithmThe Decision Buy-In Algorithm
The Decision Buy-In AlgorithmJohn Riviello
 
Introduction to Web Components & Polymer Workshop - JS Interactive
Introduction to Web Components & Polymer Workshop - JS InteractiveIntroduction to Web Components & Polymer Workshop - JS Interactive
Introduction to Web Components & Polymer Workshop - JS InteractiveJohn Riviello
 
Web Components: The Future of Web Development is Here
Web Components: The Future of Web Development is HereWeb Components: The Future of Web Development is Here
Web Components: The Future of Web Development is HereJohn Riviello
 
The Critical Career Path Conversation
The Critical Career Path ConversationThe Critical Career Path Conversation
The Critical Career Path ConversationJohn Riviello
 
Ensuring Design Standards with Web Components
Ensuring Design Standards with Web ComponentsEnsuring Design Standards with Web Components
Ensuring Design Standards with Web ComponentsJohn Riviello
 
Introduction to Web Components & Polymer Workshop - U of I WebCon
Introduction to Web Components & Polymer Workshop - U of I WebConIntroduction to Web Components & Polymer Workshop - U of I WebCon
Introduction to Web Components & Polymer Workshop - U of I WebConJohn Riviello
 
Web Components: The Future of Web Development is Here
Web Components: The Future of Web Development is HereWeb Components: The Future of Web Development is Here
Web Components: The Future of Web Development is HereJohn Riviello
 
Polymer-Powered Design Systems - DevFest Florida
Polymer-Powered Design Systems - DevFest FloridaPolymer-Powered Design Systems - DevFest Florida
Polymer-Powered Design Systems - DevFest FloridaJohn Riviello
 
Workshop: Introduction to Web Components & Polymer
Workshop: Introduction to Web Components & Polymer Workshop: Introduction to Web Components & Polymer
Workshop: Introduction to Web Components & Polymer John Riviello
 
Custom Elements with Polymer Web Components #econfpsu16
Custom Elements with Polymer Web Components #econfpsu16Custom Elements with Polymer Web Components #econfpsu16
Custom Elements with Polymer Web Components #econfpsu16John Riviello
 
The Truth About Your Web App's Performance
The Truth About Your Web App's PerformanceThe Truth About Your Web App's Performance
The Truth About Your Web App's PerformanceJohn Riviello
 
The Truth About Your Web App's Performance
The Truth About Your Web App's PerformanceThe Truth About Your Web App's Performance
The Truth About Your Web App's PerformanceJohn Riviello
 

More from John Riviello (12)

The Decision Buy-In Algorithm
The Decision Buy-In AlgorithmThe Decision Buy-In Algorithm
The Decision Buy-In Algorithm
 
Introduction to Web Components & Polymer Workshop - JS Interactive
Introduction to Web Components & Polymer Workshop - JS InteractiveIntroduction to Web Components & Polymer Workshop - JS Interactive
Introduction to Web Components & Polymer Workshop - JS Interactive
 
Web Components: The Future of Web Development is Here
Web Components: The Future of Web Development is HereWeb Components: The Future of Web Development is Here
Web Components: The Future of Web Development is Here
 
The Critical Career Path Conversation
The Critical Career Path ConversationThe Critical Career Path Conversation
The Critical Career Path Conversation
 
Ensuring Design Standards with Web Components
Ensuring Design Standards with Web ComponentsEnsuring Design Standards with Web Components
Ensuring Design Standards with Web Components
 
Introduction to Web Components & Polymer Workshop - U of I WebCon
Introduction to Web Components & Polymer Workshop - U of I WebConIntroduction to Web Components & Polymer Workshop - U of I WebCon
Introduction to Web Components & Polymer Workshop - U of I WebCon
 
Web Components: The Future of Web Development is Here
Web Components: The Future of Web Development is HereWeb Components: The Future of Web Development is Here
Web Components: The Future of Web Development is Here
 
Polymer-Powered Design Systems - DevFest Florida
Polymer-Powered Design Systems - DevFest FloridaPolymer-Powered Design Systems - DevFest Florida
Polymer-Powered Design Systems - DevFest Florida
 
Workshop: Introduction to Web Components & Polymer
Workshop: Introduction to Web Components & Polymer Workshop: Introduction to Web Components & Polymer
Workshop: Introduction to Web Components & Polymer
 
Custom Elements with Polymer Web Components #econfpsu16
Custom Elements with Polymer Web Components #econfpsu16Custom Elements with Polymer Web Components #econfpsu16
Custom Elements with Polymer Web Components #econfpsu16
 
The Truth About Your Web App's Performance
The Truth About Your Web App's PerformanceThe Truth About Your Web App's Performance
The Truth About Your Web App's Performance
 
The Truth About Your Web App's Performance
The Truth About Your Web App's PerformanceThe Truth About Your Web App's Performance
The Truth About Your Web App's Performance
 

Recently uploaded

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 

Recently uploaded (20)

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 

Future-Proofing Your JavaScript Framework Decision

  • 2. 2 ?
  • 3. GOAL: Position your team so the eventual transition off the framework will involve the least amount of friction
  • 4. Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 “BEACH SAND” BY JOSH SORENSON LICENSED BY PEXELS.COM
  • 5. Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 “SACRIFICIAL ARCHITECTURE” https://martinfowler.com/bliki/SacrificialArchitecture.html “Thinking now about things that can make it easier to replace when the time comes.” - MARTIN FOWLER
  • 6. Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 1.REDUX 2.PERPETUAL CSS 3.DEMO PAGES 4.A FRAMEWORK FOR CHOOSING YOUR FRAMEWORK PATTERNS & TOOLS
  • 8. Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 UNIDIRECTIONAL DATA FLOWhttps://redux.js.org/basics/data-flow
  • 9. Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 PREDICTABLE STATE MUTATIONShttps://redux.js.org/introduction/motivation
  • 10. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 0
  • 11. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1
  • 12. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2
  • 13. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 3 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 14. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 15. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 16. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 17. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 18. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 8 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 19. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 9 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 20. Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 0 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 21. Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 1 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 22. Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 2 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } } log('OPEN_MODAL',
 'PAUSE_PERSON',
 'ABC1234');
  • 23. Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 3 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 24. Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 4 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 25. Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 5 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 26. Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 6 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 27. Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 7 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } } { … modal: { isOpen: false, } … }
  • 28. Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 8 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } } { … modal: { isOpen: true, type: 'PAUSE_PERSON', } … }
  • 29. Future-Proofing Your JavaScript Framework Decision - @JohnRiv2 9 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 30. Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 0 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 31. Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 1 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 32. Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 2 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 33. Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 3 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 34. Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 4 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } } { viewState: { modal: { isOpen: true, type: 'PAUSE_PERSON', displayName: 'Max', } } … }
  • 35. Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 5 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 36. Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 6 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 37. Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 7 { type: 'OPEN_MODAL', payload: { type: 'PAUSE_PERSON' id: 'ABC1234', } }
  • 38. Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 8
  • 39. Future-Proofing Your JavaScript Framework Decision - @JohnRiv3 9
  • 40. Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 0 { type: 'MODAL_SUBMIT', payload: { … } }
  • 41. Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 1 { type: 'MODAL_SUBMIT', payload: { … } }
  • 42. Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 2 { type: 'MODAL_SUBMIT', payload: { … } }
  • 43. Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 3 { type: 'MODAL_SUBMIT', payload: { … } }
  • 44. Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 4 { type: 'MODAL_SUBMIT', payload: { … } }
  • 45. Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 5 { type: 'MODAL_SUBMIT', payload: { … } }
  • 46. Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 6 { type: 'MODAL_SUBMIT', payload: { … } }
  • 47. Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 7 { type: 'MODAL_SUBMIT', payload: { … } }
  • 48. Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 8 { type: 'MODAL_SUBMIT', payload: { … } }
  • 49. Future-Proofing Your JavaScript Framework Decision - @JohnRiv4 9 { type: 'MODAL_SUBMIT', payload: { … } } POST /pause/ABC1234
  • 50. Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 0 { type: 'MODAL_SUBMIT', payload: { … } } log('MODAL_SUBMIT',
 'PAUSE_PERSON',
 'ABC1234');
  • 51. Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 1 { type: 'MODAL_SUBMIT', payload: { … } }
  • 52. Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 2 { type: 'MODAL_SUBMIT', payload: { … } }
  • 53. Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 3 { type: 'MODAL_SUBMIT', payload: { … } }
  • 54. Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 4 { type: 'MODAL_SUBMIT', payload: { … } }
  • 55. Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 5 { type: 'MODAL_SUBMIT', payload: { … } } { … modal: { isOpen: true, type: 'PAUSE_PERSON',
 status: 'READY', } … }
  • 56. Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 6 { type: 'MODAL_SUBMIT', payload: { … } } { … modal: { isOpen: true, type: 'PAUSE_PERSON',
 status: 'BUSY', } … }
  • 57. Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 7 { type: 'MODAL_SUBMIT', payload: { … } }
  • 58. Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 8 { type: 'MODAL_SUBMIT', payload: { … } }
  • 59. Future-Proofing Your JavaScript Framework Decision - @JohnRiv5 9 { type: 'MODAL_SUBMIT', payload: { … } }
  • 60. Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 0 { type: 'MODAL_SUBMIT', payload: { … } }
  • 61. Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 1 { type: 'MODAL_SUBMIT', payload: { … } }
  • 62. Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 2 { type: 'MODAL_SUBMIT', payload: { … } } { viewState: { modal: { isOpen: true, type: 'PAUSE_PERSON', status: 'BUSY', } } … }
  • 63. Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 3 { type: 'MODAL_SUBMIT', payload: { … } }
  • 64. Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 4 { type: 'MODAL_SUBMIT', payload: { … } }
  • 65. Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 5 { type: 'MODAL_SUBMIT', payload: { … } }
  • 66. Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 6
  • 67. Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 7 POST /pause/ABC1234 200 OK { … data … }
  • 68. Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 8 POST /pause/ABC1234 200 OK { … data … }
  • 69. Future-Proofing Your JavaScript Framework Decision - @JohnRiv6 9 POST /pause/ABC1234 200 OK { … data … }
  • 70. Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 0 POST /pause/ABC1234 200 OK { … data … }
  • 71. Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 1 POST /pause/ABC1234 200 OK { … data … }
  • 72. Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 2 POST /pause/ABC1234 200 OK { … data … }
  • 73. Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 3 POST /pause/ABC1234 200 OK { … data … }
  • 74. Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 4 POST /pause/ABC1234 200 OK { … data … }
  • 75. Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 5 POST /pause/ABC1234 200 OK { … data … }
  • 76. Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 6 POST /pause/ABC1234 200 OK { … data … }
  • 77. Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 7 POST /pause/ABC1234 200 OK { … data … } log('MODAL_SUCCESS',
 'PAUSE_PERSON',
 'ABC1234');
  • 78. Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 8 POST /pause/ABC1234 200 OK { … data … }
  • 79. Future-Proofing Your JavaScript Framework Decision - @JohnRiv7 9 POST /pause/ABC1234 200 OK { … data … }
  • 80. Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 0 POST /pause/ABC1234 200 OK { … data … }
  • 81. Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 1 POST /pause/ABC1234 200 OK { … data … }
  • 82. Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 2 POST /pause/ABC1234 200 OK { … data … } { … modal: { isOpen: true, type: 'PAUSE_PERSON',
 status: 'BUSY', } … }
  • 83. Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 3 POST /pause/ABC1234 200 OK { … data … } { … modal: { isOpen: true, type: 'PAUSE_PERSON',
 status: 'SUCCESS', } … }
  • 84. Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 4 POST /pause/ABC1234 200 OK { … data … }
  • 85. Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 5 POST /pause/ABC1234 200 OK { … data … }
  • 86. Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 6 POST /pause/ABC1234 200 OK { … data … }
  • 87. Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 7 POST /pause/ABC1234 200 OK { … data … }
  • 88. Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 8 POST /pause/ABC1234 200 OK { … data … }
  • 89. Future-Proofing Your JavaScript Framework Decision - @JohnRiv8 9 POST /pause/ABC1234 200 OK { … data … } { viewState: { modal: { isOpen: true, type: 'PAUSE_PERSON', status: 'SUCCESS', } } … }
  • 90. Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 0 POST /pause/ABC1234 200 OK { … data … }
  • 91. Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 1 POST /pause/ABC1234 200 OK { … data … }
  • 92. Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 2 POST /pause/ABC1234 200 OK { … data … }
  • 93. Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 3
  • 94. Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 4
  • 95. Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 5
  • 96. Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 6
  • 97. Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 7 client-core src/ actions/ constants/ data/ epics/ helpers/ middleware/ reducers/ selectors/ store/ index.js dist/ es5-client-core.js
  • 98. Future-Proofing Your JavaScript Framework Decision - @JohnRiv src/ actions/ constants/ data/ epics/ helpers/ middleware/ reducers/ selectors/ store/ index.js dist/ es5-client-core.js 9 8 client-core src/actions/index.js export { default as account } from './account'; export { default as app } from './app'; ... account.js app.js … index.js … src/actions/account.js export function functionOne({ ... return { /* object */ }; } export function functionTwo({ ... return { /* object */ }; } ... export default { functionOne, functionTwo, ... };
  • 99. Future-Proofing Your JavaScript Framework Decision - @JohnRiv9 9 client-core src/ actions/ constants/ data/ epics/ helpers/ middleware/ reducers/ selectors/ store/ index.js dist/ es5-client-core.js index.js import * as _actions from './src/actions'; import * as _constants from './src/constants'; import * as _data from './src/data'; import * as _epics from './src/epics'; import * as _helpers from './src/helpers'; import * as _middleware from './src/middleware'; import * as _reducer from './src/reducers'; import * as _selectors from './src/selectors'; import * as _store from './src/store'; export const actions = _actions; export const constants = _constants; export const data = _data; export const epics = _epics; export const helpers = _helpers; export const middleware = _middleware; export const reducers = _reducer; export const selectors = _selectors; export const store = _store; src/actions/index.js export { default as account } from './account'; export { default as app } from './app'; ... src/actions/account.js export function functionOne({ ... return { /* object */ }; } export function functionTwo({ ... return { /* object */ }; } ... export default { functionOne,
  • 100. Future-Proofing Your JavaScript Framework Decision - @JohnRiv src/actions/account.js export function functionOne({ ... return { /* object */ }; } export function functionTwo({ ... return { /* object */ }; } ... export default { functionOne, 1 0 0 client-core src/ actions/ constants/ data/ epics/ helpers/ middleware/ reducers/ selectors/ store/ index.js dist/ es5-client-core.js index.js import * as _actions from './src/actions'; import * as _constants from './src/constants'; import * as _data from './src/data'; import * as _epics from './src/epics'; import * as _helpers from './src/helpers'; import * as _middleware from './src/middleware'; import * as _reducer from './src/reducers'; import * as _selectors from './src/selectors'; import * as _store from './src/store'; export const actions = _actions; export const constants = _constants; export const data = _data; export const epics = _epics; export const helpers = _helpers; export const middleware = _middleware; export const reducers = _reducer; export const selectors = _selectors; export const store = _store; src/actions/index.js export { default as account } from './account'; export { default as app } from './app'; ... import clientCore from 'client-core' import {actions as coreActions} from 'client-core' import {account as accountActions} from 'client-core/actions' import {functionOne as f1} from 'client-core/actions/account' Allows for multiple ways to import the code
  • 101. Future-Proofing Your JavaScript Framework Decision - @JohnRiv src/actions/account.js export function functionOne({ ... return { /* object */ }; } export function functionTwo({ ... return { /* object */ }; } ... export default { functionOne, src/ actions/ constants/ data/ epics/ helpers/ middleware/ reducers/ selectors/ store/ index.js dist/ es5-client-core.js 1 0 1 client-core index.js import * as _actions from './src/actions'; import * as _constants from './src/constants'; import * as _data from './src/data'; import * as _epics from './src/epics'; import * as _helpers from './src/helpers'; import * as _middleware from './src/middleware'; import * as _reducer from './src/reducers'; import * as _selectors from './src/selectors'; import * as _store from './src/store'; export const actions = _actions; export const constants = _constants; export const data = _data; export const epics = _epics; export const helpers = _helpers; export const middleware = _middleware; export const reducers = _reducer; export const selectors = _selectors; export const store = _store; src/actions/index.js export { default as account } from './account'; export { default as app } from ‘./app'; ... import clientCore from 'client-core' import {actions as coreActions} from 'client-core' import {account as accountActions} from 'client-core/actions' import {functionOne as f1} from 'client-core/actions/account' Allows for multiple ways to import the code = UMD Module+
  • 102. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 0 2 YOU MIGHT NOT NEED REDUX ¯_ _/¯
  • 103. git clone --depth 1 -b template-no-redux —single-branch https://github.com/Polymer/pwa-starter-kit my-app https://pwa-starter-kit.polymer-project.org/ NO-REDUX TEMPLATE: git clone --depth 1 -b template-no-redux —single-branch https://github.com/Polymer/pwa-starter-kit my-app
  • 105. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 0 5 CSS: SO MANY OPTIONS COMPONENT-SPECIFIC •CSS-in-JS •Shadow DOM REUSABLE CLASSES •OOCSS •SMACSS •BEM THEMING WITH VARIABLES •Sass / Less / Stylus •Post CSS •CSS Custom Properties •CSS Shadow Parts UTILITY CLASSES / FUNCTIONAL CSS / ATOMIC CSS •Atomizer •Tachyons •Tailwind
  • 106. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 0 6 STANDARD APPROACH VS UTILITY CLASSES .standard { color: red; float: left; } <div class="standard"> Standard Approach </div> .text-red { color: red; } .float-left { float: left; } <div class="text-red float-left"> Utility Classes Approach </div>
  • 107. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 0 7 Example adapted from https://tailwindcss.com/docs/what-is-tailwind/ <div class="bg-white mx-auto max-w-sm shadow-lg rounded-lg overflow-hidden"> <div class="sm:flex sm:items-center px-6 py-4"> <img class="block h-16 sm:h-24 rounded-full mx-auto mb-4 sm:mb-0 sm:mr-4 sm:ml-0" src="johnriv.jpg" alt=""> <div class="text-center sm:text-left sm:flex-grow"> <div class="mb-4"> <p class="text-xl leading-tight">John Riviello</p> <p class="text-sm leading-tight text-grey-dark">Maker of web things</p> </div> <div> <button class="text-xs font-semibold rounded-full px-4 py-1 leading-normal bg- white border border-purple text-purple hover:bg-purple hover:text-white">Message</ button></div></div></div></div>
  • 108. 😱
  • 109. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 0 9 Tweet source: https://twitter.com/sindresorhus/status/1089075390327316480
  • 112. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 2 “MAN SITTING ON GRASS FIELD” BY PIXABAY LICENSED BY CC0
  • 113. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 3 Tweet source: https://twitter.com/dan_abramov/status/1089208929572319232
  • 114. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 4 “WHITE AND GREY KITTEN SMELLING WHITE DAISY FLOWER” BY ALEX BARGAIN LICENSED BY PEXELS.COM
  • 115. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 5 CSS: 😁 Easy to add 📈 😬 Hard to remove SOLUTION? TAILWIND AND…
  • 116. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 6 Purgecss https://www.purgecss.com
  • 117. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 7 CSSSTATS.COM RESULTS Current Web App Tailwind + PurgeCSS RULES 6,260 289 SELECTORS 8,422 336 DECLARATIONS 29,100 440 PROPERTIES 171 129 FONT-SIZE 1,939 13 WIDTH 682 20 HEIGHT 578 12 COLOR 2,322 44
  • 118. 🤔
  • 119. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 1 9 USING TAILWIND “HELLO WORLD” npm install tailwindcss --save-dev styles.css: @tailwind base; /* Collection of CSS Reset rules */ @tailwind components; /* Container Styles */ @tailwind utilities; /* Classes you’ll use */ npx tailwind build styles.css -o output.css
  • 120. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 0 USING TAILWIND OUTPUT.CSS FROM @TAILWIND COMPONENTS: .container { width: 100%; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } @media (min-width: 1280px) { .container { max-width: 1280px; } }
  • 121. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 1 USING TAILWIND OUTPUT.CSS FROM @TAILWIND COMPONENTS: .container { width: 100%; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } @media (min-width: 1280px) { .container { max-width: 1280px; } } Markup in your HTML: <div class="container"> container content </div> container content
  • 122. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 2 USING TAILWIND OUTPUT.CSS FROM @TAILWIND COMPONENTS: .container { width: 100%; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } @media (min-width: 1280px) { .container { max-width: 1280px; } } Markup in your HTML: <div class="container mx-auto"> container content </div> container content
  • 123. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 3 USING TAILWIND OUTPUT.CSS FROM @TAILWIND COMPONENTS: .container { width: 100%; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } @media (min-width: 1280px) { .container { max-width: 1280px; } } Markup in your HTML: <div class="container mx-auto px-8"> container content </div> container content
  • 124. Future-Proofing Your JavaScript Framework Decision - @JohnRiv Markup in your HTML: <div class="container"> container content </div> OUTPUT.CSS FROM @TAILWIND COMPONENTS: .container { width: 100%; margin-right: auto; margin-left: auto; padding-right: 2rem; padding-left: 2rem; } @media (min-width: 640px) { .container { max-width: 640px; } } @media (min-width: 768px) { .container { max-width: 768px; } } @media (min-width: 1024px) { .container { max-width: 1024px; } } ... 1 2 4 USING TAILWIND container content tailwind.config.js: module.exports = { theme: { container: { center: true, padding: '2rem', }, } } OR SET IN CONFIGURATION:
  • 125. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 5 USING TAILWIND OUTPUT.CSS FROM @TAILWIND UTILITIES: .appearance-none { -webkit-appearance: none; -moz-appearance: none; appearance: none; } .bg-fixed { background-attachment: fixed; } .bg-local { background-attachment: local; } .bg-scroll { background-attachment: scroll; } .bg-bottom { background-position: bottom; } .bg-center { background-position: center; } .bg-left { background-position: left; } .bg-left-bottom { background-position: left bottom; } .bg-left-top { background-position: left top; } .bg-right { background-position: right; } .bg-right-bottom { background-position: right bottom; } .bg-right-top { background-position: right top; } .bg-top { background-position: top; } .bg-repeat { background-repeat: repeat; } .bg-no-repeat { background-repeat: no-repeat; } .bg-repeat-x { background-repeat: repeat-x; } .bg-repeat-y { background-repeat: repeat-y; } ...
  • 126. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 6 USING TAILWIND OUTPUT.CSS FROM @TAILWIND UTILITIES - RESPONSIVE VARIANTS: @media (min-width: 640px) { .sm:appearance-none { -webkit-appearance: none; -moz-appearance: none; appearance: none; } .sm:bg-fixed { background-attachment: fixed; } .sm:bg-local { background-attachment: local; } .sm:bg-scroll { background-attachment: scroll; } .sm:bg-bottom { background-position: bottom; } .sm:bg-center { background-position: center; } .sm:bg-left { background-position: left; } .sm:bg-left-bottom { background-position: left bottom; } .sm:bg-left-top { background-position: left top; } .sm:bg-right { background-position: right; } .sm:bg-right-bottom { background-position: right bottom; } .sm:bg-right-top { background-position: right top; } .sm:bg-top { background-position: top; } .sm:bg-repeat { background-repeat: repeat; } .sm:bg-no-repeat { background-repeat: no-repeat; } .sm:bg-repeat-x { background-repeat: repeat-x; } .sm:bg-repeat-y { background-repeat: repeat-y; } ...
  • 127. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 7 USING TAILWIND OUTPUT.CSS FROM @TAILWIND UTILITIES - RESPONSIVE VARIANTS: @media (min-width: 640px) { .sm:appearance-none { -webkit-appearance: none; -moz-appearance: none; appearance: none; } .sm:bg-fixed { background-attachment: fixed; } .sm:bg-local { background-attachment: local; } .sm:bg-scroll { background-attachment: scroll; } .sm:bg-bottom { background-position: bottom; } .tablet:bg-center { background-position: center; } .sm:bg-left { background-position: left; } .sm:bg-left-bottom { background-position: left bottom; } .sm:bg-left-top { background-position: left top; } .sm:bg-right { background-position: right; } .sm:bg-right-bottom { background-position: right bottom; } .tablet:bg-right-top { background-position: right top; } .tablet:bg-top { background-position: top; } .tablet:bg-repeat { background-repeat: repeat; } .tablet:bg-no-repeat { background-repeat: no-repeat; } .tablet:bg-repeat-x { background-repeat: repeat-x; } .tablet:bg-repeat-y { background-repeat: repeat-y; } ... tailwind.config.js: module.exports = { theme: { screens: { 'tablet': '640px', // => @media (min-width: 640px) { ... } 'laptop': '1024px', // => @media (min-width: 1024px) { ... } 'desktop': '1280px', // => @media (min-width: 1280px) { ... } } } } CAN MODIFY IN CONFIGURATION:
  • 128. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 8 USING TAILWIND OUTPUT.CSS FROM @TAILWIND UTILITIES - DEFAULT COLOR PALETTE: .bg-transparent { background-color: transparent; } .bg-black { background-color: #000; } .bg-white { background-color: #fff; } .bg-gray-100 { background-color: #f7fafc; } .bg-gray-200 { background-color: #edf2f7; } .bg-gray-300 { background-color: #e2e8f0; } .bg-gray-400 { background-color: #cbd5e0; } .bg-gray-500 { background-color: #a0aec0; } .bg-gray-600 { background-color: #718096; } .bg-gray-700 { background-color: #4a5568; } .bg-gray-800 { background-color: #2d3748; } .bg-gray-900 { background-color: #1a202c; } .bg-red-100 { background-color: #fff5f5; } .bg-red-200 { background-color: #fed7d7; } .bg-red-300 { background-color: #feb2b2; } .bg-red-400 { background-color: #fc8181; } .bg-red-500 { background-color: #f56565; } .bg-red-600 { background-color: #e53e3e; } ... MANY, MANY MORE!
  • 129. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 2 9 USING TAILWIND OUTPUT.CSS FROM @TAILWIND UTILITIES - CUSTOMIZED COLOR PALETTE: .bg-transparent { background-color: transparent; } .bg-black { background-color: #000; } .bg-white { background-color: #fff; } .bg-gray-100 { background-color: #f7fafc; } .bg-gray-200 { background-color: #edf2f7; } .bg-gray-300 { background-color: #e2e8f0; } .bg-indigo { background-color: #5c6ac4; } .bg-blue { background-color: #007ace; } .bg-red { background-color: #de3618; } tailwind.config.js: module.exports = { theme: { colors: { indigo: '#5c6ac4', blue: '#007ace', red: '#de3618', } } } CAN MODIFY IN CONFIGURATION:
  • 130. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 3 0 USING TAILWIND OUTPUT.CSS FROM @TAILWIND UTILITIES - STATE VARIANTS: .bg-transparent { background-color: transparent; } .bg-black { background-color: #000; } .bg-white { background-color: #fff; } .bg-gray-100 { background-color: #f7fafc; } .bg-gray-200 { background-color: #edf2f7; } .bg-gray-300 { background-color: #e2e8f0; } .bg-indigo { background-color: #5c6ac4; } .bg-blue { background-color: #007ace; } .bg-red { background-color: #de3618; } .hover:bg-indigo:hover { background-color: #5c6ac4; } .hover:bg-blue:hover { background-color: #007ace; } .hover:bg-red:hover { background-color: #de3618; } .focus:bg-indigo:focus { background-color: #5c6ac4; } .focus:bg-blue:focus { background-color: #007ace; } .focus:bg-red:focus { background-color: #de3618; } tailwind.config.js: module.exports = { theme: { colors: { indigo: '#5c6ac4', blue: '#007ace', red: '#de3618', } } } CAN MODIFY IN CONFIGURATION:
  • 131. Future-Proofing Your JavaScript Framework Decision - @JohnRiv OUTPUT.CSS FROM @TAILWIND UTILITIES - STATE VARIANTS: .bg-transparent { background-color: transparent; } .bg-black { background-color: #000; } .bg-white { background-color: #fff; } .bg-gray-100 { background-color: #f7fafc; } .bg-gray-200 { background-color: #edf2f7; } .bg-gray-300 { background-color: #e2e8f0; } Ooh pretty colors! 1 3 1 USING TAILWIND .bg-indigo { background-color: #5c6ac4; } .bg-blue { background-color: #007ace; } .bg-red { background-color: #de3618; } .hover:bg-indigo:hover { background-color: #5c6ac4; } .hover:bg-blue:hover { background-color: #007ace; } .hover:bg-red:hover { background-color: #de3618; } .focus:bg-indigo:focus { background-color: #5c6ac4; } .focus:bg-blue:focus { background-color: #007ace; } .focus:bg-red:focus { background-color: #de3618; } tailwind.config.js: module.exports = { theme: { colors: { indigo: '#5c6ac4', blue: '#007ace', red: '#de3618', } } } CAN MODIFY IN CONFIGURATION: Markup in your HTML: <button class="bg-indigo hover:bg-blue focus:bg-red"> Ooh pretty colors! </button>
  • 132. Future-Proofing Your JavaScript Framework Decision - @JohnRiv OUTPUT.CSS FROM @TAILWIND UTILITIES - STATE VARIANTS: .bg-transparent { background-color: transparent; } .bg-black { background-color: #000; } .bg-white { background-color: #fff; } .bg-gray-100 { background-color: #f7fafc; } .bg-gray-200 { background-color: #edf2f7; } .bg-gray-300 { background-color: #e2e8f0; } Ooh pretty colors! 1 3 2 USING TAILWIND .bg-indigo { background-color: #5c6ac4; } .bg-blue { background-color: #007ace; } .bg-red { background-color: #de3618; } .hover:bg-indigo:hover { background-color: #5c6ac4; } .hover:bg-blue:hover { background-color: #007ace; } .hover:bg-red:hover { background-color: #de3618; } .focus:bg-indigo:focus { background-color: #5c6ac4; } .focus:bg-blue:focus { background-color: #007ace; } .focus:bg-red:focus { background-color: #de3618; } tailwind.config.js: module.exports = { theme: { colors: { indigo: '#5c6ac4', blue: '#007ace', red: '#de3618', } } } CAN MODIFY IN CONFIGURATION: Markup in your HTML: <button class="bg-indigo hover:bg-blue focus:bg-red"> Ooh pretty colors! </button>
  • 133. Future-Proofing Your JavaScript Framework Decision - @JohnRiv OUTPUT.CSS FROM @TAILWIND UTILITIES - STATE VARIANTS: .bg-transparent { background-color: transparent; } .bg-black { background-color: #000; } .bg-white { background-color: #fff; } .bg-gray-100 { background-color: #f7fafc; } .bg-gray-200 { background-color: #edf2f7; } .bg-gray-300 { background-color: #e2e8f0; } Ooh pretty colors! 1 3 3 USING TAILWIND .bg-indigo { background-color: #5c6ac4; } .bg-blue { background-color: #007ace; } .bg-red { background-color: #de3618; } .hover:bg-indigo:hover { background-color: #5c6ac4; } .hover:bg-blue:hover { background-color: #007ace; } .hover:bg-red:hover { background-color: #de3618; } .focus:bg-indigo:focus { background-color: #5c6ac4; } .focus:bg-blue:focus { background-color: #007ace; } .focus:bg-red:focus { background-color: #de3618; } tailwind.config.js: module.exports = { theme: { colors: { indigo: '#5c6ac4', blue: '#007ace', red: '#de3618', } } } CAN MODIFY IN CONFIGURATION: Markup in your HTML: <button class="bg-indigo hover:bg-blue focus:bg-red"> Ooh pretty colors! </button>
  • 134. Future-Proofing Your JavaScript Framework Decision - @JohnRiv YOUR CSS FUTURE? 1 3 4 Purgecss =+ LINKS • Tailwind Docs: https://next.tailwindcss.com/ • PurgeCSS: https://www.purgecss.com/ • Tailwind Container: https://next.tailwindcss.com/docs/container/ • Tailwind Configuration: https://next.tailwindcss.com/docs/configuration • Tailwind Responsive Design: https://next.tailwindcss.com/docs/responsive-design • Tailwind Colors: https://next.tailwindcss.com/docs/colors • Tailwind State Variants: https://next.tailwindcss.com/docs/state-variants/ 📉
  • 136. DDD
  • 138. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 3 8 https://react-styleguidist.js.org/examples/basic/
  • 139. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 3 9 https://react-styleguidist.js.org/docs/documenting.html
  • 141. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 1 “LANDSCAPE PHOTOGRAPHY OF FACTORY” BY PIXABAY LICENSED BY CC0
  • 142. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 2 ANALYTIC HIERARCHY PROCESS by Thomas L. Saaty
  • 143. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 3 ANALYTIC HIERARCHY PROCESS (AHP) Goal: Criteria: Alternatives: CHOOSE THE MOST SUITABLE LEADER CHARISMA RAMÓN EDUCATIONEXPERIENCE INTEGRITY KATE PAUL
  • 144. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 4 ANALYTIC HIERARCHY PROCESS (AHP) Goal: Criteria: Alternatives: CHOOSE THE MOST SUITABLE LEADER CHARISMA RAMÓN EDUCATIONEXPERIENCE INTEGRITY KATE PAUL
  • 145. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 5 AHP FUNDAMENTAL SCALE FOR PAIRWISE COMPARISONS Intensity of Importance Definition Explanation 1 Equal importance Two elements contribute equally to the objective 3 Moderate importance Experience and judgement moderately favor one element over another 5 Strong importance Experience and judgement strongly favor one element over another 7 Very strong importance One element is favored very strongly over another; its dominance is demonstrated in practice 9 Extreme importance The evidence favoring one element 
 over another is of the highest possible order of affirmation https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Pairwise_comparisons Intensities of 2, 4, 6, and 8 can be used to express intermediate values. 1.1, 1.2, 1.3, etc. can be used for elements that are very close in importance.
  • 146. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 6 AHP PAIRWISE SCORING https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Alternatives_vs._criteria Alternatives compared with respect to EXPERIENCE RAMÓN 1 KATE 4 RAMÓN 4 PAUL 1 KATE 9 PAUL 1
  • 147. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 7 AHP RECIPROCAL SCORING EXPERIENCE RAMÓN KATE PAUL RAMÓN 1 1/4 4 KATE 4 1 9 PAUL 1/4 1/9 1 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Alternatives_vs._criteria
  • 148. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 8 AHP MATRIX PRIORITY CALCULATIONS EXPERIENCE RAMÓN KATE PAUL PRIORITY RAMÓN 1 1/4 4 0.2 1 7 KATE 4 1 9 0.7 1 7 PAUL 1/4 1/9 1 0.066 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Alternatives_vs._criteria
  • 149. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 4 9 AHP MATRIX PRIORITY CALCULATIONS EXPERIENCE RAMÓN KATE PAUL PRIORITY RAMÓN 1 1/4 4 0.2 1 7 KATE 4 1 9 0.7 1 7 PAUL 1/4 1/9 1 0.066 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Alternatives_vs._criteria
  • 150. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 0 ANALYTIC HIERARCHY PROCESS (AHP) Goal: Criteria: Alternatives: CHOOSE THE MOST SUITABLE LEADER CHARISMA RAMÓN EDUCATIONEXPERIENCE INTEGRITY KATE PAUL 0.217 0.717 0.066
  • 151. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 1 ANALYTIC HIERARCHY PROCESS (AHP) Goal: Criteria: Alternatives: CHOOSE THE MOST SUITABLE LEADER CHARISMA RAMÓN EDUCATIONEXPERIENCE INTEGRITY KATE PAUL
  • 152. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 2 ANALYTIC HIERARCHY PROCESS (AHP) Goal: Criteria: Alternatives: CHOOSE THE MOST SUITABLE LEADER EDUCATIONEXPERIENCE INTEGRITYCHARISMA RAMÓN KATE PAUL
  • 153. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 3 ANALYTIC HIERARCHY PROCESS (AHP) Goal: Criteria: Alternatives: CHOOSE THE MOST SUITABLE LEADER CHARISMAEDUCATIONEXPERIENCE RAMÓN INTEGRITY KATE PAUL
  • 154. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 4 ANALYTIC HIERARCHY PROCESS (AHP) Goal: Criteria: Alternatives: CHOOSE THE MOST SUITABLE LEADER CHARISMAEDUCATIONEXPERIENCE RAMÓN INTEGRITY KATE PAUL
  • 155. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 5 AHP MATRIX PRIORITY CALCULATIONS CRITERIA EXPERIENCE EDUCATION CHARISMA INTEGRITY PRIORITY EXPERIENCE 1 4 3 7 0.547 EDUCATION 1/4 1 1/3 3 0.127 CHARISMA 1/3 3 1 5 0.270 INTEGRITY 1/7 1/3 1/5 1 0.056 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Criteria_vs._the_Goal
  • 156. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 6 ANALYTIC HIERARCHY PROCESS (AHP) Goal: Criteria: Alternatives: CHOOSE THE MOST SUITABLE LEADER CHARISMA RAMÓN EDUCATIONEXPERIENCE INTEGRITY KATE PAUL
  • 157. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 7 AHP MATRIX PRIORITY CALCULATIONS CRITERIA EXPERIENCE EDUCATION CHARISMA INTEGRITY PRIORITY EXPERIENCE 1 4 3 7 0.547 EDUCATION 1/4 1 1/3 3 0.127 CHARISMA 1/3 3 1 5 0.270 INTEGRITY 1/7 1/3 1/5 1 0.056 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Criteria_vs._the_Goal
  • 158. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 8 ANALYTIC HIERARCHY PROCESS (AHP) Goal: Criteria: Alternatives: CHOOSE THE MOST SUITABLE LEADER CHARISMA RAMÓN EDUCATIONEXPERIENCE INTEGRITY KATE PAUL 0.547
  • 159. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 5 9 AHP MATRIX PRIORITY CALCULATIONS EXPERIENCE RAMÓN KATE PAUL PRIORITY RAMÓN 1 1/4 4 0.2 1 7 KATE 4 1 9 0.7 1 7 PAUL 1/4 1/9 1 0.066 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Alternatives_vs._criteria
  • 160. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 0 ANALYTIC HIERARCHY PROCESS (AHP) Goal: Criteria: Alternatives: CHOOSE THE MOST SUITABLE LEADER CHARISMA RAMÓN EDUCATIONEXPERIENCE INTEGRITY KATE PAUL 0.547 0.217 0.717 0.066
  • 161. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 1 AHP FINAL PRIORITY CALCULATIONS EXPERIENCE PRIORITY PRIORITY
 vs. GOAL PRIORITY with respect to EXPERIENCE RAMÓN 0.2 1 7 KATE 0.7 1 7 PAUL 0.066 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
  • 162. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 2 ANALYTIC HIERARCHY PROCESS (AHP) Goal: Criteria: Alternatives: CHOOSE THE MOST SUITABLE LEADER CHARISMA RAMÓN EDUCATIONEXPERIENCE INTEGRITY KATE PAUL 0.547 0.217 0.717 0.066
  • 163. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 3 AHP FINAL PRIORITY CALCULATIONS EXPERIENCE PRIORITY PRIORITY
 vs. GOAL PRIORITY with respect to EXPERIENCE RAMÓN 0.2 1 7 0.547 KATE 0.7 1 7 0.547 PAUL 0.066 0.547 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
  • 164. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 4 AHP FINAL PRIORITY CALCULATIONS EXPERIENCE PRIORITY PRIORITY
 vs. GOAL PRIORITY with respect to EXPERIENCE RAMÓN 0.2 1 7 0.547 KATE 0.7 1 7 0.547 PAUL 0.066 0.547 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities x x x
  • 165. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 5 AHP FINAL PRIORITY CALCULATIONS EXPERIENCE PRIORITY PRIORITY
 vs. GOAL PRIORITY with respect to EXPERIENCE RAMÓN 0.2 1 7 0.547 0.1 1 9 KATE 0.7 1 7 0.547 0.392 PAUL 0.066 0.547 0.036 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities x x x = = =
  • 166. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 6 AHP FINAL PRIORITY CALCULATIONS EXPERIENCE PRIORITY PRIORITY
 vs. GOAL PRIORITY with respect to EXPERIENCE RAMÓN 0.2 1 7 0.547 0.1 1 9 KATE 0.7 1 7 0.547 0.392 PAUL 0.066 0.547 0.036 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities x x x = = =
  • 167. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 7 AHP FINAL PRIORITY CALCULATIONS CANDIDATE PRIORITY with respect to EXPERIENCE PRIORITY with respect to EDUCATION PRIORITY with respect to CHARISMA PRIORITY with respect to INTEGRITY PRIORITY with respect to GOAL RAMÓN KATE PAUL https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
  • 168. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 8 AHP FINAL PRIORITY CALCULATIONS CANDIDATE PRIORITY with respect to EXPERIENCE PRIORITY with respect to EDUCATION PRIORITY with respect to CHARISMA PRIORITY with respect to INTEGRITY PRIORITY with respect to GOAL RAMÓN 0.1 1 9 KATE 0.392 PAUL 0.036 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
  • 169. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 6 9 AHP FINAL PRIORITY CALCULATIONS CANDIDATE PRIORITY with respect to EXPERIENCE PRIORITY with respect to EDUCATION PRIORITY with respect to CHARISMA PRIORITY with respect to INTEGRITY PRIORITY with respect to GOAL RAMÓN 0.1 1 9 0.024 0.201 0.015 KATE 0.392 0.010 0.052 0.038 PAUL 0.036 0.093 0.017 0.004 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities
  • 170. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 0 AHP FINAL PRIORITY CALCULATIONS CANDIDATE PRIORITY with respect to EXPERIENCE PRIORITY with respect to EDUCATION PRIORITY with respect to CHARISMA PRIORITY with respect to INTEGRITY PRIORITY with respect to GOAL RAMÓN 0.1 1 9 0.024 0.201 0.015 KATE 0.392 0.010 0.052 0.038 PAUL 0.036 0.093 0.017 0.004 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities = = = + + + + + + + + +
  • 171. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 1 AHP FINAL PRIORITY CALCULATIONS CANDIDATE PRIORITY with respect to EXPERIENCE PRIORITY with respect to EDUCATION PRIORITY with respect to CHARISMA PRIORITY with respect to INTEGRITY PRIORITY with respect to GOAL RAMÓN 0.1 1 9 0.024 0.201 0.015 0.358 KATE 0.392 0.010 0.052 0.038 0.492 PAUL 0.036 0.093 0.017 0.004 0.149 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities = = = + + + + + + + + +
  • 172. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 2 AHP FINAL PRIORITY CALCULATIONS CANDIDATE PRIORITY with respect to EXPERIENCE PRIORITY with respect to EDUCATION PRIORITY with respect to CHARISMA PRIORITY with respect to INTEGRITY PRIORITY with respect to GOAL RAMÓN 0.1 1 9 0.024 0.201 0.015 0.358 KATE 0.392 0.010 0.052 0.038 0.492 PAUL 0.036 0.093 0.017 0.004 0.149 https://en.wikipedia.org/wiki/Analytic_hierarchy_process_–_leader_example#Synthesizing_final_priorities = = = + + + + + + + + +
  • 173. “SURVEY ICON” BY PIXABAY LICENSED BY CC0
  • 174. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 4 “FOUR PERSON HOLDING BULB LIGHT DECORS” BY RAWPIXEL.COM LICENSED BY PEXELS.COM
  • 175. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 5 “HAWAII HANA ROAD” BY PIXABAY LICENSED BY CC0
  • 176. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 6 “WELCOME TO HANA” BY KIRT EDBLOM LICENSED BY CC BY-SA 2.0
  • 177. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 7 “HANA BEACH PARK” BY TRAVIS THURSTON LICENSED BY CC BY-SA 3.0
  • 178. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 8 “HANA BEACH PARK” BY TRAVIS THURSTON LICENSED BY CC BY-SA 3.0 IT’S THE JOURNEY, NOT THE DESTINATION
  • 179. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 7 9 “HANA BEACH PARK” BY TRAVIS THURSTON LICENSED BY CC BY-SA 3.0 IT’S THE JOURNEY, AND THE DESTINATION
  • 180. HOW DID OUR TEAM DECIDE?
  • 181. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 8 1 OUR JS FRAMEWORK CRITERIA •Community •Performance •Redux compatibility •Web Components support •Localization •Developer Productivity •Hybrid App Support
  • 182. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 8 2 OUR JS FRAMEWORK CRITERIA (WEIGHTED)
  • 183. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 8 3 OUR JS FRAMEWORK DECISION Option 1: Option 2: Option 3:
  • 184. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 8 4 OUR JS FRAMEWORK DECISION Option 1: Option 2: Option 3: Try it with your team! http://github.com/ComcastSamples/ahp-tool
  • 185. Future-Proofing Your JavaScript Framework Decision - @JohnRiv1 8 5 TAKEAWAYS • Build with a Sacrificial Architecture • Use Redux (or similar unidirectional data flow) • Use Tailwind with PurgeCSS • Demo Driven Development • Use the Analytic Hierarchy Process for decisions LINKS • https://redux.js.org/ • https://redux-observable.js.org/ • https://tailwindcss.com • https://www.purgecss.com/ • http://github.com/ComcastSamples/ahp-tool THANK YOU! Please send comments, questions, or feedback to me at @JohnRiv