Here is a highlighted overview of the major points from some of my favorite EmberConf 2017 talks:
DAY 1
Opening Keynote - Yehuda Katz, Tom Dale
- 5 Years of EmberConf!
- Announcing Amber.js - Dec 8, 2011
- New core team members
- Ember 2.x Series
- What have we learned?
- Big up front design
- Small Kernel → Addon
- Fastboot - Ember simply landed the
App.visit()
API → ember-fastboot addon
- Fastboot - Ember simply landed the
- Drop-in compatibility for new features
- Experimentation is key
- Glimmer 2.0
- Pre Glimmer: Less modular than we thought - Ember + HTMLBars
- Extract and rationalize - Ember view layer + Glimmer
- 2.10 was a drop-in replacement for 2.9
- Test suite runs on both the old engine and the new engine at the same time
- Architecture: wire format
[[11, 'div'], [11, 'span'][1, [33,'hello']...]
- Reduce “In-Browser” work
- Take advantage of declarative nature
- Glimmer VM
- Web problem: Boot fast AND stay fast once booted
- You can go the fastest if you don’t care about updating
- The truth about traditional JavaScript benchmarks
- Ember Community Survey
-
Glimmer.js
- Rendering engine used to power Ember → Now can be used standalone
- Bind dynamic content from component to template without esoteric naming systems
- TypeScript + Ember!
- Computed property accessors
- Decorators
- “Just JS” actions
- No more
.get
or.set
- This is the component API we want for Ember’s Custom Component API RFC
-
Module Unification RFC already merged - implementation has begun
- Links the Ember and Glimmer worlds together
- Write in Glimmer, drop into Ember app
Going Progressive with Ember - Samanta de Barros
-
Progressive Web Apps
- Fast
- Work offline
- Install on the device
- 69% of web traffic today comes from smartphone devices
- Native vs. Web
- Gap is rapidly shrinking
- Web app manifest JSON
- Currently, only chrome support
- iOS needs custom
<meta>
tags in<head>
- Windows needs an extra browser config file
-
ember-web-app -
ember install ember-web-app
- Generates all of these files for you and related
<meta>
tags
- Generates all of these files for you and related
- Service Worker
- is serviceworker ready?
- Intercepts every request
- Save assets on install event
- Background sync
- Push notifications API
- ember-service-worker
-
broccoli-serviceworker
- Generates SW based on config
- Application cache
- Works on all browsers
- broccoli-manifest
- User data offline?
- Local storage, WebSQL, IndexedDB
- Local Forage - Wraps all 3
- ember-localforage-adapter
- ember-pouch
- First page render
- Lighthouse - Chrome extension
A Neurobiologist’s Guide to Mind Manipulation - Casey Watts
- caseywatts.com/mindmanipulation - Print items in purple
- Cognitive restructuring
- “In-moment” vs “Reflecting”
- How the brain works
- Inner vs Outer brain
- Inner - Old, limbic system, fast ~ms
- Outer - Cortex, thoughts, slow ~s
- Brain as a system
- Feedback loop: input → process → output
- Autopilot: input → output (no process)
- Automatic thoughts/feelings vs. Deliberate thoughts/feelings
- CBT - Cognitive Behavioral Therapy
npm install constant-introspection
- 0 Whoop (introspect)
- → 1 Input (how did I get here?/current bodily state)
- → 2 Emotions & Thoughts (expand emotional vocabulary/emotion processing techniques)
- → 3 Response
- Unhelpful Thoughts
- Other tools
- Therapist
- Book: Feeling Good by David D. Burns
- Headspace (app)
- Joyable (webapp)
- Psychological Safety
- PsycSafe Group: current members feel safe
- PsycSafe Traits: Communication & Empathy
- Making the team feel more PsycSafe → raise collective group IQ
- Goal: Improving Team PsycSafety
- Communication
- Earned Dogmatism Effect: “I am experienced, therefore my idea is right”
- Reveal there is information missing
- Declare Unknowns: “We don’t fully understand X yet”
- “We don’t know how complicated auth will be!”
- Framing: “learning opportunity” not “BAD WRONG BAD”
- Server went down - learning opportunity to improve
- Acknowledge Fallibility: “I make mistakes and I know it - tell me what you notice”
- Model Curiosity: Ask many questions
- Earned Dogmatism Effect: “I am experienced, therefore my idea is right”
- Empathy
- Propinquity: Social closeness
- Task: “[potential issues]” vs. Relationship: “You aren’t competent”
- PEARLS - Partnership, Empathy, Acknowledgement, Respect, Legitimation, Support
- Validation: Recognition and acceptance of another person’s [thoughts, feelings, sensations, and behaviors] as understandable (even if you don’t agree)
- Depersonalize Ideas - “Idea A” not “Casey’s Idea”
- Vulnerability: Increases trust
- Communication
Understanding JavaScript Performance - Godfrey Chan
- Hierarchy of Speed
- Laws of Physics (base) → Hardware → Kernels → User-land → Human Factors (top)
- Everything above builds on the layers below
- Hierarchy of JS Performance
- JS Engines (base) → Libraries → Your Code (top)
factoryFor
RFC- Deprecate component
eventManger
RFC - Framework
- Time Budget
- 1,000ms initial render
- JS Engines - nanoseconds (50 nanoseconds 10,000,000x)
let obj = {}
- Written in C
- JS - Everything is a dictionary
- Hidden class “Shape” / “Map”
- Tools
- Native syntax -
node --trace_opt --trace_deopt --allow-natives-syntax my-script.js
- Native syntax -
- Libraries - microseconds (50 microseconds 10,000x)
Ember.get()
- Written in JS, Called many times, Generic code
- Tools
- CPU Profiler, Flame graphs
- Your Code - milliseconds ~ seconds (50ms 10x)
{{my-component}}
- Problems: Hidden loops
- Big Data
- Download time, Parse time, Compounding
- Backtracking - Invalidating already flushed content
- Error since Ember 2.10
- Big Data
- Tools
- Network tab, Timeline view (Chrome), User Timing API
- Micro vs Macro
- Macro: Do fewer things - improve this layer
- Don’t do the work, Reuse the work, Defer the work
- Micro: Do faster things - help the next layer
- Use helpers,
{{unbound}}
, Custom components
- Use helpers,
- Macro: Do fewer things - improve this layer
- Time Budget
- ember-bench
- Big picture: 1000 paper cuts, lots of repeated work
- Ember: Helps us do fewer things via better coordination with macro optimizations
Counter-spells and the Art of Keeping Your Application Safe - Ingrid Epure
- Gifar image vulnerability attack ~2008
- Image EXIF embedding PHP code ~2012
- First rule of web security: Never (EVER) trust user submitted data
- Reflected XSS
GET http://myapp.com/list/all?search_term=<img """><script>alert(document.cookie)</script>">
- Ember:
- HTML escaping
- Ember escapes by default
- To bypass use
Ember.String.htmlSafe()
-
Content Security Policy
- ember-cli-content-security-policy
- Whitelists “safe” scripts, fonts, images, etc.
Content-Security-Policy "script-src 'self' static.mysite.com"
- Use CSP V2 and V3 only
- hash-source and nonce-source for inline script support
- HTML escaping
- Avoid
htmlSafe()
- Use only with proper sanitization
- Never use directly on user input
- Use Ember Contextual Components
- Good helpers - Let the browser worry about it
- Use DOM to create text nodes
- Set style attributes
- Append child
- Avoid Triple Curlies -
{{{foo}}}
- Always use
rel="noopener noreferrer"
withtarget=_blank
target=_blank
vulnerability- Built-in lint rules via ember-cli-template-lint
Animate the Web with Ember.js - Jessica Jordan
- Frame-by-Frame Animations
- Image Sequence + Display Frequency
- Phi phenomenon
- Flash animations → HTML 5 animations
- Why open web standards?
- Open
- Consistent
- Available
- HTML 5
<canvas></canvas>
- Powerful Web API
- Canvas context object -
bower install --save canvas-5-polyfill
- Sprite sheet +
ctx.drawImage()
- Ember & Web Animations API
- Web Animations API - animation of the future
-
ember-web-animations-next-polyfill -
ember install ember-web-animations-next-polyfill
- Keyframe effects
- Multi-layer Components
- Sub components
{{#each ...}}{{comic-layer}}{{/each}}
- Sub components
Data Loading Patterns with JSON API - Balint Erdi
- Why JSON API?
- Convention over Configuration for APIs
- Ember Data Store:
this.store()
-
findRecord('band', 1);
- return from the store as well as trigger a reload over the wire findAll('band');
-
peekRecord('band', 1);
-peek*
does not trigger a reload, simply returns what is in the store peekAll('band');
-
-
shouldBackgroundReloadRecord
&shouldBackgroundReloadAll
- Fetching relationship data
- Lazy fetching
- Simple, on demand data fetch
- Might trigger
N
requests, flicker
- Pre-loading:
model()
hookreturn Ember.RSVP.hash()
- Moves relationship data to route’s
model()
hook - blocks rendering of template - Better UX but the
N
request issue persists,RSVP.hash()
is a model hook anti-pattern
- Moves relationship data to route’s
- Compound document syncing (side-loading)
this.store.findRecord('band', params.id, { include 'songs', reload: true });
/band/1?include=songs
- Leverage JSON API, explicit control over fetching relationship data
- Delays rendering of the child template
- Lazy fetching
- Ember Data Patterns
- https://balinterdi.com/emberconf/
- Slides
Higher Order Components - Miguel Camba
-
Higher Order functions
- Functions that return functions
- Create closures
- Higher Order components
- Components that return components
-
hash
helper used to explicitly define a Public API for the component {{yield (hash avatar=(component "user-avatar") image=user.pic size="big")}}
- Now this is accessible as a variable in the block from the callee in the parent template -
{{t.avatar}}
- API design is very important
- Less options are better
- Don’t abuse bindings to communicate with parent
- Minimize mandatory options with sensible defaults
- Options are passed to the component that cares about them
- A well crafted component should be easy to adapt to new uses
- Initial approach: Bindings -
{{x-toggle checked=checked}}
- Solution DDAU -
onChange=(action (mut checked))
- Now what if I want different colors and size
- Presentational and Container Components by Dan Abramov
-
Contextual Components
- Flexibility, composability and the right level of abstractions
- Use
hasBlock
template helper to make the contextual component “Opt In”- Now just pass in non-block form for sensible defaults
DAY 2
Empowering the Next Million Creators - Edward Faulkner
- How do we grow to empower wider audiences of people?
- Continuum from small applications with less features → bigger application with more features
-
npm install
your way up from Glimmer.js to Ember - Small: Glimmer.js
- Medium: Ember.js
- Big: Drupal, Wordpress
-
- Glimmer.js - Flexible, Expandable Modern-web platform
- The web is about HTML
- Good level of power for the task it is assigned
- Fairly easy to learn and pick up
- Templates in Ember are just a superset of HTML - Flexible (Ember strength)
- Addon ecosystem
- Drupal: You need your site up and running. Problem: developers are very expensive
- Focus on a few unique tasks → offload the rest on to the community
- A community that invests in shared standards
- Drupal: You need your site up and running. Problem: developers are very expensive
-
NEW : Card stack application architecture Drop-in tools to give you a WYSIWYG editor for your Ember components (Big on the continuum scale)
ember install @cardstack/cardstack-tools
{{#cardstack-tools}}{{outlet}}{{#cardstack-tools}}
-
ember install squishable-container
- simple component that takes it’s initial size and is able to scale itself {{#cardstack-tools}}{{#squishable-container}}{{outlet}}{{squishable-container}}{{#cardstack-tools}}
ember-toolbars
{{cardstack-content}}
-
ember install @cardstack/core-types
- I’m NPM installing my way to my final app state -
ember install @cardstack/mobiledoc
- Rich text editing on the web
- ember-overlays
-
@cardstack/hub
- layer that bridges together all sources of data your application needs, into a single source that follows the same authentication and configures to your application standards - Authentication & Authorization
SVG Animation and Interaction in Ember - Jen Weber
- SVG - images made of code
- SVG Basics
- SVG elements can be transformed with CSS
- Simply style using CSS
-
outline
→stroke
-
background-color
→fill
-
- Follows paint order, not
z-index
. Lowest in DOM order forms top layer visible to the user -
<g>
group wrapper
- Using SVGs in Ember
- Easily add actions to SVGs
- Binding attributes and classes
- Avoiding pitfalls
-
<rect class="temperature {{tempStatus}}" width="117.6" height={{thermHeight}} />
Doesn’t always work (height goes down instead of up!) - Top left corner is
0,0
- Shapes are positioned using x and y coordinates within the SVG
viewBox
- Elements can be spinned, stretched, squished, etc.
-
<rect class="temperature {{tempStatus}}" width="117.6" height={{thermHeight}} transform="rotate(180 365 710)"/>
Fixes the issue by essentially rotating the axis of the rectangle so the height eases up instead of down - Default Ember component
<div>
wrapper inside SVG === bad. UsetagName='g'
instead - Paint order Problems: Use
Ember.computed.sort()
so data with the lowesty
coordinate gets rendered first - Upgrade app > Ember v1.8.0
-
- Use computed properties in the model to manipulate plotted/transformed SVG data & coordinates
- Accessible SVG
- SVG Optimization Tools
Mastering Ember from the Perspective of a N00b - Madison Kerndt
-
Dreyfus model
- Novice → Advanced Beginner → Competent → Proficient → Expert
- Biggest shift: Proficient → Expert
- Proficient developer sees all the details and complexities in the Tree
- Expert developer sees all of the details and complexities in the Forrest
- Intuition: ability to understand something without the need for conscious reasoning
-
Adriaan de Groot
- Neuroscience and psychology research using Chess
- Can you remember the pieces?
- In order to retain information, we have to organize it in a way that is meaninful → Intuitiion
- Zone of Proximal Development - What a learner can do with and without help
- Optimal pacing is challenging people just beyond their learning ability level
- Mental Model
- Router → Route → Model → Parent Template → Component
-
{{outlet}}
- lets you specific where a child route should render inside of a template
State, Time, and Concurrency - Alex Matchneer
- State is the data in your app that changes over time
- Concurrency is when you have more than one state change operation occurring at the same time.
- ember-concurrency
- Error: Calling set on destroyed object
- No
isSubmitting
flag - No
isDestroyed
check - No “Am I Still Running?” checks
- No
.set()
calls necessary at all - Task
- Better syntax for expressing async operations
- Allows for cancellation
- Declarative API
- Derived State
- Task Modifiers
.drop()
.enqueue()
.restartable()
- Task Groups
- Derived State: Helpful “out-of-the-box” state
<TaskInstance>.isRunning
<TaskInstance>.performCount
<TaskInstance>.concurrency
- Anti-Pattern: Manual state tracking
this.set('isShipping', true); yield asyncTask(); this.set('isShipping', false);
- Redundant, Point of easy failure, Error-prone
- Respect the 4th Dimension :clock:
- When you
.perform()
a Task it creates a TaskInstance -
Essential State vs Accidental State
- Solution: Derived State (Computed Properties)
- Declarative APIs > Imperative APIs
- Slides
Confessions of an Ember Addon Author - Lauren Elizabeth Tan
- ~3.5k addons out there today
- What makes an addon good?
- #1. Solve an interesting problem
- #2. Straightforward to setup and use (docs and examples)
- #3. API needs to be deliberate
- #4. Reliable (tests)
- EX: ember-power-select, ember-concurrency, liquid-fire, ember-cli-deploy, ember-cli-mirage
- DDD - Documentation Driven Development
- Any successful project requires two things
- Solve a problem
- Convince people to use your addon
- Project doesn’t end after you type
npm publish
- Addon Anatomy
- Folder structure looks very similar to regular Ember App
- Certain folders in Ember-land, certain folders in Node-land
-
/addon
doesn’t get merged into consuming app’s tree - Allow for overriding
- Be deliberate about what get’s merged into consuming app
-
Addon internals are not actually private
- There are still ways for consuming apps to access
- Blueprints
- Addon hooks in
index.js
are really powerful- ember-test-selectors - Removes itself from the application during a prod build
-
ember-composable-helpers - Whitelist/Blacklist specific helpers from your application
filterHelpers()
- ember-cli-deploy - Augments ember-cli with custom commands
- One Weird Trick
- Tell a story - Write great docs
- What is the Public API? - Ramda documentation is a great example
- Show don’t tell - ember-burger-menu
- Testing your addon - ember-try
- Test with a real browser
- Configuration
-
ember-metrics - allows different behaviors based on configuration found in
config/environment.js
- ember-cli-build.js
-
ember-metrics - allows different behaviors based on configuration found in
- ember-factory-for-polyfill
- Dash offline documentation
- Always SemVer
EmberConf MiniTalks
- Ember Beta Docs
- QUnit-CLI -
npm install -g qunitjs; qunit --help;
-
QUnit.todo();
- Expects failures but report Green to test reporters -
QUnit.begin();
→QUnit.on('runStart');
-
Heimdall
- Reduce/Reuse/Recycle
ember install ember-perf-timeline
ember install ember-heimdall
- Timeline integration
- Stripped from prod code
Spin Me a Yarn - Serena Fritsch
- NPM released in 2010
- 11k packages published per week
- Yarn - Fast, reliable, and secure dependency management
- Package : Piece of software that can be downloaded; may depend on other packages
- Multiple levels of dependencies (nested)
- Allows us to install packages with different versions
- So you want to write a package manager by Sam Boyer
- Install phase:
- Dependency Resolution
- Fetching Packages
- Linking Packages
-
package.json
: “What I want” vs.yarn.lock
: “What I had” - NPM === Nondeterministic
- Always
git commit
youryarn.lock
file - Ember CLI 2.13 onwards is “yarn aware”
An Animated Guide to Ember Internals - Gavin Joyce
- Classic action vs Closure action
- Boot:
- Journey through Ember.js Glue: Booting Up by Mike North
- 27 events handled by default and triggered on body
- Initial Render:
- Handlebars template → Wire format
- Compilation step: Wire format → Op Codes
- Op Codes are then executed at runtime
- Glimmer VMs
- Append VM - Run initially
- Update VM - Run on update