Positioning a large number of elements


#1

Hello,

I created a customized chart component which needs to display many (~1,000) ‘bar’ elements inside it. What I did was I implemented each ‘bar’ as an ember component and have each of them bind the style attribute, for the position according to the model.

I seems to have some performance issues with this.

Is there something wrong with my approach?

Thanks!


#2

Options I thought about instead what I described above:

  • making just one component for all the “bar” elements which will observe the model and position all it’s elements using jquery. But I figured this goes a little bit against the framework, as I manually position the elements.
  • using D3 maybe… I don’t really know it… is that what I need for this type of task?

#3

You’ll run into a lot of issues with that many components (I know from experience). Here’s two things I did to solve a similar problem (I had a large list of row elements).

  1. Lazy load the items if they don’t all fit on screen at once. If the user scrolls far enough the page will be slow, but I’m not worried about that right now. (If you are, try ember-cloaking. I couldn’t get it to work in my scenario, but maybe you can.)

  2. Rather than attaching inline styles, append a dynamic stylesheet to the head of your page. Using didInsertElement and willDestroyElement allowed me to attach styles that would affect all of my rows without having to put bound styles on every element.

These may not work for you, but they’re worth a shot. One thing I can promise you: Ember is robust enough to solve your problem, you just might have to think outside the box. :slight_smile:


#4

Thanks! I’ll give ember-cloaking a closer look… btw I noticed I need to give it a view’s name… is that mean I will need to wrap my component inside a view?

What do you mean by “dynamic spreadsheet”? you mean stylesheet? well how would I position each “bar” in its own position? create a class for each bar? is that better then inline styling?


#5

You wouldn’t create a component, you would create a separate view and controller that you could give to the {{cloaked-collection}} helper.

And yes, I mean stylesheet. For me, my items followed a formula that could be decided at runtime, so I was able to use a stylesheet. You might not have that option (it sounds like you don’t).


#6

I see. Thanks! One more thing, I notice my app freezes for many seconds while its rendering all those elements… Can I somehow use Ember.run.later to avoid the freeze (maybe doing a simpler version of cloaking of just cutting all the elements I need to render into chunks and rendering each of them in a separate ember run loop)?


#7

That is also an issue I dealt with. For me, it was happening because my promises weren’t resolved yet. Ember would render the template and leave my handlebars expressions blank. Then, when the promise resolved, it would freeze the application to update the DOM. When that happens several dozen (or hundred) times, there’s a pause. My solution was to pause the router until the promises all resolved so the template only rendered once. You can learn more about pausing the router here.


#8

OK, for now I’m just splitting my data into chunks and add it chuck by chunk with Ember.run.later This helps with the freeze and gives a better perceived-performance.

Would you guys say that binding to an element’s style attribute in order to set it’s position is wrong?


#9

Wrong? Probably not. Something you want to avoid if you can? Probably. I have one particular template that I do this in because the functionality I want isn’t available in CSS (not even flexbox). I don’t think there’s anything inherently wrong with it, but I try to avoid it for two reasons:

  1. It adds more bindings, which is a performance hit. The browser will apply CSS 1000x faster than Ember will update a binding, so if you can use CSS use it.
  2. It could cause the style to change several times in quick succession. If a property is being updated quickly and Ember is trying to update the DOM every time, it could cause layout thrashing.

But if you know the downsides and take efforts to mitigate them, I don’t see any reason why it should be a bad thing.


#10

Thank you for your patience!

I’m looking at integrating D3js for rendering my data visualization. Will I have any problems integrating the two? for example with event handling or something of that nature?