Как минимум закэшировать
var variants = this.parentNode.nextElementSibling;
var allVariants = variants.querySelectorAll('div.label-point');
Затем убрать .toLowerCase() (возможно где-то закэшировать соответствие приведенного названия и элемента DOM дерева)
Согласно
https://proglib.io/p/javascript-performance-mistakes простой for быстрее forEach почти в 8 раз. Еще из серии экономии на спичках замена > на !==
Можно воспользоваться библиотеками для дебоунса (например
https://lodash.com/docs/4.17.11#debounce ), чтобы не вызывать обработку на каждое нажатие, а, например, не чаще, чем раз в секунду.
Ну и почитать про профайлер в инструментах разработки, чтобы узнать, какие строки больше всего времени едят. С этого надо начинать.
Еще подумалось, что можно сравнивать предыдущее и новое значение инпута, и если новое более строгое (Абыр -> Абырв), то искать не по всем, а только по найденным на предыдущем этапе. + нужно проверить, будет ли эффект, если не менять видимость, если она не должна меняться. Возможно такое, что пересчет стилей все равно происходит, даже если мы присваиваем стилям то же значение, что и в них хранится.
А вообще отображение без пагинации тысяч элементов как-то странно. Так что прямая дорога дальше в реактивные фреймворки, потому что там это все намного прямее, чем прямая работа с DOM. Мне больше нравится vue.