如何在没有滞后的情况下改变大量元素的位置

时间:2017-07-06 21:57:32

标签: html css angular css-position angular-material

我正在创建一个Angular组件,它可以作为编辑视频文件的时间轴。 (像这样):

timeline

我在确定时间线上所有测量条的位置时遇到了一些问题,而且我正试图找出一种更好的方法来定位它们。目前,我正在使用转换函数(pxToFrame和frameToPx)将帧值转换为像素值,以便知道每个度量条的位置。当我们非常放大(意味着大部分时间轴都在屏幕外,并且我们滚动到我们的放大部分)时,必须对每个像素条执行此操作,这意味着对视频中的每个帧执行操作文件(很多!)当我放大到足以渲染许多测量线时,这会导致组件表现得非常缓慢。这会变成如此昂贵的reFlow,它会使浏览器挂起几秒钟。

我想知道通过渲染数千个元素的位置样式来防止这种滞后的最佳方法是什么?

我尝试过实现angular2-virtual-scroll,试图只渲染视图中的元素而不是所有元素,但是组件还没有水平滚动的实现。

有关更好策略的任何想法,或者在渲染此组件时减少reFlow数量的方法?我们在这里使用10个1000个测量条元素(对于视频文件中的每个帧),因此需要大幅减少。

谢谢!

供参考, 这是我的HTML:

<div
    // this.measureLineArray holds an array of numbers that represent the frames at which there should be a line
    *ngFor="let frame of this.measureLineArray"

    class="measure-line-container" 

    // This ngStyle binding is how I have been changing the position property, but it's deathly slow when we are dealing with many measure lines
    [ngStyle]="getMeasureLinePxFromFrame(frame)"
>
    // This is the class for labeled lines
    <div 
        class="measure-line-label"
        *ngIf="frame % this.labelInterval === 0"
    >
        <div class="text">{{frame.toString()}}</div>

        <div class="bar"></div>

   </div>

   // This is the class for unlabeled lines
   <div 
        class="measure-line"
        *ngIf="!(frame % this.labelInterval === 0)"
   >
        <div class="bar"></div>

   </div>

</div>

以下是产生延迟的有问题的功能

// Here is the function that returns the position styling for each measure line

private getMeasureLinePxFromFrame(frame : Frame) : any
{
  let measureLineStyle = {
    'left': this.frameToPx(frame) + 'px'
  }
  return measureLineStyle;
}


// This is the conversion function, utilizing the width of the container element to determine of each measure-line

private frameToPx(frame : number) : number
{
  let currentProgress : number = frame / this.numFrames;

  return Math.floor(this.Timeline.clientWidth * currentProgress);
}

这是相关的CSS:

.measure-line-container {
    display: inline-flex;
    position: absolute;
    height: 100%;
    flex-direction: column;
    justify-content: flex-end;
}

.measure-line {
    position: relative;
    bottom: 0px;

    .bar {
        width: 1px;
        height: 10px;
        background-color: black;
    }
}

.measure-line-label {
    position: relative;
    height: 50%;
    display: flex;
    flex-direction: column;
    justify-content: flex-end; 

    .bar {
        position: relative;
        bottom: 0px;
        left: 0px;
        width: 1px;
        height: 100%;
        background-color: black;
    }

    .text {
        position: absolute;
        top: 0px;
        margin-left: 3px;
        color: black;
        font-size: 8px;
        text-align: center;
        user-select: none;
    }
}

1 个答案:

答案 0 :(得分:1)

阅读以下主题: https://blog.thoughtram.io/angular/2017/02/21/using-zones-in-angular-for-better-performance.htmlhttps://blog.thoughtram.io/angular/2017/02/02/making-your-angular-app-fast.html

此外,如果你花一些时间阅读Angular中的变化检测,你将获得很多好处。有几个建议如何改善。一般来说,OnPush策略应该有所帮助。但无论如何,所有变通方法都与更新需要更新的确切元素有关。即您仍然必须确定只需要在确切时间在页面上呈现/显示的元素列表,这将导致您所谓的“虚拟滚动”。

您可以将所有幻灯片放在屏幕上,但同时只移动10-20张幻灯片。当幻灯片超出范围时 - &gt;将其从activeFrames数组中删除,然后从leftFramesrightFrames中选择下一个。