淘汰组件或模板性能提升

我有一个可观察的数组。 对于每个数组元素,我生成一些非常扩展的html表单,因为可观察数组项是依次具有可观察对象的大对象:

var records = ko.observableArray([ { p1: ko.observable("initProp1"), p2: ko.observable("initProp2"), // and so on pN: ko.observable("initPropN") }, //... ]); 

html可以是大型的,复杂的和动态的,在一些属性本身的基础上改变:为了实现这一点,我使用了ko:if bindings,已知在计算上是昂贵的( http://www.knockmeout。 net / 2012/03 / knockoutjs-performance-gotcha-1ifwith.html ),特别是对于有条件渲染的大型HTML。 性能开始受到影响,特别是在IE上。

注意到重复的,即使是动态的结构,我正在考虑直接在html中使用模板或组件intead绑定数据。 我会为每个动态配置使用不同的模板/组件。

一般来说,使用组件或模板可以提供性能增益,或者内部Ko可以完全按照我不使用的方式进行操作吗? 渲染模板和组件之间的性能有何不同?

否则,我正在考虑通过JQuery每条记录生成HTML,然后使用ko.applyBindingsToNode()动态绑定observables – 这可以提供性能提升吗?

我做了一些(减少的)测试,但我需要对问题进行一些跨浏览器的通用评估。 测试似乎不一致取决于我使用的浏览器甚至是我的数据集,并且无论如何都没有正确反映我的复杂性。 直接在应用程序上进行测试意味着太多的工作,可能是无用的,这是我买不起的,所以一般的指导方针对于至少提供一个用于实际实现和测试的解决方案的提示是很宝贵的。

从你的小提琴,我看到你将每个字段渲染为一个单独的项目。 如果每个项目的显示方式相同,则可以绕过所有if绑定,作为自定义绑定的文本项目,单击该项目时,将转换为其可编辑的字段类型。

如果要保留制表符,可以输入默认演示文稿,但在焦点时,会显示相应的字段类型。

更新:我发现你甚至可以让你的自定义绑定将相应的输入类型插入到绑定的div ,因此你的演示文稿将完全如此,但所有逻辑都在自定义绑定中。

我做了一个动态插入适当类型输入的小提琴 。 这有点粗糙,但给出了方法的一般概念。 我不知道它是否比if绑定更具性能优势; 它可能只是以艰难的方式做同样的事情。 当然,上述在文本或简单输入中呈现并在用户想要编辑时改变一个字段的建议在初始加载时会更快。

我制作了一个使用组件来提供输入字段的小提琴版本。 使用的组件名为“my-”加上type字段(这是区分我的组件与inputselect标签所必需的)。 我不知道这会有多好,但它很简单,你应该能够做一些测试,看看。

 ko.components.register('my-input', { viewModel: InputModel, template: { element: 'input-template' } }); ko.components.register('my-select', { viewModel: InputModel, template: { element: 'select-template' } }); ko.components.register('my-mu', { viewModel: InputModel, template: { element: 'mu-template' } }); function InputModel(params) { return params; } function Model() { records = ko.observableArray([ [{ type: "input", id: "Date", size: "100px", value: ko.observable() }, { type: "select", id: "Weather", size: "100px", value: ko.observable(), options: [{ optId: "w1", optTxt: "Cloudy" }, { optId: "w2", optTxt: "Sunny" }, { optId: "w3", optTxt: "Rainy" }, { optId: "w4", optTxt: "Snowy" }, { optId: "w5", optTxt: "Foggy" }] }, { type: "input", id: "Lat", size: "80px", value: ko.observable() }, { type: "input", id: "Long", size: "80px", value: ko.observable() }], [{ type: "input", id: "Date", size: "100px", value: ko.observable() }, { type: "select", id: "Temperature", size: "120px", value: ko.observable(), options: [{ optId: "t0", optTxt: "<-10" }, { optId: "t1", optTxt: "]-10 : 0]" }, { optId: "t2", optTxt: "]0 : 20]" }, { optId: "t3", optTxt: "]20 : 40]" }, { optId: "t4", optTxt: ">40" }] }, { type: "select", id: "Wind", size: "70px", value: ko.observable(), options: [{ optId: "wind1", optTxt: "Strong" }, { optId: "wind2", optTxt: "Weak" }] }], [{ type: "input", id: "Date", size: "100px", value: ko.observable() }, { type: "select", id: "Weather", size: "100px", value: ko.observable(), options: [{ optId: "w1", optTxt: "Cloudy" }, { optId: "w2", optTxt: "Sunny" }, { optId: "w3", optTxt: "Rainy" }, { optId: "w4", optTxt: "Snowy" }, { optId: "w5", optTxt: "Foggy" }] }, { type: "input", id: "Lat", size: "80px", value: ko.observable() }, { type: "input", id: "Long", size: "80px", value: ko.observable() }], [{ type: "input", id: "Date", size: "100px", value: ko.observable() }, { type: "select", id: "Temperature", size: "120px", value: ko.observable(), options: [{ optId: "t0", optTxt: "<-10" }, { optId: "t1", optTxt: "]-10 : 0]" }, { optId: "t2", optTxt: "]0 : 20]" }, { optId: "t3", optTxt: "]20 : 40]" }, { optId: "t4", optTxt: ">40" }] }, { type: "input", id: "Humidity", size: "70px", value: ko.observable(), options: [{ optId: "wind1", optTxt: "Strong" }, { optId: "wind2", optTxt: "Weak" }] }, { type: "mu", id: null, value: '%' } ] ]); } var myModel = new Model(); ko.applyBindings(myModel);