better_deferred

2.0.2 • Public • Published

better_deferred

This is a depedency-free lightweight library that completely defers the download and evaluation of external Javascript post document.ready (plus a small delay) resulting in improved performance compared to using native defer or async. Native async / defer don't prevent the browser from downloading and evaluating external scripts prior to firing off document.ready which degrades performance and lighthouse scores.

The small delay is set to 5000 ms by default but it's customizable. This delay will allow you to get reduce time-to-interactive delays and will bring you closer to getting a high Lighthouse Performance score.

Please note that not all scripts are a good candidate to defer. For example, jQuery and Bootstrap are common libraries expected to be loaded as soon as possible in a page request.

Examples

The following scripts is executed after (document.ready + 5 seconds):

<script type="better_deferred" onload="console.log('loaded inline script');">
   alert('loaded');
</script>
<script type="better_deferred" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" onload="console.log('loaded external script');></script>

External scripts are loaded first (in the order they appear), then inline scripts follow (in the order they appear).

Triggering early load of better_deferred scripts

Any html element with the class better_deferred_trigger will be given a listener for mouse over, touch move, and focus; which will trigger the early load of better_deferred scripts once.

Additionally, to early trigger manually you can call window[window['_bd_name']].start().

Loaded scripts

When scripts are loaded, they are given the type loaded_better_deferred and the bottom of the document will include a reciprocating script of type text/javascript.

Support for lozad

A case I wanted to support is to load external scripts earlier if they become relevant to the user by detecting whether lozad has loaded related elements in the page.

For example, if an element to declare Calendly isn't visible yet, then I'd like to lazy load the Calendly script except if the element becomes visible and the user is likely to interact with it. So this library sets Mutation observers for better_deferred scripts when the parent has the lozad class. Upon lozad making the element visible, this library detects changes to data-loaded and will immediate start loading all deferred scripts.

Mime Types

This library support addition of custom MIME types when the script is loaded. This defaults to type="application/javascript" this can be overridden by setting data-mime-type value. For example for ESM, the type="module" needs to be set, since this is deferred, this can be set as data-mime-type="module or any of the JS IANA types.

<script type="better_deferred" data-mime-type="module">
   import * as d3 from 'https://esm.run/d3';
   console.log('esm module', d3);
</script>

Customization

By default inline scripts and external scripts will be

window['_bd_timeout'] = 5000;

To prevent name collision, this library is instantiated in window[window['_bd_name']]. This means that you can use the following pattern to set where this object is stored.

window['_bd_name'] = '_new_name_to_prevent_collisions'

Development

npm run watch

Build

npm run build

Publish

npm publish

Creating Repo

Inspiration from:

Run tests locally

Be sure to install all dependencies, then run tests:

npx playwright install --with-deps
npm run test

CI

Currently this repo uses Github actions but you can run the tests locally using a Docker container:

docker run --rm -it $(docker build -q .)

Package Sidebar

Install

npm i better_deferred

Weekly Downloads

2

Version

2.0.2

License

https://github.com/MrMurga/better_deferred/blob/main/LICENSE

Unpacked Size

15.8 kB

Total Files

5

Last publish

Collaborators

  • armando8