Skip to content
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

Ember.Select is slow with many options (~200) #633

Closed
sandstrom opened this issue Mar 30, 2012 · 9 comments
Closed

Ember.Select is slow with many options (~200) #633

sandstrom opened this issue Mar 30, 2012 · 9 comments

Comments

@sandstrom
Copy link
Contributor

Ember.Select is fairly slow with many options, say a country select with 199 countries to choose from.

It's slow because 200 views are created, one for every option. This is useful if the underlying collection changes, because changes are reflected. But typically select options are static.

The following code solves the problem, with the drawback of static options. Is this something you would like to include? If so I'll open a pull request.

Also, please let me know if you have any improvement suggestions.

// A static select where options aren't child-views but plain option tags.
// This implementation is currently much faster than Ember.Select on large collections.

(function() {
var set = Ember.set, get = Ember.get, getPath = Ember.getPath;

Ember.Select = Ember.View.extend({

  staticLabels: false,

  render: function(buffer) {

    var labelKey = get(this, "optionLabelPath").replace("content.", "");
    var valueKey = get(this, "optionValuePath").replace("content.", "");

    if (get(this, "staticLabels")) {

      var output = "";
      if (get(this, "prompt")) {
        output += "<option>" + get(this, "prompt") + "</option>";
      }
      output += get(this, "content").map(function(obj){
        return "<option value='"+get(obj, valueKey)+"'>"+get(obj, labelKey)+"</option>";
      }).join("");

      buffer.push(output);

    } else {
      this._super(buffer);
    }
  },

});
})();
@krisselden
Copy link
Contributor

One problem, you aren't escaping the values.

var escape = Handlebars.Utils.escapeExpression

escape(get(this, "prompt"))
escape(get(this, valueKey))
escape(get(this, labelKey))

@sandstrom
Copy link
Contributor Author

Yes, good point! Thanks

@ebryn
Copy link
Member

ebryn commented Mar 30, 2012

I don't think Select itself is the problem. It's likely the EachView/CollectionView that is rendering the options. We've done some work to improve the performance of them.

@sandstrom What version of Ember are you using?

@sandstrom
Copy link
Contributor Author

@ebryn I'm using 0.9.5

@wagenet
Copy link
Member

wagenet commented Mar 31, 2012

@sandstrom Now that 0.9.6 is out can you give that a try?

@sandstrom
Copy link
Contributor Author

Only have a few minutes now, but I took a quick look and Ember.Select with 200 options is faster in 0.9.6 (don't have time to benchmark, so I don't know by how much). However, still not the instantaneous feeling the the hack above gives.

But then, generating 200 views isn't something that one does often, select labels seems like an exception.

@krisselden
Copy link
Contributor

Aside from the lack of escaping, I don't think what you did is a hack. It is just unbound, I do stuff like this as needed in app code, but it not responding to changes is too surprising to be a replacement for the general purpose control.

@sandstrom
Copy link
Contributor Author

Yes, I agree. Maybe re-generating all options if one of them changed (e.g. an @each observer), or just close since the performance improvements in 0.9.6 has mitigated this problem.

@wagenet
Copy link
Member

wagenet commented Apr 17, 2012

@sandstrom I will close this for now. We do have some other ideas for performance improvements that are on our radar.

@wagenet wagenet closed this as completed Apr 17, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants