tor4kichi / TsubameViewer

漫画・小説ビューア(Windows10 & 11/XboxOne/Xbox Series X & S)
GNU General Public License v3.0
14 stars 1 forks source link

フォルダ内に1万件以上のアイテムがあってもスムーズに表示 #42

Closed tor4kichi closed 11 months ago

tor4kichi commented 2 years ago

難度の高さに対して利用ケースがレアだからあまり対応する気はない。

現状はフォルダ内アイテムを全件取得した上でソートを掛けている。特にファイル名の桁数補完のためにだけに全件取得が必要となっている。

そのため軽量化するための基本方針は、ソートの仕組みをファイルシステムに依存させることでフォルダ内アイテムの列挙をインクリメタルローディング可能にし、桁数補完が必要な場合のみ全件取得を求めるようにする。

インクリメタルローディングしているとしても、現状のままだとスクロールするにつれて表示件数が増えていくと画像分のメモリ使用によってメモリが逼迫する可能性があるので、ListViewBase.ContainerContentChanging等で表示対象から外れたItemVMの画像をクリアするような追加機能が必要となる。

ちなみに15,000件程度でメモリ使用量は1.2GBほど(タスクマネージャで確認)となっている。開くのに掛かる時間は30秒前後。うへぇ。

tor4kichi commented 11 months ago

v1.8.19 にて対応しました。

実装としては表示が必要になったアイテムのみをインデックスアクセスでファイル情報取得する形にして、ファイルシステム使用負荷をこれまでフォルダ内全体だったものを表示範囲内のみに限定することが出来ました。フォルダ内アイテムの数が多ければ多いほど今回の高速化の恩恵が大きくなりますし、HDDアクセスかつ500件程度でも待ち時間がほぼ無くなる、1万件もある場合には顕著な応答時間の改善が感じられるかと思います。

ただし、ページ到達時にフォルダ内のアイテム数を取得するためファイルシステムがアイテム数を求めるのに必要なだけの待ち時間が発生します。この待ち時間すらも削減したい場合は次のインクリメンタルローディング方式を選択する必要がありますが、今回は選びませんでした。

インクリメンタルローディング方式はページ終端が表示範囲になるタイミングで追加的にアイテムを読みにいくため、ページ到達時において待ち時間がより少なく済みます。しかし、フォルダ一覧ページと画像一覧ページをそこまで変わらない体験(全体の量がスクロールバーでわかる状態)で統一したかったので前述のインデックスアクセス方式を選択しました。

その他、更に高速化するにはアイテム数を読む前に(=ファイルシステムの応答を待つよりも前に)キャッシュから表示を開始してしまい、もしアイテム数が変わっていたら実態に合わせて更新する方法があります。ファイルシステムに頼っている並べ替えをキャッシュシステム上でも再現する必要があるため、実装には結構時間が掛かりそうです。

今回の高速化だけでほとんどの利用ケースにおける十分な高速化を果たしたとして、より突き詰めた高速表示の実装は(予定無しのレベルで)保留します。