`You might not need

${framework}`

A Case for Vanilla

in the Browser

and micro-libraries

Let's Talk

Terms

first,

platform: whatever pre-existing environment a piece of computer software or code object is designed to run within, obeying its constraints, and making use of its facilities

bloat: a program being perceptibly slower, using more memory, disk space or processing power, or have higher hardware requirements than needed—whilst making only dubious user-perceptible improvements

cargo-culting:  the ritual inclusion of code or program structures that serve no real purpose.  …Copy some program code from one place to another with little or no understanding of how it works or whether it is required in its new position.

user-centric design:  optimize the product around how users can, want, or need to use the product, rather than forcing the users to change their behavior to accommodate the product.

Do we ever cargo-cult code into new projects which contains bloat and that provides no end-user value?

Why Vanilla?

Let's Pretend....

  • The web is the platform of accessibility
  • We work for a global organization
  • We need to reach ALL people
  • Bandwidth costs money
  • There are [mb]illions of people without fast Internet
  • Success is measured by end-user experience
  • Our products aren't super complex
  • We have to work within end-user budgets

What value does `${framework}` provide?

  • Quick and Easy Development *
  • Abstract away browser complexities**
  • Tested
  • A common development platform***
  • Other things end-user doesn't care about?

*restrictions apply (to every project ever)

value provided to developer, not end-user

**introduces tribal complexities instead

***if only there was already a platform...

So are `${frameworks}` bad?

No

But do you ALWAYS need one?

And do they come at a cost?

Budgets

end-user

Bandwidth Costs Money

Average Cost / Page

http://whatdoesmysitecost.com/

According to the August 15, 2015 run of HTTP Archive, the average site now weighs 2169kb

How do we compare?

Performance Budgets

https://developers.google.com/web/tools/profile-performance/evaluate-performance/rail?hl=en

  • Response - 100ms to respond to user input before they notice a lag
  • Animation - render frames every 16ms
  • Idle - Use idle time to complete deferred work.
  • Load - deliver content under 1000ms

The RAIL Performance Model

a user-centric performance model.

How much of your load budget does `${framework}` use?

Page Load Times -- One Page with:

no images / media, limited markup, just the core files of the following -- gzipped and minified

simulating 3G ~ 1MB/s, macbook pro, chrome

`${framework}` load time -- no cache
(% budget)
load time -- cache
(% budget)
jQuery 364ms 107ms
Bootstrap JS 143ms 49ms
Bootstrap CSS 304ms 77ms
Bootstrap Glyphs 135ms 85ms
Page 747ms (74%) 261ms (26%)
`${framework}` load time -- no cache
(% budget)
load time -- cache
(% budget)
jQuery 553ms 65ms
Bootstrap JS 400ms 69ms
Bootstrap CSS 400ms 62ms
Bootstrap Glyphs 272ms 50ms
Angular Core 733ms 79ms
Page 847ms (85%) 319ms (32%)

Page Load Times -- One Page With:

no images / media, limited markup, just the core files of the following -- gzipped and minified

simulating 3G ~ 1MB/s, macbook pro, chrome

YMMV

  • powerful "desktop" hardware
  • in Chrome
  • emulating "Good 3G"
  • lab conditions
  • no content

Platforms?

Browser (HTML, CSS, JavaScript, etc)

jQuery Core

jQuery Extensions

Bootstrap.JS

used code

bloat

Browser (HTML, CSS, JavaScript, etc)

Bootstrap Core CSS

Bootstrap Theme

used code

bloat

Browser (HTML, CSS, JavaScript, etc)

Angular Core

Angular Modules

used code

bloat

Browser (HTML, CSS, JavaScript, etc)

jQuery

jQ Plugin

jQ Plugin

jQ Plugin

jQ UI

Bootstrap JS

Angular

NG Module

NG Module

NG Module

NG Module

BS CSS

BS Theme

BS Glyphs

What's Missing?

Browser (HTML, CSS, JavaScript, etc)

jQuery

jQ Plugin

jQ Plugin

jQ Plugin

jQ UI

Bootstrap JS

Angular

NG Module

NG Module

NG Module

NG Module

BS CSS

BS Theme

BS Glyphs

my-app.js

my-app.css

app assets

Content

Browser (HTML, CSS, JavaScript, etc)

my-app.js

my-app.css

app assets

Content

so, is this possible?

Browser (HTML, CSS, JavaScript, etc)

my-app.js

my-app.css

app assets

Content

Is

this

really that bad...

jQuery

jQ Plugin

jQ Plugin

jQ Plugin

jQ UI

Bootstrap JS

Angular

NG Module

NG Module

NG Module

NG Module

BS CSS

BS Theme

BS Glyphs

...that we have to put all this in between?

"Blah Blah Browser Support"

Oh, you mean IE?

https://en.wikipedia.org/wiki/Usage_share_of_web_browsers

specifically old IE?

http://www.w3counter.com/globalstats.php?year=2015&month=8 

Answer 1: Polyfills

How are Polyfills different than my `${framework}`?

freshness in TTRs (tm)

app lifecycle in days

dhtml

angular 1

polyfill

How fresh for an app released today (9/23/15)?

  1. DHTML
  2. NG1
  3. Native w/ Polyfill

TTR: time 'til refactor

Answer 2: maybe the game has changed?

Everything is Evergreen

Global Explosion of Smartphone / Mobile Usage

[imagine fancy chart]

ppl have modern devices with weak infrastucture

https://en.wikipedia.org/wiki/Global_Internet_usage

maybe infrastructure is

the new IE6?

statistically speaking

But... But... Content Editors

They're just gonna upload 30MB .tif files anyway

So why bother?

penny-pinching

just like IRL budgets, getting ahead is mostly about discipline &

unfortunately

not lottery-winning

How Vanilla?

1) The Basics

vs

Polyfill Loader

but first:

Hands On

https://ymnnf.app.lds.org/hands-on/polyfill/

https://ymnnf.app.lds.org/hands-on/polyfill/all.html

Basic Loader

function polyfill(isNeeded, src) {
    
    if(isNeeded) {
      var script = document.createElement('script');
      script.setAttribute('src', src);
      document.head.appendChild(script);
    }

}

polyfill(typeof window.CustomEvent !== "function", 'polyfills/customevent.min.js');

$(someFunction);

aka: execute when the DOM is ready but before window.load

document.addEventListener('DOMContentLoaded', someFunction);

$('.selector')

Hands On

https://ymnnf.app.lds.org/hands-on/query-selector/

 

https://ymnnf.app.lds.org/hands-on/query-selector-all/

querySelector

  • document.querySelectorAll('.selector) returns a NodeList
  • get into habit of coercing it into Array
  • Available on document and each element
  • Returns first matching Element or null
  • Always check if truthy before operating on results
  • Available on document and each element

querySelectorAll

Support

Polyfill

IE6+

modern browsers & IE8+

References

https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

 

https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll

 

https://developer.mozilla.org/en-US/docs/Web/API/element

.addClass()

.removeClass()

.toggleClass()

element.classList.add()

element.classList.remove()

element.classList.toggle()

Hands On

https://ymnnf.app.lds.org/hands-on/class-list/

Support

Polyfill

IE8+

modern browsers & IE10+

https://developer.mozilla.org/en-US/docs/Web/API/Element/classList

References

Bulk manipulation

jQuery's default behavior after $('.selector'). Also .each()

Also, how about item filtering?

jQuery's .filter(), .is(), eq(), etc.

Use built-in Array methods

[].map

[].filter

[].reduce

If you don't know them, then you're overdue...

 

 

https://feddlers.ldschurch.org/donuts.js/js/javascript/arrays/2015/03/17/javascript-fundementals-arrays-pt-2.html

 

https://feddlers.ldschurch.org/donuts.js/js/javascript/arrays/2015/02/25/javascript-fundementals-arrays-pt-1.html

 

Support

Polyfill

*

modern browsers & IE9+

Learn More

 

 

https://feddlers.ldschurch.org/donuts.js/js/javascript/arrays/2015/03/17/javascript-fundementals-arrays-pt-2.html

 

https://feddlers.ldschurch.org/donuts.js/js/javascript/arrays/2015/02/25/javascript-fundementals-arrays-pt-1.html

 

 

 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

.hide()

.show()

toggle()

.fadeIn()

Etc.

aka: toggling / animating item visibility

Hands On

https://ymnnf.app.lds.org/hands-on/item-visibility/

JavaScript: trigger state changes.

 

CSS: style states & transitions between them

 

Support

Polyfill

modern browsers & IE10+

IE8+

.on('ev', fn)

.addEventListener('ev', fn);

.trigger('custom', [data])

Hands On

https://ymnnf.app.lds.org/hands-on/custom-event/

new CustomEvent('custom', {detail: data})*

.dispatchEvent(customEvObj);*

+

*unless you want to know the internal workings, you should abstract away the details

Support

Polyfill

modern browsers

IE9+ with Polyfill*

IE9+

https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent

deferred & promise

Native Promise

Polyfill

All & IE9+

 

 

https://github.com/jakearchibald/es6-promise

$.get()

$.getJSON

Other AJAX

window.fetch()

Built-in Support

Polyfill*

Must Also Polyfill Promise

$.extend()

Object.assign()

Support

Polyfill

* with a little more effort, can be polyfilled further back as well

References

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

Much More

http://youmightnotneedjquery.com/

http://youmightnotneedjqueryplugins.com/

http://microjs.com/#

More to come...

  • ES6/ES7 syntax & features
  • Native Web Components
  • Object.observe

Vanilla vs NG?