避免模​​块化视图模型上的全局重绘

时间:2014-12-08 09:30:31

标签: mithril.js

我怎样才能避免对主视图函数进行全局重绘=调用 在更改子模块的视图时,就像在主模块视图方法中一样:

m("body", [
           m("#head", {...}),
           Menu.show(this),
           Footer.show(this)
])

静态show方法如下所示:

    function show(app)
    {
        if (inst == null)
            inst = new Footer(app);
        return inst.view(app);
    }

现在它应该增加已经很好的性能,如果有一种方法来运行view方法 如果子视图中的更改只有子视图,则不运行主视图方法 局部效应。这有意义吗?

阿克塞尔

2 个答案:

答案 0 :(得分:3)

您无法阻止全局重绘,但您可以使用subtree directives

选择性地使视图的某些部分不重绘

请注意,这是一项性能优化,会禁用受影响子树的重绘,因此,除非再次使用子树替换指令,否则无法更新其视图。

答案 1 :(得分:1)

Redraw是Mithril的一项全球运作,这迫使你进行的结构决策是设计的。 Mithril不是公开允许从应用程序中的任何给定点精确控制视图渲染过程的API,而是通过专门的差异算法来处理整个过程,比较优化的虚拟DOM模型的迭代。

话虽如此,有些方法可以根据上下文影响差异逻辑和渲染实现:

  1. 在适当的时间使用nonediff参数调用m.redraw.strategy可以完全防止重绘或避免分别完全重绘DOM。在我的应用程序中,一个特别复杂的模块会不断触发并响应路由更改(多个列表,其中每个项目本身就是一个子模块化的DOM结构,可选的额外小部件等) - 通过在控制器中设置m.redraw.strategy( 'diff' ),我管理即使在仅修改不同的DOM块(仍然是大块!)时,仍将性能保持在~55FPS。
  2. 在您希望从差异例程中删除的虚拟DOM部分上调用{ subtree : 'retain' }。如果您有大块DOM,您希望diff算法被忽略(因此后续重绘不会触及),您可以在视图中指定此特殊参数。请注意,如果您稍后决定删除子树保留指令,则必须至少重新呈现整个内部DOM树,因为之前的迭代不会被diff引擎注册 - 所以我不会建议尝试二次猜测或使用此算法进行差异化算法。
  3. 使用{ key : 'uniqueIdentifier' }突出显示diff算法可能识别为新的元素。如果你有一块视图相对于它在重绘之间的DOM中的旧位置移动,则diffing算法将破坏旧的并从头开始渲染新的。指定唯一的key将允许它确定它应该移动现有的DOM结构,并在那里应用任何补丁。如果一个庞大而复杂的DOM结构改变了它的位置,但是如果在大量的小项上使用它就会开始对性能起作用,这很有用。例如,在我的应用程序中,我为每个列表项添加了键(每个列表项都是一个至少包含8个元素,事件处理程序等的子模块),以避免重新绘制仅在列表中移动的项目。事实证明,删除key并在他们移动时从头开始创建元素的性能提高了100%。
  4. 但我的建议是让秘银做他们认为最好的事情。秘银比其他MVC库的视图组件的主要优势之一是,秘银可以让你在90%的时间内忘记重绘周期,并在需要时让它发生。这是一个优势!另外要记住的是,无数人花了无数的开发人员时间试图让Javascript MVC渲染速度更快 - 而且Mithril是最快的之一。机会是,在大多数情况下,秘银核心可能比在第二次猜测其内部逻辑时更加优化。正如我上面的经验所表明的那样,引入额外的代码以试图提高性能实际上违背了我的期望。秘银的速度非常快 - 这应该让我们在其他问题上花费我们的创造力!