kineticjs的性能问题

kineticjs的性能问题,kineticjs,Kineticjs,随着画布上形状数量的增加,kineticjs出现了一些严重的性能问题。我有两个函数,一个用于初始化路径和文本,并在舞台上呈现它们。第二个函数每5秒调用一次,并更新先前绘制的路径和文本上的任何更改。 这是我正在尝试的一个示例片段 /** * Function that inits the shapes */ init = function(params) { //Create the path object var path = new Kinetic.Path({

随着画布上形状数量的增加,kineticjs出现了一些严重的性能问题。我有两个函数,一个用于初始化路径和文本,并在舞台上呈现它们。第二个函数每5秒调用一次,并更新先前绘制的路径和文本上的任何更改。 这是我正在尝试的一个示例片段

  /**
  * Function that inits the shapes
  */
  init = function(params) {
  //Create the path object
  var path = new Kinetic.Path({
    data : params.geom,
    fill : params.fill,
    stroke : params.stroke.fill,
    strokeEnabled : false,
    scale : 1
  });
  path.setId(params.id + '.path');
  var simpleText = new Kinetic.Text({
    x : params.x,
    y : params.y + (params.height /2),
    text : params.displayText,
    fontSize : 12,
    fontFamily : params.family,
    fontStyle : params.style,
    fill : params.fill
  });
  simpleText.setId(params.id + '.text');

  var layer = new Kinetic.Layer();
  layer.setId(params.id);
  layer.add(path);
  layer.add(simpleText);
  stage.add(layer);
}

/**
* Update every 5 seconds based on new data
*/
update = function(params) {
  var layer = null;
  if (Kinetic.Global.ids[params.id] != undefined) {
    layer = Kinetic.Global.ids[params.id];
    //Set text
    var textItem = Kinetic.Global.ids[params.id + '.text'];
    textItem.setText(params.displayText);
    //center the text
    textItem.setAttr('x', params.x + (params.width / 2) - (textItem.textWidth / 2));
    textItem.setAttr('y', params.y + (params.height / 2) -            textItem.getAttr('fontSize'));
    // set center style
    textItem.setAlign('center');
    //Set path color
    var pathItem = Kinetic.Global.ids[params.id + '.path'];
    pathItem.setFill(params.fill);
    pathItem.setOpacity(params.alpha);

    layer.clear();
    layer.draw();
  }
}
随着要绘制的形状数量的增加,此代码将变得缓慢并消耗大量内存。
上面的代码中可能有很多地方需要改进,我正在寻找这些指针。具体地说,我不确定Id查找和更新是否是更新现有形状的最佳方式。

您可以使用
层.get('#someID')
函数,而不是通过
动能.Global.ids
对象查找对象。不确定这是否对性能有很大帮助,但这只是一个开始

另外,我不认为每次更新时都需要使用
layer.clear()
layer,是吗?我认为
layer.draw()
应该足以更新形状

建议:您可能只需要每5秒使用一次
drawsecene()
,而不是
draw()。有关动能绘制函数之间的差异,请参见此处:

不管怎样,每5秒在一个层上使用
draw()
方法将非常昂贵,尤其是当层中开始有很多形状时

另一个重要问题是:您的对象是否总是每5秒更改一次?我的意思是,也许有时候你可能不需要绘制图层,因为没有更新发生。如果可以检查对象是否已更新,则可以决定是否需要调用更新函数以及是否需要重新绘制图层

我的最后一个建议建立在上面提到的最后一点的基础上,可能您不需要每次都重新绘制图层,从而重新绘制图层内的所有对象,其中可能没有更新图层中的所有对象(并且需要重新绘制)可能只有部分对象已更新。在这种情况下,如果使用
Kinetic.Group
将每个文本/路径分组在一起,则可以使用
Group.draw()
而不是
layer.draw()
。现在,如果您可以找到每5秒更新数据的组,则只需绘制
动能.Group
,而不是每5秒绘制整个层

顺便说一下,您也可以像这样使用
.get()
函数:

var layers = stage.get('Layer'); // Returns an array of all Kinetic.Layers inside stage
var groups = layers[0].get('Group'); // Returns an array of all Kinetic.Groups inside the first layer (in the layers array)

有关get方法的更多信息,请参见此处:

您可以使用
层.get('#someID')
函数,而不是通过
动能.Global.ids
对象查找对象。不确定这是否对性能有很大帮助,但这只是一个开始

另外,我不认为每次更新时都需要使用
layer.clear()
layer,是吗?我认为
layer.draw()
应该足以更新形状

建议:您可能只需要每5秒使用一次
drawsecene()
,而不是
draw()。有关动能绘制函数之间的差异,请参见此处:

不管怎样,每5秒在一个层上使用
draw()
方法将非常昂贵,尤其是当层中开始有很多形状时

另一个重要问题是:您的对象是否总是每5秒更改一次?我的意思是,也许有时候你可能不需要绘制图层,因为没有更新发生。如果可以检查对象是否已更新,则可以决定是否需要调用更新函数以及是否需要重新绘制图层

我的最后一个建议建立在上面提到的最后一点的基础上,可能您不需要每次都重新绘制图层,从而重新绘制图层内的所有对象,其中可能没有更新图层中的所有对象(并且需要重新绘制)可能只有部分对象已更新。在这种情况下,如果使用
Kinetic.Group
将每个文本/路径分组在一起,则可以使用
Group.draw()
而不是
layer.draw()
。现在,如果您可以找到每5秒更新数据的组,则只需绘制
动能.Group
,而不是每5秒绘制整个层

顺便说一下,您也可以像这样使用
.get()
函数:

var layers = stage.get('Layer'); // Returns an array of all Kinetic.Layers inside stage
var groups = layers[0].get('Group'); // Returns an array of all Kinetic.Groups inside the first layer (in the layers array)

有关get方法的更多信息,请参见此处:

这些都是很好的观点,我已经实现了一些,谢谢!然而,显著提高性能的变化是,我的每个图形项(包括路径和文本)都只使用一个图层,而不是一个图层。我的要求是支持大约1000个图形项,每个图形项都有一个路径和一个文本,现在看来可以了。然而,如果需求改变以支持更多,我相信我可能需要的不仅仅是一个层。是的,肯定!您不希望每个项目都有一个层(不确定这在上面的代码中是否明显),因为这将对性能造成巨大影响。试想一下,每层向DOM添加2个画布,一个用于渲染节点,另一个用作命中画布。相反,如果您需要将节点分组在一起,请使用“查看此链接”了解更多信息:谢谢,组已经就位,性能也更好。这些都是很好的观点,我已经实现了一些感谢!然而,显著提高性能的变化是,我的每个图形项(包括路径和文本)都只使用一个图层,而不是一个图层。我的要求是支持大约1000个图形项目,每个项目都有一个路径和一个文本,这似乎是可行的