CirclonGroup / angular-tree-component

A simple yet powerful tree component for Angular (>=2)
https://angular2-tree.readme.io/docs
MIT License
1.09k stars 488 forks source link

Solution: Low performance on scrolling. Performance boost #958

Closed dmitriy-fullstack-2010 closed 11 months ago

dmitriy-fullstack-2010 commented 11 months ago

Guys, I'm sorry, I will publish the ticket not according to the format, but I want to share a solution to the performance problem. I am using the latest version of the plugin. The fact is that I need to display a list of a large volume, 1000 or more items. But the plugin, for inexplicable reasons, slows down a lot when scrolling. I suffered for a long time. Even the introduction of virtual scrolling did not help.

As a result, the solution solution turned out to be simple. It turns out that the plugin tracks mouseover, mouseout events inside the tree-node-wrapper component. And this is a terribly slow thing.turned out to be simple. It turns out that the plugin tracks mouseover, mouseout events inside the tree-node-wrapper component. And this is a terribly slow thing. https://github.com/CirclonGroup/angular-tree-component/blob/19b58abe33dcbddbcba80c80ed26babfb7d43a16/projects/angular-tree-component/src/lib/components/tree-node-wrapper.component.ts#L17C17-L17C17 I removed these 2 lines and the list started flying, even with 3000 items on the page without virtualscroll.

At the same time, even the dragndrop functionality seems to continue to work correctly. Judging by the source code, these events are mostly needed to track the focus on the element, which can be sacrificed for the sake of performance.

To remove these event trackers, it is enough to redefine the template according to the instructions https://angular2-tree.readme.io/docs/templates#treenodewrappertemplate . Not all the templates in the instructions are actual, I recommend to be carefuly.

WARNING: If you are using mouseover, mouseout events, or use focuss css class, this changes can mess up the expected behavior. Use this solution with caution. I don't recommend it unless you have performance issues.

I am using this template:

      <ng-template #treeNodeWrapperTemplate let-index="index" let-node let-templates="templates">
        <div [style.padding-left]="node.getNodePadding()" class="node-wrapper">
          <tree-node-checkbox *ngIf="node.options.useCheckbox" [node]="node"></tree-node-checkbox>
          <tree-node-expander [node]="node"></tree-node-expander>

          <div (click)="node.mouseAction('click', $event)"
               (contextmenu)="node.mouseAction('contextMenu', $event)"
               (dblclick)="node.mouseAction('dblClick', $event)"
               (treeDrop)="node.onDrop($event)"
               (treeDropDragEnter)="node.mouseAction('dragEnter', $event)"
               (treeDropDragLeave)="node.mouseAction('dragLeave', $event)"
               (treeDropDragOver)="node.mouseAction('dragOver', $event)"
               [allowDragoverStyling]="node.allowDragoverStyling()"
               [class.node-content-wrapper-active]="node.isActive"
               [class.node-content-wrapper-focused]="node.isFocused"
               [treeAllowDrop]="node.allowDrop"
               [treeDragEnabled]="node.allowDrag()"
               [treeDrag]="node"
               class="node-content-wrapper">

            <tree-node-content [index]="index" [node]="node"
                               [template]="templates.treeNodeTemplate"></tree-node-content>
          </div>
        </div>
      </ng-template>