Elementor 3.9 Developers Update

Elementor 3.9 and Elementor Pro 3.9 include several very interesting updates. This post covers performance-related improvements and developer-related changes. Although the topics are mainly technical, this post simplifies the content to allow regular users to understand the basic ideas behind the changes.

Smaller CSS Assets

When you upgrade to 3.9 the amount of unused CSS will drop, improving the overall page speed.

Automating CSS Generation

Elementor uses a SASS pre-processor to style elements and a Grunt task runner to automate the process of converting SCSS code into standard CSS files. We also use Grunt tasks to generate LTR and RTL files, adding browser vendor-prefixes (-webkit-, -moz-, -ms- and -o-), minifying the CSS files and more.

Optimizing CSS Assets

With extra tweaks added in Elementor 3.9 we managed to reduce the total size of all the CSS assets even further. For example, in the free version of Elementor, the CSS assets size was reduced by ~13%, from 5.3MB to 4.6MB. In the Pro version of Elementor, the CSS assets size was reduced by ~10%, from 7.3MB to 6.6MB.

Please note that this will not necessarily reduce the CSS files on your websites by 10%-13% as it depends on what elements you are using on your page and whether those elements were affected by the current change. Saying that, each reduction in asset size should decrease the amount of unused CSS and improve the overall page speed.

Lazy Load for Background Images

Elementor 3.9 introduces a new experiment that helps boost performance by improving the LCP score by using lazy loading background images.

Loading Background Images

One of Elementor’s biggest performance improvement requests was to add lazy loading of background images. The lack of lazy loading led to lower LCP score and had a negative affect on your page performance.

Many of our users suggested adding the option to select the background image file size instead of the full image size used by default. Others suggested utilizing the HTML srcset attribute. The problem is that the first solution would require you to update all your Elementor pages and the second applies only on <img> tags, not on background images.

Lazy Loading Images in Elementor

Elementor 3.9 introduced a new approach that can be activated in the Experiment tab. When background images are set on widgets, sections, columns or containers on images that appear below the fold, Elementor will use the smallest available image size – the thumbnail size – together with a high blur. It will ensure that on initial load, the images that are instantly available load fully, and those below the fold use the smallest available size possible, which  improves the LCP score.

Then, when the user scrolls down, the original background image will be loaded, replacing the thumbnail. It’s a custom lazy load solution, which can be tracked on the Network Tab of the browser’s Dev Tools. Simply scroll down and see how the background images are loaded just before they enter the viewport. You can also compare the page size and its lighthouse score before and after activating the new “Lazy Load Background Images” experiment.

With this approach we managed to reduce the biggest performance issue entirely. Improving the initial load time, increasing the performance and the lighthouse score. Lazy load will be added to all images below the fold instantly when activating the experiment – that way, you don’t need to update all the pages where background images are set.

UPDATE 28/11/2022: In elementor-3.9-beta-3 we were able to further enhance background-image lazy loading! Instead of loading thumbnail size images on page load, Elementor uses the image dominant colors as background colors. This little change removes entirely background images from the initial page load.

Resource Hints for Google Fonts

Another performance improvement introduced in Elementor 3.9 will help browsers deliver Google Fonts sooner.

Loading Fonts

Up until now Elementor loaded Google Fonts using a simple <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=..."> tag. As of 3.9 we started using the <link rel="preconnect"> tag.

Preconnect Browser Hint

The use of “preconnect” resource hints will let the browser know that the page intends to consume Google Fonts and deliver the font sooner. The browser can probably improve the user experience by preemptively initiating a connection to that origin as the page loads.

The use of resource hints leads to an improvement in performance and a better lighthouse score.

SQL Optimization

We managed to optimize the number of SQL queries in the database on every WordPress admin page by eliminating duplicate queries and queries for unused features.

Checking for Feature Usage

When you are in the WordPress dashboard, Elementor checks whether the site has “Landing Pages”. Elementor Pro performs the same checks to see if the site has “Custom Fonts”, “Custom Icons” and “Popups”.

Both Elementor and Elementor Pro use WP_Query to fetch data from the database, storing the information in memory for later use.

Optimizing Queries

We improved the way Elementor fetched data, removing duplicate queries to fetch the same data we already had. The new optimized method uses a single query and then stores the data to be used elsewhere in the code.

In addition, the data returned from the query was stored in memory but not consumed as a whole. Instead of storing the entire query data in memory, as of 3.9 we store only the needed information, to free up memory space.

WebP Support

Elementor 3.9 introduces a new integration with the Performance Lab plugin developed by the WordPress Performance Team.

Performance Lab Plugin

The Performance Lab plugin is focused on enhancing the performance of WordPress websites with a collection of modules which will eventually be merged into WordPress core.

One of those modules is the “WebP Uploads” which creates WebP files from JPEG image uploads to WordPress websites.

Elementor Integration

If the “Performance Lab” plugin is activated and the “WebP Uploads” feature is enabled, Elementor will use the generated WebP.

Please note that only JPEG images uploaded after activating the plugin will convert to WebP format, all images uploaded before then will maintain their JPEG format.

Improved Repeaters

Elementor 3.9 improves repeater controls and fixes JS errors reported by 3rd-party developers. This will strengthen the feature and allow addon developers to use repeaters in all three panel tabs.

Elementor Repeaters

The repeater control is a complex mechanism that allows addon developers to create repeatable groups of fields in a single control.

Elementor uses repeaters exclusively in the “Content” tab. It was never intended to be used in the “Style” or the “Advanced” tabs. However, some addon developers started utilizing repeaters in tabs other than the “Content” tab.

Paste Styles Bug

Why was it important that repeater controls only be used in the “Content” tab? When a widget uses a repeater control, and the user runs a “Paste Style” command, Elementor pastes the element data, ignoring settings from the “Content” tab. This ensures that only settings from the “Style” and the “Advanced” tabs are implemented on the target element.

As repeaters were never meant to be used outside of the “Content” tab, we hadn’t applied the “Paste Style” functionality on repeaters. Several developers pointed out that this caused bugs which returned JS errors. These errors lead to various usability issues in the Editor. In this release, we address these issues. As of Elementor 3.9 addon developers can use repeaters in every panel settings tab.

Registering Widget JS Handlers

As of Elementor 3.9 there is a new JavaScript hook that can be used after a widget is triggered in the frontend.

Widget JS Handlers

Addon developers can register custom scripts that add additional JS functionality. In order to wire the widget JS handler to the widget and make sure the script runs at the proper time in Elementor’s loading sequence, it is necessary to register the handler with Elementor.

When the page loads, Elementor decides when to load the registered widget handlers. Behind the scenes, Elementor checks which widgets are used in the page, which widgets have JS handlers that need to be loaded in the frontend, and when/how to load them.

DOM ready vs. Handler ready

The “Improved Assets Loading” experiment changes how the widget handlers mentioned above are loaded. The experiment improves performance by swapping the synchronous loading for an asynchronous method.

This change affects JS handlers that listen to the frontend/element_ready/{elementType.skinName} hook that is triggered when the element is ready in the DOM. But because the handler is loaded asynchronously, the loading is delayed.

We introduced a new hook frontend/element_handler_ready/{elementType.skinName} that is triggered after the handler is loaded asynchronously.

The old hook works only when the experiment is turned off, loading the handler synchronously. The new hook works in both cases, when the loading is synchronous or asynchronous.

JS Handler Hooks

frontend/element_ready/{elementType.skinName} – Triggered when the element is ready in the DOM.

frontend/element_handler_ready/{elementType.skinName} – Triggered after the element handler was initiated.

Theme Location Templates

The “Theme Builder” functionality has been part of Elementor Pro since version 2.0 (mid 2018).

Elementor Pro 2.0.10 introduced the elementor/theme/get_location_templates/template_id filter hook to allow multi-language plugins to filter the template ID for theme location templates.

Elementor passes the $theme_template_id value to the hook to allow developers to use conditional logic when using the filter.

Elementor Pro 3.9.0 added the $location parameter to the hook to allow developers to add filters based on the Theme Locations.

 * Filter the template ID for theme location templates.
 * @param int    $theme_template_id Template ID.
 * @param string $location          Theme location.
function filter_template_id( $theme_template_id, $location ) {
	/* … */
add_filter( 'elementor/theme/get_location_templates/template_id', 'filter_template_id' );


Elementor 3.9 introduces several performance improvements that have a direct impact on a site’s lighthouse score. Some of the new features will be applied automatically, others will require experiment activation. But the general trend is to continue improving your site building experience and your site speed each time you update to a new version.

In addition, addon developers can now safely use repeaters everywhere without worrying about JavaScript errors. A new hook helps addon developers add JS handlers that load asynchronously. Finally, a new parameter in the Theme Builder helps target templates based on Theme Location.

Share on facebook
Share on twitter
Share on linkedin


Rami Yushuvaev
Rami Yushuvaev
Head of Elementor Developers Experience. Fullstack developer. Open source projects contributor. Creator of ChartsCSS.org, GenerateWP.com, DisplayWP.com and many other projects.

One Response

  1. When will you give us (specially for EU customers) an easy way to load all Google Fonts server side, like for example Kadence Theme does with on option click?
    I like that you think about speed with the preconnect, but better would be to have the possibility to not use Google servers at all. Speed wise and GDPRA wise.

Leave a Reply

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