У меня действительно плохой опыт, когда я потратил много часов на производительность по сравнению с использованием собственной виртуализации списков, используемой в стандартном ListBox. Я бы посоветовал не использовать пользовательские списки и вместо этого использовать ObservableCollection. Я думаю, что ListBox, вероятно, в основном тестировался с ObservableCollection, и любые уловки, которые вы пытаетесь сделать, чтобы избежать заполнения всего списка, могут иметь неприятные последствия, так как ListBox не настолько гибок, как можно было бы ожидать, исходя из того факта, что ItemsSource является просто IEnumerable. На самом деле, исходя из этого ожидания - вы можете предположить, что ему нужно перечислить все элементы от 0 до 200, если вы хотите отобразить элемент 200.
Если у вас есть несколько сотен элементов в списке - вы можете упростить модель данных для их отображения, чтобы заполнить коллекцию ObservableCollection всеми элементами с начала и загружать данные элементов только тогда, когда содержимое элементов запрашиваются и еще не доступны. Если это слишком много - вы можете добавить небольшую задержку перед загрузкой данных и проверить, отображается ли представление элемента коллекции на экране после этой задержки, прежде чем начинать загрузку.
Другая вещь, которая предположительно полезна, - это если ваш ItemTemplate имеет предопределенные размеры.