Skip to content

Applying renderOnlyVisible option on ngx flicking

Jongmoon Yoon edited this page Sep 10, 2019 · 2 revisions

renderOnlyVibible is an option on the Flicking component that can improve performance by rendering only the visible panels. If your data covers hundreds or thousands of pages, you'll see significant performance gains.

However, Angular differs from some framework policies in React and Vue. This makes the interface slightly different. There are some things that must be handled by the component user. This document describes the elements to be aware of in order to use renderOnlyVisible.

Note: For Vue and React, when passing panel information in Flicking, you can filter and show only the panels that will be rendered. This is because these frameworks give you control over what is actually rendered through the render life cycle.

In Angular, on the other hand, you cannot modify the panel information you pass. Although it can be shown or not shown, it is not possible to manipulate existing content. For this reason, Angular has a slightly different interface than Vue and React.

We hope that the following information will help you develop your Angular framework.

[panel] should have all panel information.

If renderOnlyVisible: false, you do not need to pass the [panels] property. However, if renderOnlyVisible: true, you must specify an array that contains information for all panels, not just the panel information shown in the panels property.

For example, suppose you pass the panel information list0 to a component:

<ngx-flicking [panels]="list0">
</ngx-flicking>

At this time, there are precautions.

If the panels have changed, they must have a different reference from the existing panels. Angular developers are usually well aware, but there's room for mistakes.

For example, if you want to update the panel information by adding a new item to list0, If you perform an operation that does not change the Reference in list0 as follows, it will have no effect.

this.list0.push(end + 1)

This is because Angular checks for changes based on a reference change. Therefore, you must perform an operation that changes the referece of list0.

this.list0.push(end + 1);
this.list0 = this.list0.slice();

You should handle onRenderPanelChange

As mentioned at the beginning, Angular displays user-specified panel information without manipulation. Therefore, you need to filter the panel you want to show. Therefore, the user must implement an onRenderPanelChange handler to filter only the panels to render in the viewport.

visibles in Event Object

In the event object of onRenderPanelChange, visibles contains an array of currently visible panel information. The user refers to visible panel information by referring to visibles.

For example, suppose the panel information is as follows and only the second and third panels are shown.

const panels = ["abc", "def", "ghi", "jkl"]; 

In this case, the event of onRenderPanelChange (event) is passed as follows.

event = {
  visibles: [
    {index: 1, key: 1, data: "def"}, 
    {index: 2, key:2, data: "ghi"}
  ]
}

main properties of visibles

Let's take a look at the key attributes passed above. visibles is an array of objects with the following properties:

  • index
  • key
  • data

index

  • (logically) identify the same panel.
  • It is equal to the index of each panel passed by the user.

key

  • (Physically) identify the same panel.
  • In non circular mode, index and key have the same value.
  • In the circular mode, however, the index and key can have different values. For example, if multiple panels with the same index are shown in one flicking area, this is used to distinguish each panel.

For example, suppose you have a panel with an index of [0, 1, 2, 3] and each clone is created.

The index of each of the original and clone panels is the same as 0, 1, 2, 3, but each key differs from [0, 1, 2, 3] and [4, 5, 6, 7]. That is, the key value of the original panel is the same as index, but the key value of clone is determined by (number of original panels + the number of previous clones) * index.

By using this key, you can use NgForOf's trackBy to separate the same panels by key. You can achieve higher performance by avoiding unnecessary rendering.

<ngx-flicking class="flicking flicking0" [options]="{ gap: 10, renderOnlyVisible: true, circular: true, moveType: 'snap'}" [panels]="list0" (renderPanelChange)="onRenderPanelChange($event)">
    <ng-template>
      <div *ngFor="let panel of visiblePanels;trackBy=trackByFn">
          {{ panel.data }}
      </div>
    </ng-template>
  </ngx-flicking>
  trackByFn(index, item) {
    return item.key;
  }

However, it cannot be used if the existing key value is changed. For example, it cannot be used when the index and key of an existing panel can be changed through prepend. If you only use append, you can use it because it doesn't change the existing key.

data

Contains panel data that matches index in the user panel list.

For example, suppose you have the following panel information and only the second and third panels are shown.

const panels = ["abc", "def", "ghi", "jkl"]; 

The visibles property of the event item of onRenderPanelChange (event) is as follows:

event = {
  visibles: [
    {index: 1, key: 1, data: "def"}, 
    {index: 2, key: 2, data: "ghi"}
  ]
}

In this case, the data for each element in the visibles array is the second and third data that you specify, respectively.

Example

Based on this, you can configure it as follows:

HTML Template

<ngx-flicking class="flicking" [options]="{ renderOnlyVisible: true}" [panels]="list0" (renderPanelChange)="onRenderPanelChange($event)">
    <ng-template>
      <div *ngFor="let panel of visiblePanels;trackBy=trackByFn">
          {{ panel.data }}
      </div>
    </ng-template>
  </ngx-flicking>

Source Code(TS)

export class SampeComponent implements OnInit {
  list0 = [0, 1, 2, 3, 4];

  onAppend() {
    const end = this.list0[this.list0.length - 1] || 0;
    this.list0.push(end + 1);
    this.list0 = this.list0.slice();
  }

  onRenderPanelChange(event: RenderPanelChangeEvent) {
    this.visiblePanels = event.visibles;
  }

  // TrackBy can be used if the existing panel does not modify index
  trackByFn(index, item) {
    console.log("index:", index, "item key", item.key);
    return item.key;
  }
}