diff --git a/src/.vuepress/sidebars/widgets.js b/src/.vuepress/sidebars/widgets.js index 10d6233..3d50128 100644 --- a/src/.vuepress/sidebars/widgets.js +++ b/src/.vuepress/sidebars/widgets.js @@ -46,7 +46,15 @@ module.exports = [ 'rendering-repeaters', 'rendering-html-attribute', 'rendering-inline-editing', + ] + }, + 'widget-optimization', + { + collapsable: false, + sidebarDepth: -1, + children: [ 'widget-output-caching', + 'widget-inner-wrapper', ] }, ] diff --git a/src/widgets/widget-inner-wrapper.md b/src/widgets/widget-inner-wrapper.md new file mode 100644 index 0000000..e509b1f --- /dev/null +++ b/src/widgets/widget-inner-wrapper.md @@ -0,0 +1,94 @@ +# Widget DOM Optimization + + + +Elementor widgets define define their own markup in the `render()` method. However, Elementor wraps each widget in two `
` elements, the outer `
` element and the inner `
` element. These additional wrapper allow Elementor to add additional styles like background, margins, borders, motion effect etc. + +Two wrapper for each widget increase the overall DOM size, reducing page performance. To overcome this, developers can use the `has_widget_inner_wrapper()` method to control the number of wrapper elements the widget has. + +By switching to a single wrapper, a widget can reduces the DOM size and optimize it's footprint on the page. However, existing widgets that rely on the inner `.elementor-widget-container` wrapping element to style widgets, can keep backwards compatibility. + +## Widget Markup + +The current, unoptimized widget markup includes two wrapping elements: + +```html +
+
+ ... +
+
+``` + +The optimized markup, has only one wrapping element: + +```html +
+ ... +
+``` + +By default, Elementor uses the unoptimized markup for backward compatibility. + +## Examples + +### Optimized Widget DOM + +To reduce the DOM size, developers can use the `has_widget_inner_wrapper()` method in the widget class, as shown below: + +```php +` wrapper. + +### Retaining Unoptimized Widget DOM (for BC) + +Legacy widgets that rely on the `.elementor-widget-container` class can continue using the unoptimized DOM by setting the method to return `true`: + +```php{4-6,16} +add_control( + 'color', + [ + 'label' => esc_html__( 'Color', 'textdomain' ), + 'type' => \Elementor\Controls_Manager::COLOR, + 'selectors' => [ + '{{WRAPPER}} > .elementor-widget-container h3' => 'color: {{VALUE}};', + ], + ] + ); + } + + protected function render(): void { + ?> +

+ ... +

+ + +Elementor offers several methods and best practices to optimize widgets and improve performance. The optimizations are not implemented for all the widgets to keep backwards compatibility for older websites. In addition, each widget has its own characteristics. The widget developer needs to add some extra for Elementor to make sure Elementor knows how to process it. + +## Performance Optimization Methods + +Elementor has two performance optimization methods: + +```php +class Elementor_Test_Widget extends \Elementor\Widget_Base { + + public function has_widget_inner_wrapper(): bool {} + + protected function is_dynamic_content(): bool {} + +} +``` + +* **DOM Optimization** - The `has_widget_inner_wrapper()` method lets you determine whether the widget uses optimized DOM structure or not. + +* **Element Output Caching** - The `is_dynamic_content()` method lets you determine whether the widget returns dynamic content, to cache the element HTML output or not. diff --git a/src/widgets/widget-structure.md b/src/widgets/widget-structure.md index 6d823bb..b192f5a 100644 --- a/src/widgets/widget-structure.md +++ b/src/widgets/widget-structure.md @@ -40,6 +40,8 @@ class Elementor_Test_Widget extends \Elementor\Widget_Base { public function get_style_depends(): array {} + public function has_widget_inner_wrapper(): bool {} + protected function is_dynamic_content(): bool {} protected function register_controls(): void {}