diff --git a/core/.eslintrc.json b/core/.eslintrc.json
index 8a871ac96934f179f2a0e2e42695f1ba6cd7ed09..476aa59cf100a23e73ecf1cc3cf745ac20b8e28d 100644
--- a/core/.eslintrc.json
+++ b/core/.eslintrc.json
@@ -19,6 +19,7 @@
     "Cookies": true,
     "Backbone": true,
     "Modernizr": true,
+    "loadjs": true,
     "Popper": true,
     "Shepherd": true,
     "Sortable": true,
diff --git a/core/assets/vendor/loadjs/loadjs.min.js b/core/assets/vendor/loadjs/loadjs.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..b2165fc367847e82bd417fed6270a8f30470bdcd
--- /dev/null
+++ b/core/assets/vendor/loadjs/loadjs.min.js
@@ -0,0 +1 @@
+loadjs=function(){var h=function(){},c={},u={},f={};function o(e,n){if(e){var r=f[e];if(u[e]=n,r)for(;r.length;)r[0](e,n),r.splice(0,1)}}function l(e,n){e.call&&(e={success:e}),n.length?(e.error||h)(n):(e.success||h)(e)}function d(r,t,s,i){var c,o,e=document,n=s.async,u=(s.numRetries||0)+1,f=s.before||h,l=r.replace(/[\?|#].*$/,""),a=r.replace(/^(css|img)!/,"");i=i||0,/(^css!|\.css$)/.test(l)?((o=e.createElement("link")).rel="stylesheet",o.href=a,(c="hideFocus"in o)&&o.relList&&(c=0,o.rel="preload",o.as="style")):/(^img!|\.(png|gif|jpg|svg|webp)$)/.test(l)?(o=e.createElement("img")).src=a:((o=e.createElement("script")).src=r,o.async=void 0===n||n),!(o.onload=o.onerror=o.onbeforeload=function(e){var n=e.type[0];if(c)try{o.sheet.cssText.length||(n="e")}catch(e){18!=e.code&&(n="e")}if("e"==n){if((i+=1)<u)return d(r,t,s,i)}else if("preload"==o.rel&&"style"==o.as)return o.rel="stylesheet";t(r,n,e.defaultPrevented)})!==f(r,o)&&e.head.appendChild(o)}function r(e,n,r){var t,s;if(n&&n.trim&&(t=n),s=(t?r:n)||{},t){if(t in c)throw"LoadJS";c[t]=!0}function i(n,r){!function(e,t,n){var r,s,i=(e=e.push?e:[e]).length,c=i,o=[];for(r=function(e,n,r){if("e"==n&&o.push(e),"b"==n){if(!r)return;o.push(e)}--i||t(o)},s=0;s<c;s++)d(e[s],r,n)}(e,function(e){l(s,e),n&&l({success:n,error:r},e),o(t,e)},s)}if(s.returnPromise)return new Promise(i);i()}return r.ready=function(e,n){return function(e,r){e=e.push?e:[e];var n,t,s,i=[],c=e.length,o=c;for(n=function(e,n){n.length&&i.push(e),--o||r(i)};c--;)t=e[c],(s=u[t])?n(t,s):(f[t]=f[t]||[]).push(n)}(e,function(e){l(n,e)}),r},r.done=function(e){o(e,[])},r.reset=function(){c={},u={},f={}},r.isDefined=function(e){return e in c},r}();
\ No newline at end of file
diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index ee69d9c619156678f50e2557da36e07e47fdd659..6b0031d0aad4e014da225a71f4c3da0c896f1c1e 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -95,6 +95,16 @@ drupal.announce:
     - core/drupal
     - core/drupal.debounce
 
+loadjs:
+  remote: https://github.com/muicss/loadjs
+  version: "4.2.0"
+  license:
+    name: MIT
+    url: https://raw.githubusercontent.com/muicss/loadjs/4.2.0/LICENSE.txt
+    gpl-compatible: true
+  js:
+    assets/vendor/loadjs/loadjs.min.js: { minified: true }
+
 drupal.autocomplete:
   version: VERSION
   js:
diff --git a/core/misc/cspell/dictionary.txt b/core/misc/cspell/dictionary.txt
index 1ef535ce39358cc4be435095172b706248c94fb6..3edb5849646e1bf2202f8d964e14f704d7e9f3b7 100644
--- a/core/misc/cspell/dictionary.txt
+++ b/core/misc/cspell/dictionary.txt
@@ -840,6 +840,7 @@ llamasarelame
 llame
 llamma
 lnumber
+loadjs
 localemark
 localetranslatedirty
 localizable
diff --git a/core/package.json b/core/package.json
index 55dfe7044e282e6f9ddbf45b2e6281b859fa6a91..3b1e4d863f984635521d79ebd52af97a4c48ae7a 100644
--- a/core/package.json
+++ b/core/package.json
@@ -63,6 +63,7 @@
     "jquery-form": "^4.3.0",
     "jquery-once": "^2.2.3",
     "js-cookie": "3.0.0-rc.0",
+    "loadjs": "^4.2.0",
     "minimist": "^1.2.2",
     "mkdirp": "^1.0.4",
     "nightwatch": "^1.6.3",
diff --git a/core/scripts/js/assets.js b/core/scripts/js/assets.js
index a9c405b6518f2118d791c6663c425e7213cb50ee..5e7186775fafb4eb94f965d3f943514390d5d7ca 100644
--- a/core/scripts/js/assets.js
+++ b/core/scripts/js/assets.js
@@ -167,6 +167,10 @@ const assetsFolder = `${coreFolder}/assets/vendor`;
       pack: 'underscore',
       files: ['underscore-min.js', 'underscore-min.js.map'],
     },
+    {
+      pack: 'loadjs',
+      files: [{ from: 'dist/loadjs.min.js', to: 'loadjs.min.js' }],
+    },
   ].map(async ({ pack, files = [], folder = false, library = false }) => {
     const sourceFolder = pack;
     const libraryName = library || folder || pack;
diff --git a/core/yarn.lock b/core/yarn.lock
index cef6ce3705e7b8d620b254e297f168817e499f8c..8503d5892f4468705b2232bb5c520cb32342fdcd 100644
--- a/core/yarn.lock
+++ b/core/yarn.lock
@@ -3610,6 +3610,11 @@ load-json-file@^4.0.0:
     pify "^3.0.0"
     strip-bom "^3.0.0"
 
+loadjs@^4.2.0:
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/loadjs/-/loadjs-4.2.0.tgz#2a0336376397a6a43edf98c9ec3229ddd5abb6f6"
+  integrity sha512-AgQGZisAlTPbTEzrHPb6q+NYBMD+DP9uvGSIjSUM5uG+0jG15cb8axWpxuOIqrmQjn6scaaH8JwloiP27b2KXA==
+
 locate-path@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"