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.
elementorFrontend.elementsHandler.getHandlers();
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:
- The user uses an older version prior to v3.1.0, and the
elementorFrontend.utils.swiper
utility does not return a Promise. - 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 Disabled | v3.1.0 Optimized Mode Enabled |
Assets File Size Reduced by up to 6KB | Assets 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.
19 Responses
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
Marius
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)
Thanks
Amazing, finally elementor becomes a good solution for bigger businesses.
When this option enabled, some js linked to 3rd party widgets from my plugins doesn’t work on certain pages (Crocoblock plugins, Powerpack Elements).
it is in settings not tools…
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
Thanks Nick!
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.
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?
This feature cut the js load from elementor on my page in half.
Amazing improvement!
However.
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.
https://www.loom.com/share/054ee2fce4c0448d9c8fa85ac2a3a9e9
Please make this the next step to improvement!
Kind regards
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.
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.
Thanks.
Thanks a lot for making this feature available. Now my pages are loading with a blazing speed on the litespeed server.
The link for “handlers” under “1. Widget JS Handlers” is not working
Thanks
Thank you very much for your article
Please help me with it.
https://stackoverflow.com/questions/70791119/swiper-js-sync-slider-in-async-method
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?
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.