Вызывать decorateCookedElement при каждой смене страницы?

Ваш код должен работать нормально. Вы просто наткнулись на ошибку в Discourse.

loadScript() не устанавливает атрибут async для загружаемых скриптов. Поэтому по умолчанию он принимает значение async="true", что нарушает порядок загрузки. Это особенность браузера. Для скриптов, загружаемых через JS, нужно явно указывать async="false".

Плагины меньше по размеру, поэтому загружаются быстрее основного пакета, но из-за атрибута async они больше не соблюдают порядок загрузки — то есть не ждут загрузки и выполнения основного пакета перед своим выполнением.

Скорее всего, это осталось незамеченным, потому что loadScript, насколько мне известно, нигде не вложен в ядро. Обычно файлы, которые должны работать вместе, объединяют в один пакет. Так что, отвечая на ваш другой вопрос: нет, в Discourse нет функций, которые решают такую задачу.

Ваш другой фрагмент тоже должен работать. Чтобы сделать его чуть более читаемым, попробуйте использовать цепочку вызовов без вложенности.

// Это размещается вне декоратора
const PLUGINS = {
  speed: "https://example.com/foo.js",
  skipBack: "https://example.com/bar.js",
  jumpForward: "https://example.com/baz.js"
};

// Затем выполняйте свою работу внутри декоратора
loadScript(MEDIA_ELEMENT_SRC)
  .then(() => loadScript(PLUGINS.speed))
  .then(() => loadScript(PLUGINS.skipBack))
  .then(() => loadScript(PLUGINS.jumpForward))
  .then(() => {
    audioplayers.forEach(function (el) {
      new MediaElementPlayer(el, MEDIA_ELEMENT_CONFIG);
    });
  });