Если надо следить за window, то resize вполне подходящий вариант, а чтобы слишком часто не выполнять сложные вычисления, отложить выполнение функции через setTimeout примерно так:
Очевидно: в зависимости от задачи. resize - realtime пропорциональная зависимость от размеров всего окна. matchMedia - единоразовые изменения по breakpoint'ам. ResizeObserver - слежение за конкретным элементом (который может и не менять размеров при изменении окна\media).
В вопросе написано какой ЛУЧШИЙ способ!
Вы написали методы которые я и так перечислил.
Можно интервалами в секунду проверять matchMedia,
а можно window.addEventListener('resize', function(event) {
// повесить слушателя и пусть висит всегда
}),
а может выгодно ResizeObserver повесить на body?
Лучше addEventListener('resize') общий или в 15, например, местах на блоках отдельные ResizeObserver?
Виталий Першин выше написал хороший ответ, но вдруг у кого то есть еще мысли.
Андрей Чирков, для каждой ситуации "лучший" - свой, что тут непонятного?
Я даже написал в каких случаях надо что использовать.
Что выиграет - один глобальный resize и ручная обработка или множество ResizeObserver? Надо тестировать конкретный случай. Но, в случае множества меняющихся элементов, я бы всё равно использовал множество ResizeObserver, потому что это проще и удобнее поддерживать, и только если бы это стало узким местом смотрел бы иные варианты.
А проверять интервалами matchMedia точно не нужно, ты делаешь это неправильно. На matchMedia можно повесить слушателя onchange(раньше addListener) и он будет срабатывать только на изменение.