New Experiment: Optimized Asset Loading Mode

Cover image

In the upcoming Elementor v3.1.0, we created a new “Improved Asset Loading” mode, which reduces the amount of JS code loaded on the page by default. When activated, parts of the infrastructure code will be loaded asynchronously, only when needed.

Which Functionalities Already Support the New Improved Asset Loading Mode?

1. Widget JS Handlers

Up to Elementor v3.1.0, all widget handlers were loaded to every page by default, regardless of whether they are actually used on the page.

Starting in Elementor v3.1.0, when the “Improved Asset Loading” mode is active, each widget will dynamically load its handler, only when being used on the page.

How Does It Affect Usage of Widget Handlers?

Up to Elementor v3.1.0, when you wanted to extend a certain widget’s JS functionality, you were able to get the widget’s handler by calling the following method:

elementorFrontend.elementsHandler.getHandlers( 'accordion.default' );

It was also possible to get the JS handlers for all JS-enhanced widgets at once, as one object, by not passing any value to the function.


Starting Elementor v3.1.0, The method name was changed to getHandler(), and when the “Improved Asset Loading” mode is active, calling the method will return a “Promise” (instead of the handler itself); once the “Promise” is fulfilled, the widget handler will be available as the function argument:

elementorFrontend.elementsHandler.getHandler( 'accordion.default' )
	.then( ( handler ) => {
		console.log( 'The Requested Handler: ', handler )
	} );

* IMPORTANT NOTE: The old method name and its behavior are now deprecated. Within the next few releases, the old method will be removed entirely, and there will be no option to get all handlers at once as one object. Therefore, you will have to use the new method when calling a widget’s JS handler.

2. Swiper JS Library

Starting in Elementor v3.1.0, when the “Improved Asset Loading” mode is active, the Swiper JS library will only be loaded when the page includes at least one element utilizing the Swiper library.

For example: Section/Column Background Slideshow, or one of the Carousel Widgets (Image Carousel, Testimonial Carousel, etc.).

Starting v3.1.0, we’ve changed the implementation of creating a new swiper instance by changing the ‘swiper’ utility (available in the global scope at elementorFrontend.utils.swiper). Initializing Swiper this way now returns a Promise instead of the ‘Swiper’ global variable provided by the library.

Therefore, starting in v3.1.0, in order to support the new dynamic assets loading feature, the creation of new Swiper instances has to be done using the elementorFrontend.utils.swiper utility, when it returns the Promise.

For Example:

const asyncSwiper = elementorFrontend.utils.swiper;
new asyncSwiper( swiperElement, swiperConfig ).then( ( newSwiperInstance ) => {
  console.log( 'New Swiper instance is ready: ', newSwiperInstance );
  mySwiper = newSwiperInstance;
} );

Backward Compatibility For External Plugins Developers

In case that your plugin is dependent on the Swiper JS library, you will now have to make sure that the library is available before using it since it will not be loaded by default.

It also needs to be considered that there might still be users who hadn’t made the upgrade to v3.1.0 yet, in which the Swiper utility does not return a Promise. Therefore we need to consider both scenarios:

  1. The user uses an older version prior to v3.1.0, and the elementorFrontend.utils.swiper utility does not return a Promise.
  2. The user uses v3.1.0 and up, in which the elementorFrontend.utils.swiper utility returns a Promise.

Once the Swiper library is available, a global variable called ‘Swiper’ will exist in the window scope. It is necessary to check if this variable exists; if it does, use it.

If the Swiper global object does not exist, we’ll use a Promise, which will create the new Swiper instance automatically once it’s fulfilled.

Code snippet for creating a new swiper instance in a widget handler that supports v3.1.0 and up with backward compatibility:

if ( 'undefined' === typeof Swiper ) {
  const asyncSwiper = elementorFrontend.utils.swiper;
  new asyncSwiper( swiperElement, swiperConfig ).then( ( newSwiperInstance ) => {
    console.log( 'New Swiper instance is ready: ', newSwiperInstance );
    mySwiper = newSwiperInstance;
  } );
} else {
  console.log( 'Swiper global variable is ready, create a new instance: ', Swiper );
  mySwiper = new Swiper( swiperElement, swiperConfig );

Page Assets Reduction

v3.1.0 Optimized Mode Disabledv3.1.0 Optimized Mode Enabled
Assets File Size Reduced by up to 6KBAssets File Size Reduced by up to 177KB 

Starting Elementor v3.1.0, the “Improved Asset Loading” mode will be available, although it will not be active by default. Still, a minor improvement will occur even when this new setting is disabled, and the page assets size will be slightly reduced (up to 6KB). Once the “Improved Asset Loading” mode is enabled, the total size of Javascript assets loaded on each Elementor page can be reduced by up to 177KB compared to the same assets being loaded on a version prior to 3.1.0.

Why did we make this change?

  • Elementor views performance improvements as one of our top priorities, and we continuously work hard on ways to make Elementor sites faster and more performant.
  • We are now providing our users with the option to load less code by default, which translates to significantly faster page-load times.
  • This change, in addition to providing a performance improvement in itself, also includes infrastructure to be used towards more code reduction in the future.

This is another substantial step in our roadmap of performance improvements. Many more improvements are currently under development and will be gradually released.

How to Enable The Improved Asset Loading JS Mode

In the admin panel, go to Elementor → Tools → Experiments → Improved Asset Loading.


Rotem Ben Itzhak
Rotem Ben Itzhak
Rotem is a developer in Elementor's Editor team, passionate about exploring new technologies, creating music, and turning coffee into code.

20 Responses

  1. Hi Rotem,

    this is amazing! I wanted this so long! THANK YOU very much!

    Looking forward to disable — if not used –– /share-link.min.js in the near future… 😉

    Greetings from Germany

  2. I just started getting an error on Edge in frontend.min.js around the first. Not sure if this is related, swiper doesn’t load. Works fine in Chrome / other browsers.
    frontend.min.js (2,61647)


  3. When this option enabled, some js linked to 3rd party widgets from my plugins doesn’t work on certain pages (Crocoblock plugins, Powerpack Elements).

  4. Youve lost “T” letter at the last string. Please make the correction in the article

    “In the admin panel, go to Elementor → Tools → Experiments → Improved Asse Loading.”
    should be
    “In the admin panel, go to Elementor → Tools → Experiments → Improved Asset Loading.”

    Also in my WP (Elementor Pro 3.1.0) I have this option in
    Elementor → Settings → Experiments → Improved Asset Loading

  5. Does not work properly when having WP Rocket activated and the WooThumbs gallery installed. The additional images from the gallery won’t be loaded. Hoped it would work as this would really improve loading time and remove clutter, but for now this will be not an option for me.

  6. My site breaks when this is enabled and Autoptimize’s “Aggregate JS” is enabled. When I disable “Aggregate JS” in Autoptimize, Elementor’s “Improved Asset Loading” starts working well.

    Do you think we can have a way where we can enable both “Improved Asset Loading” and “Aggregate JS” with Autoptimize?

  7. This feature cut the js load from elementor on my page in half.

    Amazing improvement!


    It would be even more amazing if this would unload unused css aswell.

    When it is active and i inspect my page i can see at least 70% of the css loaded by elementor is coming from widgets i am not using and even have deactivated using a widgetmanager.

    However the css is still loaded on every page on my site.

    Please make this the next step to improvement!

    Kind regards

  8. Could you please upload an example of a case where there are multiple instance at one page?
    For some reason it does not work as expected.

  9. Hello,

    It seems that the improved loading gives some problems with the Menu Cart Widget (Pro). In a first load the menu does not work well and the window with the cart information does not display, you have to reload the page so that the click can do its function again.


  10. var options = {
    // my swiper options
    const asyncSwiper = elementorFrontend.utils.swiper;
    new asyncSwiper(‘.tpslider’, options).then((newSwiperInstance) => {
    var swiper = newSwiperInstance;

    console.log(swiper); // returns undefined

    How can I access the swiper variable from outside of the promise?

  11. I’m having a similar issue as Sajib. The swiper instance created via the asyncSwiper class is not accessible outside of the asyncSwiper promise function. Trying to get two swiper sliders connected with the thumbs parameter and it’s not working due to this issue.

  12. If I upgrade the Swiper library but Improved Asset Loading is inactive, the swiper slider does not work. what is the solution for this?

Leave a Reply

Your email address will not be published. Required fields are marked *