【问题标题】:How to get around angulars performance issue with large content如何解决大内容的角度性能问题
【发布时间】:2016-02-13 07:04:20
【问题描述】:

我熟悉 Angular 的摘要循环以及它如何影响长列表和大模型值的性能。我只是好奇您是否有针对我的情况专门针对该问题的任何解决方法。 我正在构建一个应用程序,它可能需要也可能不需要用户在textarea 中输入大文本,例如错误日志,但由于与 大型模型 上的 2 路数据绑定相关的角度固有问题它导致我的应用程序挂起。

目前我要求用户在文件中附加大量内容。但我想知道是否有任何方法可以解决这个问题。 我能想到的一种潜在解决方法是不在文本字段上使用模型,而是使用 Angular 的轻量级 jquery api angular.element('#mytext').val() 访问文本。但是这种方法存在将 JS 代码与 DOM 紧密绑定的缺点,这不是一个好的做法。我对更多“棱角分明”的解决方案感兴趣。

这是演示性能问题的 plunkr。要查看挂起,请开始在文本区域中输入,您会遇到严重的延迟

http://plnkr.co/edit/0wccRJjjlhJqZtdipDLv?p=preview

【问题讨论】:

  • 在用户介绍文字时尝试使用节流功能。
  • 你的意思是去抖动吗?如果是这样,我已经有 1 秒的去抖,它会产生轻微的差异,但不够显着
  • throttle 将允许您在用户在 1 秒后完成引入字符时执行代码。但是debounce功能也可以,但是会在文字介绍时每1秒执行一次。
  • 您需要模型在 keyup 时更新,还是可以将其限制为仅在更改时更新?查看 ng-model-options:docs.angularjs.org/api/ng/directive/ngModelOptions

标签: javascript angularjs performance data-binding


【解决方案1】:

瓶颈不是摘要(它会有所贡献,但可以使用 ngModelOptions 'debounce' option 有效地对抗),而是在元素上使用 ng-modela listener added by textarea directive

这种性能问题建议使用自定义指令而不是内置指令(在这种情况下为ngModel)。对于双向绑定,它可能是

app.directive('bigText', function () {
  return {
    scope: {
      bigText: '='
    },
    template: '<textarea>',
    link: function (scope, element) {
      // .val(value) on directive init
      var initialized = false;
      // prevents .val(oldValueFromOutside) on input
      var internalChange = false;
      var $textarea = element.find('textarea');

      scope.$watch('bigText', function (oldVal, newVal) {
        if (internalChange || (initialized && oldVal === newVal)) return;
        initialized = true;
        $textarea.val(newVal);
      });

      // generic JS debounce,
      // for ex. https://github.com/niksy/throttle-debounce
      var handler = debounce(1000, function () {
        var text = $textarea.val();
        if (scope.bigText !== text) {
          internalChange = true;
          scope.$apply(function () {
            scope.bigText = text;
          });
          internalChange = false;
        }
      });
      $textarea.on('change keyup', handler);
      // $textarea.off on scope destroy
    }
  };
});

手动维护双向绑定的重要部分是使用internalChange 标志,它可以防止从外部范围获取旧值作为摘要上的newVal(鸡/蛋困境)。

也可以从 Angular 指令对输入事件 for performancecompatibility 的处理中学到一些东西。

请注意,类似的性能问题可能是由Chrome bug 引起的,而不是由 Angular 应用程序引起的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多