SlideShare a Scribd company logo
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: Scale
Neo4j
 
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
Alexander Hendorf
 
Reactive microservices with Micronaut - Greach 2018
Reactive microservices with Micronaut - Greach 2018Reactive microservices with Micronaut - Greach 2018
Reactive microservices with Micronaut - Greach 2018
Alvaro Sanchez-Mariscal
 
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
ConSol Consulting & Solutions Software GmbH
 
Socket applications
Socket applicationsSocket applications
Socket applications
João Moura
 
Coding Your Way to Java 12
Coding Your Way to Java 12Coding Your Way to Java 12
Coding Your Way to Java 12
Sander Mak (@Sander_Mak)
 
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
Martin 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 Components
Sven Wolfermann
 
Torquebox Asheville.rb April 2011
Torquebox Asheville.rb April 2011Torquebox Asheville.rb April 2011
Torquebox Asheville.rb April 2011
Lance Ball
 
Lagergren jvmls-2014-final
Lagergren jvmls-2014-finalLagergren jvmls-2014-final
Lagergren jvmls-2014-final
Marcus Lagergren
 
AFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack EncoreAFUP Lorraine - Symfony Webpack Encore
AFUP Lorraine - Symfony Webpack Encore
Engineor
 
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
Simo 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 strategies
DanHeidinga
 
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
Dave 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 2014
jbandi
 
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 7
Bruno 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 2015
AboutYouGmbH
 
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
Alex Casquete
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
Alive 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 Algorithm
John 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 Interactive
John 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 Here
John Riviello
 
The Critical Career Path Conversation
The Critical Career Path ConversationThe Critical Career Path Conversation
The Critical Career Path Conversation
John Riviello
 
Ensuring Design Standards with Web Components
Ensuring Design Standards with Web ComponentsEnsuring Design Standards with Web Components
Ensuring Design Standards with Web Components
John 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 WebCon
John 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 Here
John Riviello
 
Polymer-Powered Design Systems - DevFest Florida
Polymer-Powered Design Systems - DevFest FloridaPolymer-Powered Design Systems - DevFest Florida
Polymer-Powered Design Systems - DevFest Florida
John 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 #econfpsu16
John 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 Performance
John 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 Performance
John 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

HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
panagenda
 
What is an RPA CoE? Session 1 – CoE Vision
What is an RPA CoE?  Session 1 – CoE VisionWhat is an RPA CoE?  Session 1 – CoE Vision
What is an RPA CoE? Session 1 – CoE Vision
DianaGray10
 
JavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green MasterplanJavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green Masterplan
Miro Wengner
 
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge GraphGraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
Neo4j
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
Y-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PPY-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PP
c5vrf27qcz
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
Edge AI and Vision Alliance
 
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
Edge AI and Vision Alliance
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
saastr
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
Jason Yip
 
Mutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented ChatbotsMutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented Chatbots
Pablo Gómez Abajo
 
AppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSFAppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSF
Ajin Abraham
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Alpen-Adria-Universität
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
Zilliz
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
Zilliz
 

Recently uploaded (20)

HCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAUHCL Notes and Domino License Cost Reduction in the World of DLAU
HCL Notes and Domino License Cost Reduction in the World of DLAU
 
What is an RPA CoE? Session 1 – CoE Vision
What is an RPA CoE?  Session 1 – CoE VisionWhat is an RPA CoE?  Session 1 – CoE Vision
What is an RPA CoE? Session 1 – CoE Vision
 
JavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green MasterplanJavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green Masterplan
 
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge GraphGraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
Y-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PPY-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PP
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
“Temporal Event Neural Networks: A More Efficient Alternative to the Transfor...
 
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
 
Mutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented ChatbotsMutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented Chatbots
 
AppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSFAppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSF
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
 
Generating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and MilvusGenerating privacy-protected synthetic data using Secludy and Milvus
Generating privacy-protected synthetic data using Secludy and Milvus
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
Programming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup SlidesProgramming Foundation Models with DSPy - Meetup Slides
Programming Foundation Models with DSPy - Meetup Slides
 

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