Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New: Implement caching mechanism on render elements [ED-13883] #25730

Merged
merged 56 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
b350809
New: Implement caching mechanism on render elements [ED-13883]
KingYes Apr 14, 2024
b865189
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 15, 2024
30b7660
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 15, 2024
5e8b1c8
Fix typo
KingYes Apr 15, 2024
d0fe91b
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 15, 2024
bb03fd3
Merge branch 'tweak/ED-13883-elements-cache' of github.com:elementor/…
KingYes Apr 15, 2024
d120722
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 15, 2024
71a8285
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 15, 2024
9986587
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 15, 2024
4722e38
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 15, 2024
8a3763e
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 15, 2024
ac5dcb3
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 15, 2024
b96747c
wip
KingYes Apr 16, 2024
ece2f12
Merge branch 'tweak/ED-13883-elements-cache' of github.com:elementor/…
KingYes Apr 16, 2024
8c71865
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 16, 2024
345a5d6
Added clear cache
KingYes Apr 16, 2024
9020f22
Merge branch 'tweak/ED-13883-elements-cache' of github.com:elementor/…
KingYes Apr 16, 2024
d207a4f
Added options
KingYes Apr 17, 2024
d24b30d
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 17, 2024
a902c4e
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 17, 2024
af16d38
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 17, 2024
4f1f492
Merge branch 'main' into tweak/ED-13883-elements-cache
elementorbot Apr 17, 2024
a8c3acb
lint
KingYes Apr 17, 2024
fcdf1d1
Set all elements default to dynamic
KingYes Apr 21, 2024
4bffa48
Fix conflict
KingYes Apr 21, 2024
c53758d
Added core widgets as a static cache
KingYes Apr 21, 2024
bb1c404
Merge branch 'main' into tweak/ED-13883-elements-cache
KingYes Apr 21, 2024
0ec9c7c
Added core widgets as a static cache
KingYes Apr 30, 2024
af1ee13
Merge branch 'main' into tweak/ED-13883-elements-cache
KingYes Apr 30, 2024
61ce410
Rearrange components
KingYes May 1, 2024
6cf45c3
Merge branch 'main' into tweak/ED-13883-elements-cache
KingYes May 1, 2024
d793912
remove my debug line
KingYes May 1, 2024
c958aa8
Merge branch 'tweak/ED-13883-elements-cache' of github.com:elementor/…
KingYes May 1, 2024
b6bee26
Merge branch 'main' into tweak/ED-13883-elements-cache
KingYes May 2, 2024
184923d
Merge branch 'main' into tweak/ED-13883-elements-cache
KingYes May 3, 2024
39dad02
Added description of the cache control
KingYes May 5, 2024
825e4f5
Improve Assets Condition impl
KingYes May 8, 2024
824a7c2
deprecated tagged
KingYes May 8, 2024
e8a3e08
texts
KingYes May 8, 2024
0dd1002
review
KingYes May 8, 2024
07e7116
remove test
KingYes May 8, 2024
1a52e37
Merge branch 'main' into tweak/ED-13883-elements-cache
KingYes May 8, 2024
d7b1bfe
Merge branch 'main' into tweak/ED-13883-elements-cache
louiswol94 May 9, 2024
484f80c
Merge branch 'main' into tweak/ED-13883-elements-cache
KingYes May 12, 2024
3f5dc5c
Restore old code
KingYes May 12, 2024
7e74fbb
Review
KingYes May 12, 2024
6e5794e
Rearrange components
KingYes May 12, 2024
da14e22
Move add control to the module file
KingYes May 12, 2024
641f609
Control desc
KingYes May 12, 2024
1c80936
Temp: enable by default
KingYes May 12, 2024
a8d99e0
Temp: enable by default
KingYes May 12, 2024
1303569
Temp: enable by default
KingYes May 12, 2024
d460607
Debug
louiswol94 May 13, 2024
8f25772
Make sure the $wp_scripts and $wp_styles are already loaded
KingYes May 13, 2024
aa9dd54
fix warrning in the code
KingYes May 13, 2024
2fd4573
restore
KingYes May 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 20 additions & 0 deletions assets/dev/js/editor/editor-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,26 @@ export default class EditorBase extends Marionette.Application {
if ( ! this.widgetsCache[ widgetType ].commonMerged ) {
jQuery.extend( this.widgetsCache[ widgetType ].controls, this.widgetsCache.common.controls );

this.widgetsCache[ widgetType ].controls = elementor.hooks.applyFilters( 'elements/widget/controls/common', this.widgetsCache[ widgetType ].controls, widgetType, this.widgetsCache[ widgetType ] );

// TODO: Move this code to own file.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you implement this change now already?
We often forget to update such things at a later stage.

if ( this.widgetsCache[ widgetType ].controls?._element_cache ) {
let elementCacheDescription = __( 'The default cache status for this element:', 'elementor' );

elementCacheDescription += ' <strong>';
if ( this.widgetsCache[ widgetType ]?.is_dynamic_content ) {
elementCacheDescription += __( 'Inactive', 'elementor' );
} else {
elementCacheDescription += __( 'Active', 'elementor' );
}
elementCacheDescription += '</strong><br />';
elementCacheDescription += __( 'Activating cache improves loading times by storing a static version of this element.', 'elementor' );
elementCacheDescription += ' <a href="https://go.elementor.com/element-caching-help/" target="_blank">' + __( 'Learn more', 'elementor' ) + '</a>.';

this.widgetsCache[ widgetType ].controls._element_cache.description = elementCacheDescription;
}
// TODO: End of code to move.

this.widgetsCache[ widgetType ].commonMerged = true;
}

Expand Down
115 changes: 114 additions & 1 deletion core/base/document.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ abstract class Document extends Controls_Stack {

const BUILT_WITH_ELEMENTOR_META_KEY = '_elementor_edit_mode';

const CACHE_META_KEY = '_elementor_element_cache';

/**
* Document publish status.
*/
Expand Down Expand Up @@ -857,6 +859,9 @@ public function save( $data ) {

$post_css->delete();

// Remove Document Cache
$this->delete_cache();

/**
* After document save.
*
Expand Down Expand Up @@ -1447,7 +1452,7 @@ public function get_main_meta( $key ) {
* @access public
*
* @param string $key Meta data key.
* @param string $value Meta data value.
* @param mixed $value Meta data value.
*
* @return bool|int
*/
Expand Down Expand Up @@ -1785,6 +1790,68 @@ protected function save_settings( $settings ) {
* @access protected
*/
protected function print_elements( $elements_data ) {
if ( ! Plugin::$instance->experiments->is_feature_active( 'e_element_cache' ) ) {
$this->do_print_elements( $elements_data );

return;
}

$cached_data = $this->get_document_cache();

if ( false === $cached_data ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KingYes We might be able to extract this a bit?

if ( false === $cached_data ) {
    $cached_data = $this->some_descriptive_method_name();
} else {
    $this->enqueue_styles_and_scripts();
}

add_filter( 'elementor/element/should_render_shortcode', '__return_true' );

$scripts_to_queue = [];
$styles_to_queue = [];

global $wp_scripts, $wp_styles;

$should_store_scripts = $wp_scripts instanceof \WP_Scripts && $wp_styles instanceof \WP_Styles;
if ( $should_store_scripts ) {
$scripts_ignored = $wp_scripts->queue;
$styles_ignored = $wp_styles->queue;
}

ob_start();

$this->do_print_elements( $elements_data );

if ( $should_store_scripts ) {
$scripts_to_queue = array_values( array_diff( $wp_scripts->queue, $scripts_ignored ) );
$styles_to_queue = array_values( array_diff( $wp_styles->queue, $styles_ignored ) );
}

$cached_data = [
'content' => ob_get_clean(),
louiswol94 marked this conversation as resolved.
Show resolved Hide resolved
'scripts' => $scripts_to_queue,
'styles' => $styles_to_queue,
];

if ( $this->should_store_cache_elements() ) {
$this->set_document_cache( $cached_data );
}

remove_filter( 'elementor/element/should_render_shortcode', '__return_true' );
} else {
if ( ! empty( $cached_data['scripts'] ) ) {
foreach ( $cached_data['scripts'] as $script_handle ) {
wp_enqueue_script( $script_handle );
}
}

if ( ! empty( $cached_data['styles'] ) ) {
foreach ( $cached_data['styles'] as $style_handle ) {
wp_enqueue_style( $style_handle );
}
}
}

if ( ! empty( $cached_data['content'] ) ) {
echo $cached_data['content']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
louiswol94 marked this conversation as resolved.
Show resolved Hide resolved
}
}

protected function do_print_elements( $elements_data ) {
// Collect all data updaters that should be updated on runtime.
$runtime_elements_iteration_actions = $this->get_runtime_elements_iteration_actions();

Expand All @@ -1803,6 +1870,52 @@ protected function print_elements( $elements_data ) {
}
}

public function set_document_cache( $value ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is too big. Can we extract cache manipulation to a separate class or trait?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it should be within a cache module, I'm not sure

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about extracting it to the caching module. But we have a lots of codes connected to this class, so I just put it here for now.

$expiration = '+12 hours';
KingYes marked this conversation as resolved.
Show resolved Hide resolved

$data = [
'timeout' => strtotime( $expiration, current_time( 'timestamp' ) ),
'value' => $value,
];

$this->update_json_meta( static::CACHE_META_KEY, $data );
}

private function get_document_cache() {
$cache = $this->get_json_meta( static::CACHE_META_KEY );

if ( empty( $cache['timeout'] ) ) {
return false;
}

if ( current_time( 'timestamp' ) > $cache['timeout'] ) {
return false;
}

if ( ! is_array( $cache['value'] ) ) {
return false;
}

return $cache['value'];
}

protected function delete_cache() {
$this->delete_meta( static::CACHE_META_KEY );
}

private function should_store_cache_elements() {
static $should_store_cache_elements = null;

if ( null === $should_store_cache_elements ) {
$should_store_cache_elements = (
! is_admin()
&& ! Plugin::$instance->preview->is_preview_mode()
);
}

return $should_store_cache_elements;
}

protected function register_document_controls() {
$this->start_controls_section(
'document_settings',
Expand Down
2 changes: 2 additions & 0 deletions core/files/manager.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php
namespace Elementor\Core\Files;

use Elementor\Core\Base\Document as Document_Base;
use Elementor\Core\Common\Modules\Ajax\Module as Ajax;
use Elementor\Core\Files\CSS\Global_CSS;
use Elementor\Core\Files\CSS\Post as Post_CSS;
Expand Down Expand Up @@ -112,6 +113,7 @@ public function clear_cache() {
}

delete_post_meta_by_key( Post_CSS::META_KEY );
delete_post_meta_by_key( Document_Base::CACHE_META_KEY );

delete_option( Global_CSS::META_KEY );
delete_option( Frontend::META_KEY );
Expand Down
1 change: 1 addition & 0 deletions core/modules-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public function get_modules_names() {
'announcements',
'site-navigation',
'styleguide',
'element-cache',
'apps',
'home',
'conversion-center',
Expand Down
9 changes: 9 additions & 0 deletions core/page-assets/loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ public function enable_assets( array $assets_data ) {
foreach ( $assets_data as $assets_type => $assets_list ) {
foreach ( $assets_list as $asset_name ) {
$this->assets[ $assets_type ][ $asset_name ]['enabled'] = true;

if ( 'scripts' === $assets_type ) {
wp_enqueue_script( $asset_name );
Comment on lines +61 to +62
Copy link
Contributor

@rotemee rotemee May 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KingYes - Currently pro assets will not be loaded (if core will be upgraded but not the pro), see the usage of assets_loader->add_assets in the pro, it's adding the assets but not registering them:
Here in your implementation, you enqueue only by the handle, so all assets must be first registered, probably what's best is to change the add_ssets method to also register the assets that are being added.
+
Also, change the tests accordingly.

} else {
wp_enqueue_style( $asset_name );
}
louiswol94 marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
Expand All @@ -75,6 +81,9 @@ public function add_assets( array $assets ) {
$this->assets = array_replace_recursive( $this->assets, $assets );
}

/**
* @deprecated 3.22.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the method that we want to keep no? because you now enqueue instead of enable, so why not move the code you have in enable_assets to this method and deprecate the enable_assets.
+
Call the enqueue_assets from the enable_assets and pass the argument.
+
Change in: Elementor\Core\Base\Elements_Iteration_Actions to enqueue_assets instead of enable_assets.
+
Restore the enqueue_assets test (without the "enable" part), why delete it?

*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KingYes - Not sure I understand the latest changes related to the loader, I see that you've restored the call to enqueue_assets(), but why not go with the direction that you need?:

  • enqueue_assets - will enqueue immediately (and not deprecated).
  • enable_assets - will point to the enqueue_assets() and will be marked as deprecated.
  • add_assets - will also register the assets.
    In other words to get rid of the "pre-enabled" capability if it's not needed?

public function enqueue_assets() {
$assets = $this->get_assets();
$is_preview_mode = Plugin::$instance->preview->is_preview_mode();
Expand Down
49 changes: 49 additions & 0 deletions includes/base/element-base.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,20 @@ protected function should_print_empty() {
return true;
}

/**
* Whether the element returns dynamic content.
*
* set to determine whether to cache the element output or not.
*
* @since 3.22.0
* @access protected
*
* @return bool Whether to cache the element output.
*/
protected function is_dynamic_content(): bool {
return true;
}

KingYes marked this conversation as resolved.
Show resolved Hide resolved
/**
* Get child elements.
*
Expand Down Expand Up @@ -430,6 +444,11 @@ public function add_link_attributes( $element, array $url_control, $overwrite =
public function print_element() {
$element_type = $this->get_type();

if ( $this->should_render_shortcode() ) {
echo '[elementor-element data="' . esc_attr( base64_encode( wp_json_encode( $this->get_raw_data() ) ) ) . '"]';
KingYes marked this conversation as resolved.
Show resolved Hide resolved
louiswol94 marked this conversation as resolved.
Show resolved Hide resolved
return;
}

/**
* Before frontend element render.
*
Expand Down Expand Up @@ -523,6 +542,36 @@ public function print_element() {
do_action( 'elementor/frontend/after_render', $this );
}

protected function should_render_shortcode() {
$should_render_shortcode = apply_filters( 'elementor/element/should_render_shortcode', false );

if ( ! $should_render_shortcode ) {
return false;
}

$raw_data = $this->get_raw_data();

if ( ! empty( $raw_data['settings']['_element_cache'] ) ) {
return 'yes' === $raw_data['settings']['_element_cache'];
}

if ( $this->is_dynamic_content() ) {
return true;
}

if ( empty( $raw_data['settings']['__dynamic__'] ) ) {
return false;
}

$is_dynamic_content = apply_filters( 'elementor/element/is_dynamic_content', false, $raw_data, $this );

if ( $is_dynamic_content ) {
return true;
}

return false;
}

/**
* Get the element raw data.
*
Expand Down
1 change: 1 addition & 0 deletions includes/base/widget-base.php
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ protected function get_initial_config() {
'show_in_panel' => $this->show_in_panel(),
'hide_on_search' => $this->hide_on_search(),
'upsale_data' => $this->get_upsale_data(),
'is_dynamic_content' => $this->is_dynamic_content(),
];

if ( isset( $config['upsale_data'] ) && is_array( $config['upsale_data'] ) ) {
Expand Down
4 changes: 4 additions & 0 deletions includes/elements/column.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ public function get_icon() {
return 'eicon-column';
}

protected function is_dynamic_content(): bool {
return false;
}

/**
* Get initial config.
*
Expand Down
4 changes: 4 additions & 0 deletions includes/elements/container.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ class Container extends Element_Base {
*/
private $active_kit;

protected function is_dynamic_content(): bool {
return false;
}

/**
* Container constructor.
*
Expand Down
4 changes: 4 additions & 0 deletions includes/elements/section.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ public function get_icon() {
return 'eicon-columns';
}

protected function is_dynamic_content(): bool {
return false;
}

/**
* Get presets.
*
Expand Down
4 changes: 4 additions & 0 deletions includes/widgets/accordion.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ public function get_keywords() {
return [ 'accordion', 'tabs', 'toggle' ];
}

protected function is_dynamic_content(): bool {
return false;
}

/**
* Hide widget from panel.
*
Expand Down
4 changes: 4 additions & 0 deletions includes/widgets/alert.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ public function get_keywords() {
return [ 'alert', 'notice', 'message' ];
}

protected function is_dynamic_content(): bool {
return false;
}

/**
* Register alert widget controls.
*
Expand Down
4 changes: 4 additions & 0 deletions includes/widgets/audio.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ public function get_keywords() {
return [ 'audio', 'player', 'soundcloud', 'embed' ];
}

protected function is_dynamic_content(): bool {
return false;
}

/**
* Register audio widget controls.
*
Expand Down
4 changes: 4 additions & 0 deletions includes/widgets/button.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ public function get_categories() {
return [ 'basic' ];
}

protected function is_dynamic_content(): bool {
return false;
}

/**
* Get widget upsale data.
*
Expand Down
4 changes: 4 additions & 0 deletions includes/widgets/counter.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ public function get_keywords() {
return [ 'counter' ];
}

protected function is_dynamic_content(): bool {
return false;
}

/**
* Register counter widget controls.
*
Expand Down