Performance 将Fabric.JS与Angular 2一起使用时出现性能问题

Performance 将Fabric.JS与Angular 2一起使用时出现性能问题,performance,angular,canvas,fabricjs,Performance,Angular,Canvas,Fabricjs,在Angular 2应用程序中,我使用Fabric.JS在画布中拖动元素。当我在手机上打开我的应用程序时,在拖动项目时会有相当大的延迟。在最初的几秒钟内,延迟并不存在,但随着我拖拽物品的时间越来越长,延迟变得越来越严重 我决定在不使用Angular 2的情况下使用Fabric.JS进行测试,发现在不使用Angular 2的情况下没有延迟 在下面的代码示例中,我将向画布添加三个方形对象。只有这三个对象的延迟几乎不明显,但如果我添加更多更复杂的对象,它会变得非常糟糕 我的滞后角度2组件: impor

在Angular 2应用程序中,我使用Fabric.JS在画布中拖动元素。当我在手机上打开我的应用程序时,在拖动项目时会有相当大的延迟。在最初的几秒钟内,延迟并不存在,但随着我拖拽物品的时间越来越长,延迟变得越来越严重

我决定在不使用Angular 2的情况下使用Fabric.JS进行测试,发现在不使用Angular 2的情况下没有延迟

在下面的代码示例中,我将向画布添加三个方形对象。只有这三个对象的延迟几乎不明显,但如果我添加更多更复杂的对象,它会变得非常糟糕

我的滞后角度2组件:

import {Component, OnInit, ViewChild, ElementRef} from '@angular/core';
import 'fabric';
declare let fabric;

@Component({
  selector: 'app-fabric-canvas',
  template: `
    <canvas #canvas width="800" height="800"></canvas>
  `
})
export class FabricCanvasComponent implements OnInit {

  @ViewChild('canvas') canvasRef:ElementRef;
  private canvas: any;
  private square1;
  private square2;
  private square3;

  ngOnInit() {
    this.canvas = new fabric.Canvas(this.canvasRef.nativeElement, { });

    this.square1 = new fabric.Rect({
      width: 50,
      height:50,
      left: 0,
      top: 0,
      fill:'red'
    });

    this.square2 = new fabric.Rect({
      width: 50,
      height:50,
      left: 0,
      top: 0,
      fill:'blue'
    });

    this.square3 = new fabric.Rect({
      width: 50,
      height:50,
      left: 0,
      top: 0,
      fill:'green'
    });

    this.canvas.add(this.square1);
    this.canvas.add(this.square2);
    this.canvas.add(this.square3);
  }
}
<canvas id="canvas" width="800" height="800"></canvas>

<script>
    var canvas = new fabric.Canvas('canvas');

    var square1 = new fabric.Rect({
        width: 50,
        height:50,
        left: 0,
        top: 0,
        fill:'red'
    });

    var square2 = new fabric.Rect({
        width: 50,
        height:50,
        left: 0,
        top: 0,
        fill:'blue'
    });

    var square3 = new fabric.Rect({
        width: 50,
        height:50,
        left: 0,
        top: 0,
        fill:'green'
    });

    canvas.add(square1);
    canvas.add(square2);
    canvas.add(square3);

</script>
从'@angular/core'导入{Component,OnInit,ViewChild,ElementRef};
进口"织物";;
申报纺织品;
@组成部分({
选择器:“应用程序结构画布”,
模板:`
`
})
导出类FabricCanvasComponent实现OnInit{
@ViewChild(“canvas”)canvasRef:ElementRef;
私人画布:任何;
私人广场1;
私人广场2;
私人广场3;
恩戈尼尼特(){
this.canvas=new fabric.canvas(this.canvasRef.nativeElement,{});
this.square1=new fabric.Rect({
宽度:50,
身高:50,
左:0,,
排名:0,
填充:“红色”
});
this.square2=新织物.Rect({
宽度:50,
身高:50,
左:0,,
排名:0,
填充:“蓝色”
});
this.square3=新织物.Rect({
宽度:50,
身高:50,
左:0,,
排名:0,
填充:“绿色”
});
this.canvas.add(this.square1);
this.canvas.add(this.square2);
this.canvas.add(this.square3);
}
}
我的测试不使用角度2且不滞后:

import {Component, OnInit, ViewChild, ElementRef} from '@angular/core';
import 'fabric';
declare let fabric;

@Component({
  selector: 'app-fabric-canvas',
  template: `
    <canvas #canvas width="800" height="800"></canvas>
  `
})
export class FabricCanvasComponent implements OnInit {

  @ViewChild('canvas') canvasRef:ElementRef;
  private canvas: any;
  private square1;
  private square2;
  private square3;

  ngOnInit() {
    this.canvas = new fabric.Canvas(this.canvasRef.nativeElement, { });

    this.square1 = new fabric.Rect({
      width: 50,
      height:50,
      left: 0,
      top: 0,
      fill:'red'
    });

    this.square2 = new fabric.Rect({
      width: 50,
      height:50,
      left: 0,
      top: 0,
      fill:'blue'
    });

    this.square3 = new fabric.Rect({
      width: 50,
      height:50,
      left: 0,
      top: 0,
      fill:'green'
    });

    this.canvas.add(this.square1);
    this.canvas.add(this.square2);
    this.canvas.add(this.square3);
  }
}
<canvas id="canvas" width="800" height="800"></canvas>

<script>
    var canvas = new fabric.Canvas('canvas');

    var square1 = new fabric.Rect({
        width: 50,
        height:50,
        left: 0,
        top: 0,
        fill:'red'
    });

    var square2 = new fabric.Rect({
        width: 50,
        height:50,
        left: 0,
        top: 0,
        fill:'blue'
    });

    var square3 = new fabric.Rect({
        width: 50,
        height:50,
        left: 0,
        top: 0,
        fill:'green'
    });

    canvas.add(square1);
    canvas.add(square2);
    canvas.add(square3);

</script>

var canvas=newfabric.canvas('canvas');
var square1=新结构.Rect({
宽度:50,
身高:50,
左:0,,
排名:0,
填充:“红色”
});
var square2=新结构.Rect({
宽度:50,
身高:50,
左:0,,
排名:0,
填充:“蓝色”
});
var square3=新结构.Rect({
宽度:50,
身高:50,
左:0,,
排名:0,
填充:“绿色”
});
canvas.add(square1);
canvas.add(平方2);
canvas.add(square3);

问题是:为什么我只有在将Fabric.JS与Angular 2一起使用时才会遇到这种延迟?我在Angular 2组件中导入或使用Fabric.JS的方式是否有问题?

我遇到了完全相同的问题(只有触摸)。我制作了一个全新的Angular 2项目,添加了布料,每次触摸都会减慢拖动速度

我花了好几个小时寻找解决办法。角度变化检测策略没有帮助,NgZone也没有。最终,我找到了一个修复方法,从Fabric源代码中删除了两行代码。我在他们的GitHub上提交了一个问题:

删除以下两行为我修复了延迟:
-
addListener(this.upperCanvasEl,'touchmove',this.\u onMouseMove,{passive:false})\u onMouseUp()
-函数
-
addListener(fabric.document,'touchmove',this.\u onMouseMove,{passive:false})\u onMouseDown()
-函数进行编码


我不确定删除这些功能是否可行,但当Fabric背后的人员正在进行合法修复时,您可以将其用作解决方案。

问题来自Zone.js不支持EventListenerOptions(被动等)。支持增加在v。0.8.7:

我可能不是angular2专家,但据我所知angular不是运行密集型fps相关应用程序的地方,有一种解决方案我还没有探索过,叫做在angular的区域外运行代码。比如说谢谢你的提示,这可能正是我需要的。我会试试的。我已经用Fabric.js在Angular 2中实现了座位预订应用程序,即使有1000个座位(矩形),我也没有问题。这是我的项目。在这个项目中,我刚刚测试了1000个项目,我发现我的移动设备没有问题。你允许用户交互吗?比如,移动、缩放、更新对象?如果没有,这可能就是你没有遇到任何问题的原因。谢谢你的建议。我用NgZone做了一些测试,我相信它能正常工作。但由于其他一些问题,我最终在我的项目中使用了PIXI.JS,而不是Fabric。我正在使用Angular 4和Ionic 3构建一个应用程序,遇到了完全相同的问题:在浏览器上工作正常,但在尝试平移/旋转对象时会出现明显的延迟。通过删除本文中建议的行,滞后问题得以解决。非常感谢你。