New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Glimmer Engine #10501

Merged
merged 321 commits into from May 5, 2015

Conversation

Projects
None yet
@wycats
Member

wycats commented Feb 21, 2015

Glimmer is the next-generation rendering engine for Ember.js. Built on top of HTMLBars, streams, and an entirely rewritten view layer, Glimmer offers the best performance of any of the major JavaScript frameworks while remaining backwards compatible with Ember 1.x apps.


The Virtual DOM showed the world that render-time diffing delivers awesome performance by minimizing DOM updates and keeping unchanged elements stable. But like any abstraction, it comes with a cost. In this case, constructing the virtual DOM to compare requires at least some subset of components do a full re-render, and building virtual DOM nodes for static areas of your markup that will never change for every change requires many more allocations and increases GC pressure.

Glimmer analyzes templates at compile time, relying on the fact that Handlebars' declarative syntax clearly differentiates between static areas, which make up the majority of a template, and the dynamic areas that can change. Instead of invoking a render() method and diffing the result, Glimmer only walks the (much smaller) existing dynamic tree.


Handlebars' declarative syntax means that from the perspective of an app, the template is being "re-rendered every time", but we can take advantage of static knowledge to reduce the work that we need to do. User code, like helpers and computed properties, are executed during the walk, but only to get (primitive) values which can be === compared, not to build up a new tree. In other words, the programming model is equivalent to "render every time", but we take advantage of the declarative nature of Ember's APIs to reduce work.

Internally, instead of creating a virtual DOM, Glimmer builds a tree of streams, each stream pointing to a node in the DOM. On initial render, we track the last value (always a primitive) that we inserted into the DOM. The streams are not exposed to application code; Glimmer executes user code when necessary and pushes the new value into the stream.

When re-rendering, we walk the tree and flush the streams. If the primitive value produced by the stream has not changed, we do nothing. If it has changed, we write the change to the DOM. Like Virtual DOM approaches, this is a "write-only" algorithm.

One of the benefits of this approach is that we can naturally fuse the Ember/Polymer model of observing individual properties with the React model of explicitly re-rendering areas of the template. No matter what happens, the process of revalidation walks the tree, looking for dirty nodes, and revalidates any dirty nodes it finds.

The only difference is how much of dynamic tree is marked dirty before revalidation begins. Also, because observation can only dirty dynamic nodes (and schedule a top-down revalidation), multiple observers and re-renders that occur during a single run-loop still only produce a single batch of DOM updates.

In essence, the biggest difference between Glimmer and traditional virtual DOM approaches is that we diff values, not DOM. This approach not only lets us avoid the algorithmic complexity of tree diffing (instead, we just === check two values), it also lets us avoid doing many render-time allocations.

Slides from the talk at EmberConf

Work List

(this looks like more things than it actually is)

  • merge subscription change into our branch
  • linkRenderNode can mark stability
  • Ember should return true from linkRenderNode
  • make sure all child streams correctly disconnect from parents
  • add stream pruning logic that correctly prunes ancestors
  • add scope teardown hook to HTMLBars (recursive upon clear or remove)
    • this is also responsible for view layer teardown
  • Propagate correct visitor through descendent hooks (so dirty checks can be avoided for a subtree)
  • Do not dirty check render nodes that were just created (fixes regression)
  • Add "classify" hook to decide which hook content et al should delegate to
  • Make sure that #view is idempotent
  • Components and views should create a new scope frame
    • Implement custom scope in Ember (so that ambient view, controller, etc. can be stored)
    • Eliminate *component* hacks
  • Lifecycle hooks on the renderer
  • Move code duplicated between #view, #component and Ember.View into the Renderer
  • Support reflecting attributes onto angle-bracket components
  • Pass mutable bindings as "mutator" objects
  • Support foo={{action "bar"}}
  • Legacy support: Implement unknownProperty/setUnknownProperty to work with mutator objects
    • Deprecate setting non-mut attributes, and support (mut foo) sexprs in legacy Handlebars syntax
  • Investigate executing teardown callbacks at a "quiescent" state ("vent plasma")
    • Make sure to consider the rpflo stress test situation
  • Implement a zip and map abstraction for streams to clean up ad hoc stream creation
  • Add tests for memory leaks
  • Make sure that custom render functions that mutate the buffer continue to work
  • options.template should not exist if there is no template
  • feature flag all the things
  • Handlebars helper compat
  • Template function that returns a string (legacy)
  • Context shifting #each
  • collection helper
  • {{input}}
    • TextField
    • Checkbox
    • TextArea
  • Ember.Select
  • unbound
    • non-block form
    • block form (partially done, but not completely)
  • #view and view helper
  • #view and view helper with back-compat edge cases
  • #with helper
  • with helper with back-compat edge-cases
  • yield without a block
  • {{render}}
  • ContainerView
  • Top-level view APIs
    • createElement
    • appendTo
    • replaceIn
    • destroyElement
  • isVisible

@wycats wycats referenced this pull request Feb 21, 2015

Merged

The Road to Ember 2.0 RFC #15

@wycats

This comment has been minimized.

Show comment
Hide comment
@wycats

wycats Feb 22, 2015

Member
React Hook Ember Hook Server? Initial Render? Rerender? Purpose
componentWillMount init Yes Yes No Set initial component state without triggering re-render
componentDidMount didInsertElement No Yes No Provides opportunity for manual DOM manipulation
componentWillReceiveProps willReceiveAttrs No No Yes React to changes in component attributes, so that setState can be invoked before render
shouldComponentUpdate Maybe N/A No No Yes Gives a component an opportunity to reject downstream revalidation
componentWillUpdate willUpdate No No Yes Invoked before a template is re-rendered to give the component an opportunity to inspect the DOM before updates have been applied (example)
componentDidUpdate didUpdate No No Yes Invoked after a template is re-rendered to give the component an opportunity to update the DOM (example)
componentWillUnmount willDestroyElement No No Yes The inverse of componentDidMount/didInsertElement; clean up anything set up in that hook
N/A willRender No Yes Yes In Ember, executed both after init and after willUpdate*
N/A didRender No Yes Yes In Ember, executed both after didInsertElement and didUpdate*

* These hooks can be used in cases where the setup for initial render and subsequent re-renders is idempotent (e.g. $().addClass) instead of duplicating the logic in both places. In most cases, it is better to try to make these hooks idempotent, in keeping with the spirit of "re-render from scratch every time".

Member

wycats commented Feb 22, 2015

React Hook Ember Hook Server? Initial Render? Rerender? Purpose
componentWillMount init Yes Yes No Set initial component state without triggering re-render
componentDidMount didInsertElement No Yes No Provides opportunity for manual DOM manipulation
componentWillReceiveProps willReceiveAttrs No No Yes React to changes in component attributes, so that setState can be invoked before render
shouldComponentUpdate Maybe N/A No No Yes Gives a component an opportunity to reject downstream revalidation
componentWillUpdate willUpdate No No Yes Invoked before a template is re-rendered to give the component an opportunity to inspect the DOM before updates have been applied (example)
componentDidUpdate didUpdate No No Yes Invoked after a template is re-rendered to give the component an opportunity to update the DOM (example)
componentWillUnmount willDestroyElement No No Yes The inverse of componentDidMount/didInsertElement; clean up anything set up in that hook
N/A willRender No Yes Yes In Ember, executed both after init and after willUpdate*
N/A didRender No Yes Yes In Ember, executed both after didInsertElement and didUpdate*

* These hooks can be used in cases where the setup for initial render and subsequent re-renders is idempotent (e.g. $().addClass) instead of duplicating the logic in both places. In most cases, it is better to try to make these hooks idempotent, in keeping with the spirit of "re-render from scratch every time".

@wycats

This comment has been minimized.

Show comment
Hide comment
@wycats

wycats Feb 22, 2015

Member

The above comment is an attempt to classify the hooks in React and Ember so that we can make sure that the new Ember components implement at least the hooks that React folks have identified as being important in the programming model.

Member

wycats commented Feb 22, 2015

The above comment is an attempt to classify the hooks in React and Ember so that we can make sure that the new Ember components implement at least the hooks that React folks have identified as being important in the programming model.

@rwjblue

This comment has been minimized.

Show comment
Hide comment
@rwjblue

rwjblue Feb 22, 2015

Member

All new API's will also need to be feature flagged.

Member

rwjblue commented Feb 22, 2015

All new API's will also need to be feature flagged.

@wycats

This comment has been minimized.

Show comment
Hide comment
@wycats

wycats Feb 22, 2015

Member

@rwjblue yessir

Member

wycats commented Feb 22, 2015

@rwjblue yessir

@Linicks

This comment has been minimized.

Show comment
Hide comment
@Linicks

Linicks Feb 22, 2015

The init hook name is a little unclear compared to componentWillMount. Could it be named initElelement, or something similar ?

Linicks commented Feb 22, 2015

The init hook name is a little unclear compared to componentWillMount. Could it be named initElelement, or something similar ?

@stefanpenner

This comment has been minimized.

Show comment
Hide comment
@stefanpenner

stefanpenner Feb 22, 2015

Member

The init hook name is a little unclear compared to componentWillMount. Could it be named initElelement, or something similar ?

I would prefer leaving it as init, as it clearly describes what it handles, initialization of the current entity.

That entity just happens to be a component. initFoo as a pattern feels like an exercise in over specification. Especially when you consider the rest of the collaborators all having a unique initFoo method, initModel initRoute etc.

Also worth noting, as we continue to align ourselves with >= ES2015 init will likely become constructor

Member

stefanpenner commented Feb 22, 2015

The init hook name is a little unclear compared to componentWillMount. Could it be named initElelement, or something similar ?

I would prefer leaving it as init, as it clearly describes what it handles, initialization of the current entity.

That entity just happens to be a component. initFoo as a pattern feels like an exercise in over specification. Especially when you consider the rest of the collaborators all having a unique initFoo method, initModel initRoute etc.

Also worth noting, as we continue to align ourselves with >= ES2015 init will likely become constructor

@stefanpenner

This comment has been minimized.

Show comment
Hide comment
@stefanpenner

stefanpenner Feb 22, 2015

Member

@wycats @tomdale good job guys :)

Member

stefanpenner commented Feb 22, 2015

@wycats @tomdale good job guys :)

@alexspeller

This comment has been minimized.

Show comment
Hide comment
@alexspeller

alexspeller Feb 22, 2015

Contributor

😍

Contributor

alexspeller commented Feb 22, 2015

😍

@alexdiliberto

This comment has been minimized.

Show comment
Hide comment
@alexdiliberto

alexdiliberto Feb 22, 2015

Contributor

This is amazing 👍 👍 👍

Contributor

alexdiliberto commented Feb 22, 2015

This is amazing 👍 👍 👍

@Linicks

This comment has been minimized.

Show comment
Hide comment
@Linicks

Linicks Feb 22, 2015

The problem with just using init is that init is used in so many places in the tech world. In an Ember only world it would be clear and concise, but in an ever increasing complex tech stack it's nice to have that extra bit of clarity. I think that's why FB chose an even more verbose naming scheme than my proposal. I have had the chance/misfortune of maintaining allot of legacy software, and appreciate when the code is self describeing as practical. This is really a preference in either direction, but after being in this game for so many years I'm getting a little opionated :) Either way this is exciting stuff, and look forward to seeing this come together in Ember.

Linicks commented Feb 22, 2015

The problem with just using init is that init is used in so many places in the tech world. In an Ember only world it would be clear and concise, but in an ever increasing complex tech stack it's nice to have that extra bit of clarity. I think that's why FB chose an even more verbose naming scheme than my proposal. I have had the chance/misfortune of maintaining allot of legacy software, and appreciate when the code is self describeing as practical. This is really a preference in either direction, but after being in this game for so many years I'm getting a little opionated :) Either way this is exciting stuff, and look forward to seeing this come together in Ember.

@ebryn

This comment has been minimized.

Show comment
Hide comment
@ebryn

ebryn Feb 23, 2015

Member

@Linicks if you look at their ES6 syntax, you'll see they're utilizing the constructor to initialize this.state

Member

ebryn commented Feb 23, 2015

@Linicks if you look at their ES6 syntax, you'll see they're utilizing the constructor to initialize this.state

@fivetanley

This comment has been minimized.

Show comment
Hide comment
@fivetanley

fivetanley Feb 23, 2015

Member

What is a "ShadowRoot"?

Member

fivetanley commented Feb 23, 2015

What is a "ShadowRoot"?

@gonvaled

This comment has been minimized.

Show comment
Hide comment
@gonvaled

gonvaled Feb 23, 2015

This being a "DOM write-only" implementation, how does Ember deal with changes to the DOM done by third-party components, like jQuery based changes, which are not controlled by Ember?

gonvaled commented Feb 23, 2015

This being a "DOM write-only" implementation, how does Ember deal with changes to the DOM done by third-party components, like jQuery based changes, which are not controlled by Ember?

@davidlormor

This comment has been minimized.

Show comment
Hide comment
@davidlormor

davidlormor Feb 23, 2015

"the Dynamic Tree only includes nodes that may have changed (...) and never needs to compare static content that will never change"...sounds fast! 🚀 👍

davidlormor commented Feb 23, 2015

"the Dynamic Tree only includes nodes that may have changed (...) and never needs to compare static content that will never change"...sounds fast! 🚀 👍

@stefanpenner

This comment has been minimized.

Show comment
Hide comment
@stefanpenner

stefanpenner Feb 23, 2015

Member

This being a "DOM write-only" implementation, how does Ember deal with changes to the DOM done by third-party components, like jQuery based changes, which are not controlled by Ember?

It doesn't and likely cannot support this. It would be impossible to know what those plugins are doing

Member

stefanpenner commented Feb 23, 2015

This being a "DOM write-only" implementation, how does Ember deal with changes to the DOM done by third-party components, like jQuery based changes, which are not controlled by Ember?

It doesn't and likely cannot support this. It would be impossible to know what those plugins are doing

@mgenev

This comment has been minimized.

Show comment
Hide comment
@mgenev

mgenev Feb 23, 2015

@stefanpenner that means we can no longer use bootstrap (jQiery dependent) in an ember app unless a bootstrap-for-ember version is written, right? Same goes for foundation etc...

mgenev commented Feb 23, 2015

@stefanpenner that means we can no longer use bootstrap (jQiery dependent) in an ember app unless a bootstrap-for-ember version is written, right? Same goes for foundation etc...

@stefanpenner

This comment has been minimized.

Show comment
Hide comment
@stefanpenner

stefanpenner Feb 23, 2015

Member

@stefanpenner that means we can no longer use bootstrap (jQiery dependent) in an ember app unless a bootstrap-for-ember version is written, right? Same goes for foundation etc...

No, this is no different then today. If you component is re-rendered your bootstrap and jquery code needs to re-run.

Member

stefanpenner commented Feb 23, 2015

@stefanpenner that means we can no longer use bootstrap (jQiery dependent) in an ember app unless a bootstrap-for-ember version is written, right? Same goes for foundation etc...

No, this is no different then today. If you component is re-rendered your bootstrap and jquery code needs to re-run.

@wycats

This comment has been minimized.

Show comment
Hide comment
@wycats

wycats Feb 23, 2015

Member

@stefanpenner @mgenev I think there's a little bit of confusion here.

From new-world Ember's perspective, as long as the element for a component still exists in the DOM, it doesn't matter where it has been moved, whether it has been decorated, etc.

There are a few restrictions on moving elements around, but they're very minor and would be easy to abstract. Stay tuned as we continue to make more progress.

Member

wycats commented Feb 23, 2015

@stefanpenner @mgenev I think there's a little bit of confusion here.

From new-world Ember's perspective, as long as the element for a component still exists in the DOM, it doesn't matter where it has been moved, whether it has been decorated, etc.

There are a few restrictions on moving elements around, but they're very minor and would be easy to abstract. Stay tuned as we continue to make more progress.

Show outdated Hide outdated packages/ember-htmlbars/tests/helpers/new_each_helper_test.js
// and generate:
//
// - {{#each p in people}} (legacy)
// - {{#each people as |p|}} (legacy)

This comment has been minimized.

@ef4

ef4 Feb 24, 2015

Contributor

why is {{#each people as |p|}} marked as legacy? Are we not keeping that syntax?

@ef4

ef4 Feb 24, 2015

Contributor

why is {{#each people as |p|}} marked as legacy? Are we not keeping that syntax?

// want to require non-enumerability for this API, which
// would introduce a large cost.
return intern(debugName + ' [id=' + GUID_KEY + Math.floor(Math.random() * new Date()) + ']');

This comment has been minimized.

@ef4

ef4 Feb 24, 2015

Contributor

Are there really platforms where Math.random() is so broken that we need to multiply by new Date?

@ef4

ef4 Feb 24, 2015

Contributor

Are there really platforms where Math.random() is so broken that we need to multiply by new Date?

This comment has been minimized.

@tomdale

tomdale Feb 24, 2015

Member

Dunno, let's have our IE friends run http://jsbin.com/lexonidara/2/edit?html,js,output overnight.

@tomdale

tomdale Feb 24, 2015

Member

Dunno, let's have our IE friends run http://jsbin.com/lexonidara/2/edit?html,js,output overnight.

This comment has been minimized.

@jdalton

jdalton Mar 4, 2015

Ran this in IE11 overnight and no collisions.

@jdalton

jdalton Mar 4, 2015

Ran this in IE11 overnight and no collisions.

This comment has been minimized.

@loopmode

loopmode Mar 6, 2015

I came from using millis to multiplying by random in that particular order, so the idea was to allow for more possible values during a single CPU cycle. Maybe the author had a similar purpose in mind.

@loopmode

loopmode Mar 6, 2015

I came from using millis to multiplying by random in that particular order, so the idea was to allow for more possible values during a single CPU cycle. Maybe the author had a similar purpose in mind.

@rwjblue rwjblue changed the title from [WIP] <my-component> syntax and stable full re-renders to [WIP] Implement Glimmer Engine Mar 3, 2015

@rwjblue

This comment has been minimized.

Show comment
Hide comment
@rwjblue

rwjblue Mar 3, 2015

Member

Updated title + description based on EmberConf presentation.

Member

rwjblue commented Mar 3, 2015

Updated title + description based on EmberConf presentation.

@toblender

This comment has been minimized.

Show comment
Hide comment
@toblender

toblender Mar 3, 2015

Minor correction: teack === track?

toblender commented Mar 3, 2015

Minor correction: teack === track?

@morenoh149

This comment has been minimized.

Show comment
Hide comment
@morenoh149

morenoh149 Mar 3, 2015

@toblender yeah. I thought he meant teach

morenoh149 commented Mar 3, 2015

@toblender yeah. I thought he meant teach

@darkbaby123

This comment has been minimized.

Show comment
Hide comment
@darkbaby123

darkbaby123 Mar 4, 2015

Contributor

@wycats You mentioned a lot about diffing values to check if they're dirty. I'm curious what's the difference between Glimmer's diffing logic and Angular's dirty-checking.

As I know Angular dirty-checking also checks values (expressions) one by one and execute corresponding callbacks (mostly change doms). But:

  1. Angular doesn't have run loop so it's can not batch update doms.
  2. watchers need to be triggered by $apply() manually sometimes.
Contributor

darkbaby123 commented Mar 4, 2015

@wycats You mentioned a lot about diffing values to check if they're dirty. I'm curious what's the difference between Glimmer's diffing logic and Angular's dirty-checking.

As I know Angular dirty-checking also checks values (expressions) one by one and execute corresponding callbacks (mostly change doms). But:

  1. Angular doesn't have run loop so it's can not batch update doms.
  2. watchers need to be triggered by $apply() manually sometimes.
@drogus

This comment has been minimized.

Show comment
Hide comment
@drogus

drogus Mar 4, 2015

Contributor

I'm curious what's the difference between Glimmer's diffing logic and Angular's dirty-checking.

These two diffing situations are not happening at the same level. Angular's diffing happens outside of a view layer in order to check if a template change is needed. So let's say that you have a user = { login: 'drogus' } object. And you use it in a template as <span class="login">{{user.login}}</span>. Now, in order to update the template automatically you need to know if a value of the user object was changed. In Angular it's done by dirty checking all of the properties used in templates. In Ember properties are observed, so it knows when a property is changed.

This PR and diffing described here happen in a view layer when a framework already knows that it needs to rerender something, but it needs to figure out what to rerender exactly. DOM is slow, so regenerating the entire template may be costly and here comes the diffing algorithm that React started with.

Contributor

drogus commented Mar 4, 2015

I'm curious what's the difference between Glimmer's diffing logic and Angular's dirty-checking.

These two diffing situations are not happening at the same level. Angular's diffing happens outside of a view layer in order to check if a template change is needed. So let's say that you have a user = { login: 'drogus' } object. And you use it in a template as <span class="login">{{user.login}}</span>. Now, in order to update the template automatically you need to know if a value of the user object was changed. In Angular it's done by dirty checking all of the properties used in templates. In Ember properties are observed, so it knows when a property is changed.

This PR and diffing described here happen in a view layer when a framework already knows that it needs to rerender something, but it needs to figure out what to rerender exactly. DOM is slow, so regenerating the entire template may be costly and here comes the diffing algorithm that React started with.

@bitinn

This comment has been minimized.

Show comment
Hide comment
@bitinn

bitinn Mar 5, 2015

One interesting side-effects of React (or other similar dom-diffing) approach is you can worry less about what's being updated in DOM (as oppose to update them manually on value change).

What sort of limit will value-diffing approach impose on DOM manipulation? Would you say this approach is closer to something like Riot than React?

Update: to me, it seems the key differences here are:

  1. dom-diff approach allow user to define almost arbitrary dom update logics, then perform it through a full render.
  2. value-diff approach capture those logic via template/helpers, and can minimize the need to go through static dom tree.
  3. value-diff is conceptually closer to traditional template renderer, though Glimmer use batch dom update (what dom-diff commonly do) to improve performance.

Apologize if I am totally mistaken :)

bitinn commented Mar 5, 2015

One interesting side-effects of React (or other similar dom-diffing) approach is you can worry less about what's being updated in DOM (as oppose to update them manually on value change).

What sort of limit will value-diffing approach impose on DOM manipulation? Would you say this approach is closer to something like Riot than React?

Update: to me, it seems the key differences here are:

  1. dom-diff approach allow user to define almost arbitrary dom update logics, then perform it through a full render.
  2. value-diff approach capture those logic via template/helpers, and can minimize the need to go through static dom tree.
  3. value-diff is conceptually closer to traditional template renderer, though Glimmer use batch dom update (what dom-diff commonly do) to improve performance.

Apologize if I am totally mistaken :)

@wagenet wagenet referenced this pull request Mar 6, 2015

Closed

Reduce dependency on ArrayComputed and ReduceComputed #10582

0 of 2 tasks complete
@mixonic

This comment has been minimized.

Show comment
Hide comment
@mixonic

mixonic Mar 8, 2015

Member

@bitinn your understanding is pretty good. I think the comparison to Riot is a good one.

Your points one and two are correct IMO. Point three is a bit off, but I'm not sure what you are thinking when you say "traditional template renderer". A full rerender in glimmer will re-use the static DOM anywhere the template being used has not changed, and will only update dynamic content if it has changed. Where the template has changed, Glimmer will cloneNode a cached fragment of pre-hydrated DOM.

I'm sure the architecture will be discussed in more details as this gets closer to landing.

Member

mixonic commented Mar 8, 2015

@bitinn your understanding is pretty good. I think the comparison to Riot is a good one.

Your points one and two are correct IMO. Point three is a bit off, but I'm not sure what you are thinking when you say "traditional template renderer". A full rerender in glimmer will re-use the static DOM anywhere the template being used has not changed, and will only update dynamic content if it has changed. Where the template has changed, Glimmer will cloneNode a cached fragment of pre-hydrated DOM.

I'm sure the architecture will be discussed in more details as this gets closer to landing.

@jonathanKingston

This comment has been minimized.

Show comment
Hide comment
@jonathanKingston

jonathanKingston Mar 8, 2015

Contributor

Is the intention to swap out ShadowRoot with document.ShadowRoot eventually?

Contributor

jonathanKingston commented Mar 8, 2015

Is the intention to swap out ShadowRoot with document.ShadowRoot eventually?

Tom Dale and Yehuda Katz added some commits Mar 19, 2015

Attrs, scope and view destruction cleanup
This commit fixes several edge cases in how scope was managed in
templates, how attrs are looked up, and how views are cleaned up,
particularly the willDestroyElement user hook.
@WillsonSmith

This comment has been minimized.

Show comment
Hide comment

WillsonSmith commented May 5, 2015

eznaclq

@binhums

This comment has been minimized.

Show comment
Hide comment
@binhums

binhums May 5, 2015

Contributor

Woohoo!

Contributor

binhums commented May 5, 2015

Woohoo!

@oskarrough

This comment has been minimized.

Show comment
Hide comment
@oskarrough

oskarrough May 5, 2015

Just updated from 1.11.1 and it took five minutes to get everything working through all your console.logs. So good!

oskarrough commented May 5, 2015

Just updated from 1.11.1 and it took five minutes to get everything working through all your console.logs. So good!

@mrinterweb

This comment has been minimized.

Show comment
Hide comment

mrinterweb commented May 5, 2015

@Fed03

This comment has been minimized.

Show comment
Hide comment
@Fed03

Fed03 commented May 5, 2015

image

@tubbo

This comment has been minimized.

Show comment
Hide comment
@tubbo

tubbo commented May 6, 2015

yay

@btecu

This comment has been minimized.

Show comment
Hide comment
@btecu

btecu May 6, 2015

Contributor

Great work!

Contributor

btecu commented May 6, 2015

Great work!

@Adriaaaaan

This comment has been minimized.

Show comment
Hide comment
@Adriaaaaan

Adriaaaaan May 6, 2015

Great work! although our app is currently very broken still I'm already seeing a huge improvement in performance in my list views. Now i just have a million deprecation warnings to fix

Adriaaaaan commented May 6, 2015

Great work! although our app is currently very broken still I'm already seeing a huge improvement in performance in my list views. Now i just have a million deprecation warnings to fix

@wycats

This comment has been minimized.

Show comment
Hide comment
@wycats

wycats May 6, 2015

Member

@Adriaaaaan That's great news! Please do report any notable breakage. We want things to be pretty clean by the time we ship 1.13 final :)

You might also want to run in prod mode to check out perf. Those deprecation warnings aren't free to generate ;)

Member

wycats commented May 6, 2015

@Adriaaaaan That's great news! Please do report any notable breakage. We want things to be pretty clean by the time we ship 1.13 final :)

You might also want to run in prod mode to check out perf. Those deprecation warnings aren't free to generate ;)

@chrism

This comment has been minimized.

Show comment
Hide comment
@chrism

chrism May 6, 2015

Great Work!

Anyone using Liquid Fire should check that ember-animation/liquid-fire#276 has been resolved before updating as it is not yet glimmer compatible.

chrism commented May 6, 2015

Great Work!

Anyone using Liquid Fire should check that ember-animation/liquid-fire#276 has been resolved before updating as it is not yet glimmer compatible.

@jmurphyau

This comment has been minimized.

Show comment
Hide comment
@jmurphyau

jmurphyau May 6, 2015

Contributor

@wycats any help you can provide on unbound helpers? A helper that produces a stream like value that can be invalidated causing the value in the template to update? Trying to get ember-get-helper to work with glimmer.. Simply returning a new child stream (e..g objectStream.get(key)) doesn't cause a new value to render in the template when that value changes.. Do I need to look into some of the hooks or somehow subscribe to the new stream?

Contributor

jmurphyau commented May 6, 2015

@wycats any help you can provide on unbound helpers? A helper that produces a stream like value that can be invalidated causing the value in the template to update? Trying to get ember-get-helper to work with glimmer.. Simply returning a new child stream (e..g objectStream.get(key)) doesn't cause a new value to render in the template when that value changes.. Do I need to look into some of the hooks or somehow subscribe to the new stream?

@jmurphyau

This comment has been minimized.

Show comment
Hide comment
@jmurphyau

jmurphyau May 6, 2015

Contributor

I can't seem to find that really detailed description of all the HTMLBars lifecycle hooks etc.. Do you have a link to that that you could provide?

Contributor

jmurphyau commented May 6, 2015

I can't seem to find that really detailed description of all the HTMLBars lifecycle hooks etc.. Do you have a link to that that you could provide?

@wycats

This comment has been minimized.

Show comment
Hide comment
@wycats

wycats May 6, 2015

Member

@jmurphyau right now there is no public way for a helper to express dynamic dependencies, but that's a good idea.

Glimmer intentionally doesn't expose the internal stream machinery; it's changing quite a bit still, but it makes sense for a helper to be able to tell Ember when to invalidate it.

It also kind of makes sense for us to include this get helper in Ember itself honestly. It's a primitive, like {{component}}.

Member

wycats commented May 6, 2015

@jmurphyau right now there is no public way for a helper to express dynamic dependencies, but that's a good idea.

Glimmer intentionally doesn't expose the internal stream machinery; it's changing quite a bit still, but it makes sense for a helper to be able to tell Ember when to invalidate it.

It also kind of makes sense for us to include this get helper in Ember itself honestly. It's a primitive, like {{component}}.

@wycats

This comment has been minimized.

Show comment
Hide comment
@wycats

wycats May 6, 2015

Member

@jmurphyau as I said in the blog post, more info on the life cycle hooks is forthcoming :)

Member

wycats commented May 6, 2015

@jmurphyau as I said in the blog post, more info on the life cycle hooks is forthcoming :)

@Adriaaaaan

This comment has been minimized.

Show comment
Hide comment
@Adriaaaaan

Adriaaaaan May 6, 2015

@wycats Hmmm have looked into it more, I'm now seeing a rather significant performance regression. related to interacting with sub resources templates from a list. It seems that interacting with it causes the the whole tree to redraw making it unusable if there are a lot of rows per page. 1.11 is faster, its most notable when selecting the rows (the detail page is very laggy at appearing, the more rows in the list the longer it takes). Although it is clearly much faster at rendering (the page appears much faster) interacting with it is much worse as it seems to be doing more work everytime something changes. I'll see If I can make a simple jsbin

Adriaaaaan commented May 6, 2015

@wycats Hmmm have looked into it more, I'm now seeing a rather significant performance regression. related to interacting with sub resources templates from a list. It seems that interacting with it causes the the whole tree to redraw making it unusable if there are a lot of rows per page. 1.11 is faster, its most notable when selecting the rows (the detail page is very laggy at appearing, the more rows in the list the longer it takes). Although it is clearly much faster at rendering (the page appears much faster) interacting with it is much worse as it seems to be doing more work everytime something changes. I'll see If I can make a simple jsbin

@EnglishCriminal

This comment has been minimized.

Show comment
Hide comment

EnglishCriminal commented May 6, 2015

@jiyinyiyong

This comment has been minimized.

Show comment
Hide comment
@jiyinyiyong

jiyinyiyong May 7, 2015

Hi, you mentioned there's slide in EmberConf 2015. But is there a video?
I can't find it in the list "EmberConf 2015 by Confreaks"
https://www.youtube.com/playlist?list=PLE7tQUdRKcyacwiUPs0CjPYt6tJub4xXU

jiyinyiyong commented May 7, 2015

Hi, you mentioned there's slide in EmberConf 2015. But is there a video?
I can't find it in the list "EmberConf 2015 by Confreaks"
https://www.youtube.com/playlist?list=PLE7tQUdRKcyacwiUPs0CjPYt6tJub4xXU

@igorT

This comment has been minimized.

Show comment
Hide comment
@igorT

igorT May 7, 2015

Member

@jiyinyiyong it's the keynote, towards the end

Member

igorT commented May 7, 2015

@jiyinyiyong it's the keynote, towards the end

@jmurphyau jmurphyau referenced this pull request May 7, 2015

Closed

[Proposal] get helper #10878

@jiyinyiyong

This comment has been minimized.

Show comment
Hide comment
@jiyinyiyong

jiyinyiyong May 8, 2015

@igorT I don't get it. Could you point it out in the video?

found it, thx https://youtu.be/o12-90Dm-Qs?t=3077

jiyinyiyong commented May 8, 2015

@igorT I don't get it. Could you point it out in the video?

found it, thx https://youtu.be/o12-90Dm-Qs?t=3077

@blessenm

This comment has been minimized.

Show comment
Hide comment
@blessenm

blessenm May 8, 2015

Contributor

Stupid question. So there is no virtual DOM in ember right? Just value diffing to find which part of the DOM needs to be manipulated.

Contributor

blessenm commented May 8, 2015

Stupid question. So there is no virtual DOM in ember right? Just value diffing to find which part of the DOM needs to be manipulated.

@axemclion

This comment has been minimized.

Show comment
Hide comment
@axemclion

axemclion May 14, 2015

Glimmer is pretty fast - almost 25% faster !! Ran some tests and results here - http://blog.nparashuram.com/2015/05/performance-boost-in-emberjs-from.html

axemclion commented May 14, 2015

Glimmer is pretty fast - almost 25% faster !! Ran some tests and results here - http://blog.nparashuram.com/2015/05/performance-boost-in-emberjs-from.html

@jdurand

This comment has been minimized.

Show comment
Hide comment
@jdurand

jdurand May 15, 2015

@blessenm instead of diffing DOM it diffs a tree of possibly mutable states that are bound to the real DOM. It doesn't need to maintain a virtual DOM because it has a deeper knowledge of your apps state.

jdurand commented May 15, 2015

@blessenm instead of diffing DOM it diffs a tree of possibly mutable states that are bound to the real DOM. It doesn't need to maintain a virtual DOM because it has a deeper knowledge of your apps state.

@blessenm

This comment has been minimized.

Show comment
Hide comment
@blessenm

blessenm May 15, 2015

Contributor

@jdurand thanks for the clarification.

Contributor

blessenm commented May 15, 2015

@jdurand thanks for the clarification.

@ballPointPenguin

This comment has been minimized.

Show comment
Hide comment
@ballPointPenguin
Contributor

ballPointPenguin commented May 18, 2015

The Glimmer Twins

@juggy

This comment has been minimized.

Show comment
Hide comment
@juggy

juggy Jun 2, 2015

Contributor

Why not expose componentNameMap as a global config to enable custom inputs using the same convenient {{input prop type="custom-comp"}} ?

Contributor

juggy commented on 5a1c5e1 Jun 2, 2015

Why not expose componentNameMap as a global config to enable custom inputs using the same convenient {{input prop type="custom-comp"}} ?

This comment has been minimized.

Show comment
Hide comment
@bantic

bantic Jun 3, 2015

Member

@juggy Not sure exactly what you are asking. Using another type should "just work". E.g. {{input type="color"}} should be fine.

Member

bantic replied Jun 3, 2015

@juggy Not sure exactly what you are asking. Using another type should "just work". E.g. {{input type="color"}} should be fine.

This comment has been minimized.

Show comment
Hide comment
@juggy

juggy Jun 3, 2015

Contributor

type=date-picker to load the component date-picker for example with the value and properties set. But now I realise this is just sugar that might not be good in the long run. Just call the component directly.

I guess what bugs me here is that input either create a checkbox or a textfield, you also have textarea to create a text area. At the end we should get rid of all that and just call the components. Another discussion altogether. So nevermind for now.

Contributor

juggy replied Jun 3, 2015

type=date-picker to load the component date-picker for example with the value and properties set. But now I realise this is just sugar that might not be good in the long run. Just call the component directly.

I guess what bugs me here is that input either create a checkbox or a textfield, you also have textarea to create a text area. At the end we should get rid of all that and just call the components. Another discussion altogether. So nevermind for now.

This comment has been minimized.

Show comment
Hide comment
@rwjblue

rwjblue Jun 3, 2015

Member

@juggy - {{textarea}} creates a <textarea>

Member

rwjblue replied Jun 3, 2015

@juggy - {{textarea}} creates a <textarea>

This comment has been minimized.

Show comment
Hide comment
@bantic

bantic Jun 3, 2015

Member

@juggy The type="checkbox" isn't actually intended to only be sugar to simplify creation of check box inputs. It's to reflect the fact that both text inputs and check box inputs are the same html tag (input) but have somewhat different semantics. The meaning of the value property is somewhat different between the two, and a checkbox input has a boolean checked property that is meaningless for text inputs. For custom inputs making your own component would definitely be the best way to go (i.e. {{calendar-date-picker-input}}).

Member

bantic replied Jun 3, 2015

@juggy The type="checkbox" isn't actually intended to only be sugar to simplify creation of check box inputs. It's to reflect the fact that both text inputs and check box inputs are the same html tag (input) but have somewhat different semantics. The meaning of the value property is somewhat different between the two, and a checkbox input has a boolean checked property that is meaningless for text inputs. For custom inputs making your own component would definitely be the best way to go (i.e. {{calendar-date-picker-input}}).

@jmurphyau

This comment has been minimized.

Show comment
Hide comment
@jmurphyau

jmurphyau Jun 12, 2015

Contributor

@wycats someone has asked a relatively simple question on stackoverflow and in slack - 'what is a stream'.. I answered as best I could but wanted to bring it up here just so I could get a better understanding - what is a stream? Did the name 'stream' come from anywhere/anything in particular?

I mean - I do know what it is (I think) - just not sure how to best describe it..

Contributor

jmurphyau commented Jun 12, 2015

@wycats someone has asked a relatively simple question on stackoverflow and in slack - 'what is a stream'.. I answered as best I could but wanted to bring it up here just so I could get a better understanding - what is a stream? Did the name 'stream' come from anywhere/anything in particular?

I mean - I do know what it is (I think) - just not sure how to best describe it..

@antigremlin

This comment has been minimized.

Show comment
Hide comment
@antigremlin

antigremlin Jun 16, 2015

Hi Robert,
Do you know of any future plans to support viewName? Is anything going to change with the upcoming deprecation of views in Ember 2.0? I have posted a question on Ember forums here but no one seems to know the answer.

antigremlin commented on 5e1787a Jun 16, 2015

Hi Robert,
Do you know of any future plans to support viewName? Is anything going to change with the upcoming deprecation of views in Ember 2.0? I have posted a question on Ember forums here but no one seems to know the answer.

@matthewp

This comment has been minimized.

Show comment
Hide comment
@matthewp

matthewp Jun 19, 2015

Is there somewhere that explains how Glimmer works in more detail, with links to code maybe? Given how many commits are included in this PR it's hard to figure out how the details are implemented in practice. For example you say:

On initial render, we track the last value (always a primitive) that we inserted into the DOM.

But I can't find in the code where this happens. And I don't know what you mean by a primitive value. I assume you mean that you track attribute string values and text node's string nodeValues but am having a difficult time finding where this happens in the code.

Is there maybe one or two commits that contain most of the work that I can look at?

matthewp commented Jun 19, 2015

Is there somewhere that explains how Glimmer works in more detail, with links to code maybe? Given how many commits are included in this PR it's hard to figure out how the details are implemented in practice. For example you say:

On initial render, we track the last value (always a primitive) that we inserted into the DOM.

But I can't find in the code where this happens. And I don't know what you mean by a primitive value. I assume you mean that you track attribute string values and text node's string nodeValues but am having a difficult time finding where this happens in the code.

Is there maybe one or two commits that contain most of the work that I can look at?

@ef4

This comment has been minimized.

Show comment
Hide comment
@ef4

ef4 Jun 19, 2015

Contributor

@matthewp Much of the infrastructure is actually in https://github.com/tildeio/htmlbars

There's not really a single commit to point to -- the work was extensive and many people put in hundreds of commits.

Contributor

ef4 commented Jun 19, 2015

@matthewp Much of the infrastructure is actually in https://github.com/tildeio/htmlbars

There's not really a single commit to point to -- the work was extensive and many people put in hundreds of commits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment