I connected to the site fancybox, the page began to load much longer as possible to put the loading styles and js fancybox after all the rest

    1 answer 1

    There are ready-made libraries for solving the problem of dynamic loading, but I will give an example of a very simple sequential loader on promises.

    The loader takes as argument a two-dimensional array of css and js resources connected to the page. Each element of the array is assumed to be a subarray of objects of the form {link: 'url'} or {script: 'url'} .
    Important point: it is expected only the termination of loading of resources (on a network), with any result. That is, this loader does not check if the file was successfully loaded, and certainly it does not wait for parsing styles / script execution.


    Place the loader code in the <head> document (the content of simple-loader.js is later in the response):

     <script src="js/simple-loader.js"></script> <script> jsCssLoader([ [ { link : 'css/main.css' }, { script: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js' } ], [{ script: 'js/main.js' }], [{ link: 'https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css' }], [{ script: 'https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js' }] ]); </script> 

    In this example, the css-file of the page will be loaded first with jQuery → then the js-script of the page will be loaded → then the css-file of the funkybox → and finally its js.


    But the contents of simple-loader.js , which does all the "magic":

      function jsCssLoader(resources2dArr) { const resources = resources2dArr.slice(0); document.addEventListener('DOMContentLoaded', function () { const resEvents = ['load', 'error']; const promisedEl = resObj => new Promise(resolve => { const newEl = tag => document.head.appendChild(document.createElement(tag)); const key = Object.keys(resObj)[0], el = newEl(key); resEvents.forEach(evt => el.addEventListener(evt, () => resolve(el))); if (resObj.link) { el.rel = 'stylesheet'; el.href = resObj[key]; } else el.src = resObj[key]; }); const next = res2dArr => { let arr = res2dArr.shift(); arr && arr.length && Promise.all(arr.map(res => promisedEl(res))).then(els => next(res2dArr)); }; next(resources); }, { once: true }); }