angular.js $应用瓶颈

时间:2015-12-04 11:50:20

标签: javascript angularjs d3.js svg

我正在使用实时数据在网页上使用SVG绘制一些线条。为了管理我使用Angular.js的数据并管理可视化,我使用D3.js.

我设置一个角度控制器来保存数据(线)。数据由一些点数组成(带有x / y坐标的字典)。有些行在初始化时已知,其他行根据实时数据更新。

我设置了一个包含SVG元素的角度指令(' topView')。对于初始化时的每一行,我使用以下命令将其添加为路径:

var routeLeftLine = container.select("#routes").append("path");            
var routeLeftLineData = scope.val.route.left; // -> 1000+ points in there
routeLeftLine
            .attr("d", lineFunction(routeLeftLineData))
            .attr("stroke", "black")
            .attr("stroke-width", 1)
            .attr("fill", "none");

对于我想要不断更新的每一行(1),我设置了一个角度指令,例如:

<surface-cable val="data.cable"></surface-cable>

其中data是我控制器上的数据对象,data.cable是点数组。 该指令如下所示:

OCMSWeb.directive('surfaceCable', function ( /* dependencies */ ) {
return {
    restrict: 'AE', 
    scope: { 
        val: '='
    },
    templateNamespace: 'svg',
    replace: true,
    template: '<g/>',
    link: function (scope, element, attrs) {
        var cableLine = d3.select(element[0]).append("path");

        scope.$watch('val', function () {
            var cableLineData = simplify(scope.val, 1, false); // size grows in time

            cableLine
                .attr("d", lineFunction(cableLineData))
                .attr("stroke", "rgb(240,144,32)")
                .attr("stroke-width", 1)
                .attr("fill", "none");
        }, true);
    }
};
});

当我使用计时器更新数据时,结构工作正常,更改反映在SVG中。

当我增加一行中的点数(> 1000,我将来还需要更多)时出现问题(两者都是不变的,更新的行都有这个效果)性能下降。即使要重绘的元素还不包含许多元素,行的更新也会变得非常慢。

我无法找到原因。 SVG / d3 / angular是否再次渲染svg中的所有元素?
我绑定数据的方式效率低下吗?我应该一起跳过d3吗?

我试图分析javascript的性能,大约80-90%的CPU时间似乎是针对angular $ apply的调用(我认为,扫描DOM进行更改?)。如果元素(行是<path>元素)有很多数据点,为什么$ apply需要这么长时间呢?

2 个答案:

答案 0 :(得分:1)

使用此体系结构,每次更改范围内的任何内容时,1000行表示1000个指令,1000个监视和1000个值比较,无论这些值是否实际更改。我怀疑这里的根本问题是你的d3代码,虽然不必要地重新设置笔画,笔画宽度和填充的属性肯定没有帮助。

一般来说,更好的方法是使用单个指令获取行数并处理SVG中所有电缆路径的布局。如果您正在查看数以千计的路径,那么您可能希望在画布上而不是SVG上进行渲染。

答案 1 :(得分:0)

虽然@ ethan-jewett没有完全回答我的问题,但是你做到了  然而,我指出了正确的方向。

因为我将控制器的'data'字典(包含静态和动态数据)链接到指令,我假设angular会检查其中的所有值以进行更改。通过将静态数据移出此“数据”字典,它不会被检查并使此设置更快。

当我增加动态数据的大小时,分析仍会产生角度变慢,我认为这是出于同样的原因(角度需要检查所有数据的变化)。我不确定我将如何解决这个问题:我将研究D3.js是否有更有效的机制来检测数据中的变化,或者我会将我的长阵列分成静态和动态部分(因为它们代表路径/电缆,只有电缆的末端才能真正改变。在某些时候,电缆的很大一部分可以被认为是静态的。)。