独自の VirtualFlow を実装しようとしていますが、パフォーマンスの問題がいくつかあり、ボトルネックがどこにあり、それを改善するために何ができるかわかりません。
これは 2 つのリストのショーケースです。1 つは単純なセルで、もう 1 つはチェックボックスもあり、両方とも 100_000 個のアイテムがあります (GIF 品質で申し訳ありません)。
ご覧のとおり、ラベルだけの単純なセルをスクロールするのに問題はありませんが、チェックボックスを含むリストは最初はかなり遅くなる可能性があります.
そのようなパフォーマンスに到達するために(そうでなければはるかに悪いでしょう)、必要に応じてすべてのセルがメモリ内で準備できるように、セルファクトリ関数をメモ化します。さらに高速/スムーズにするために他に何かあるのではないかと考えていました。
セルを表示するために使用するコードは次のとおりです。
long start = System.currentTimeMillis();
builtNodes.clear();
for (int i = from; i <= to; i++) {
C cell = cellForIndex.apply(i);
Node node = cell.getNode();
builtNodes.add(node);
}
manager.virtualFlow.container.getChildren().setAll(builtNodes);
long elapsed = System.currentTimeMillis() - start;
System.out.println("Show elapsed: " + elapsed);
この小さなログも追加しました。重い部分は呼び出したときのようですgetChildren().setAll(...)
。セルの構築とレイアウトの両方がほぼ即時です。
from
およびto
パラメータに関するもう 1 つの注意事項です。スクロールするときは、スクロールバーの値を取得し、次のように最初と最後の表示インデックスを計算します。
public int firstVisible() {
return (int) Math.floor(scrolled / cellHeight);
}
public int lastVisible() {
return (int) Math.ceil((scrolled + virtualFlow.getHeight()) / cellHeight - 1);
}
いくつかの質問に答えるために編集します。
独自の VirtualFlow を実装する理由
最終的な目標は、独自の ListView 実装を作成することです。そのためには、VirtualFlow も必要です。また、それはかなり低レベルで難しい作業であることもわかっていますが、プログラミングについて詳しく学ぶには良い方法だと思います。一般およびJavaFXについても
なぜメモ化?
セル ファクトリの結果をメモリにキャッシュすることで、ノードが既に構築されているため、その後のスクロールが大幅に高速化されます。ノードを配置するだけで済みます。これは非常に簡単です。何らかの理由でVirtualFlowがより複雑なセルに遅れをとっているため、問題は最初にあり、人気のあるライブラリであるFlowlessもメモ化を使用してノードをメモリにキャッシュするため、理由を理解できませんが、最初からすでに非常に流暢です. JavaFX の VirtualFlow (JFX16 から改訂) もメモ化なしで非常に効率的ですが、理解するのははるかに複雑です。