1. Лишние манипуляции над домом.
appendChild нужно делать только после того, как элемент и все его дети будут настроены. Т.е. если в функции
showMessage сначала настроить
messageWrapper (задать класс; добавить в него
message) и только потом сделать
document.body.appendChild, то можно выиграть в производительности за счет меньшего количества обращений к DOM-дереву.
Эти строки вызывают вопрос, т.к. не очень понятно, зачем нужно добавлять элементу класс и через 100 миллисекунд его убирать. Выглядит, как что-то ненужное
messageWrapper.classList.add("messageWrapperUnvis");
setTimeout(() => {
messageWrapper.classList.remove("messageWrapperUnvis");
}, 100);
2. Ивент листенеры нужно удалять за собой.
Нужно убирать отратобавшие event listeners, т.к. их накопление приводит к утечке памяти.
Также желательно пересмотреть подход к определению слушателей вообще, т.к. в функции
modalWindow на каждое событие
contextmenu устанавливается другое событие
contextmenu, назначение которого только лишь в том, чтобы удалить предыдущий
currentDiv. Имеет смысл вынести
currentDiv в функцию
modalWindow, а внутри слушателя делать необходимую проверку.
3. Нерациональный ранний выход из функции.
В функции
modalWindow нет смысла создавать элементы, кроме
wrapper, т.к. при срабатывании условия
e.target.matches("#input") произойдет
return и ранее созданные элементы просто окажутся бесполезными. Т.е. if нужно разместить непосредственно после
wrapper.
4. Бесполезные элементы.
Функцию
addNewItem я бы вообще переделал, т.к. внутри нее на
каждый keypress производится куча действий над элементами, которые в итоге так и не попадут на страницу:
nListItem и
remove будут добавлены только при
e.key === "Enter" && input.value !== "" (кстати, нет смысла плодить вложенные if'ы, когда можно использовать булевы выражения).
В общем, уделяй внимание каждой отдельной сущности, которую ты создаешь; помни о ее назначении и о том, как она будет взаимодействовать с другими сущностями на странице. Это поможет избежать ненужных операций и в конечном итоге сделает код чище.
Когда код небольшой части приложения становится осмысленным для создающего, появляется мотивация упорядочивать его в глобальных масштабах, т.е. решать архитектурные вопросы, что в совокупности с шишками, которые принесет этот процесс, в конечном итоге, сделает тебя более скилованным разработчиком.