#33898 closed enhancement (fixed)
Reduce Customizer peak memory usage by JSON-encoding settings and controls separately
Reported by: | westonruter | Owned by: | westonruter |
---|---|---|---|
Milestone: | 4.4 | Priority: | normal |
Severity: | normal | Version: | 3.4 |
Component: | Customize | Keywords: | has-patch |
Focuses: | performance | Cc: |
Description
In working on a site with a lot of settings and controls in the Customizer, I found that peak memory usage (via memory_get_peak_usage()
) can skyrocket, even to the point where memory usage would come up against the memory_limit
and cause a fatal error. In investigating why, I found the culprit to be this line in wp-admin/customize.php
:
var _wpCustomizeSettings = <?php echo wp_json_encode( $settings ); ?>;
Given a site that has 100 instances of a given widget that has 500 fields in it (see example widget code), the metrics are:
- Initial
_wpCustomizeSettings
JSON size: 14,315,157 bytes memory_get_usage()
: 18,812,904memory_get_peak_usage()
: 47,674,256
If, however, all settings and controls are looped over and serialized separately, these are the metrics:
- Initial
_wpCustomizeSettings
JSON size: 6,803 bytes memory_get_usage()
: 18,812,904memory_get_peak_usage()
: 19,980,976
In both cases, the PHP render time was 0.5 seconds, so doing multiple wp_json_encode()
calls does not add significant processing time compared with a single wp_json_encode()
. The improvements to memory are dramatic, however. But when serializing all of the data together, the peak memory usage is 140% larger (2.4× higher) than when the settings and controls get serialized individually.
In other words, by serializing settings and controls individually, we can cut peak memory usage more and less in half, depending on how many settings and controls are registered the Customizer.
Attachments (5)
Change History (19)
#1
@
9 years ago
- Keywords has-patch added
33898.diff implements the change. I piloted this change in a feature plugin as well: https://github.com/xwp/wp-customize-widgets-plus/pull/32/files
#2
@
9 years ago
I want to take this opportunity to move the logic that is currently in customize.php
into a method on WP_Customize_Manager
, in the same way that has already been done for the preview with WP_Customize_Manager::customize_preview_settings()
.
This ticket was mentioned in Slack in #core by westonruter. View the logs.
9 years ago
@
9 years ago
Additional changes: https://github.com/xwp/wordpress-develop/compare/9591c75...a9126f3
#4
@
9 years ago
- Keywords needs-unit-tests added
In 33898.2.diff:
Serialize settings individually in Preview to avoid memory peak spike.
Move logic from customize.php
to WP_Customize_Manager
class.
- Move logic for exporting JS to Customizer pane to
customize_pane_settings()
method, to correspond tocustomize_preview_settings()
. - Move logic for setting preview url, return url, and autofocus
- Move iOS detection to helper method.
- Create
get_document_title_template
method instead of global variable. - Use
wp_json_encode()
for outputtingajaxurl
. - Move rendering of templates and outputting of settings to
customize_controls_print_footer_scripts
action.
What's remaining are unit tests for these new methods, the logic for which was previously not testable since it was inline to the customize.php
template code.
This ticket was mentioned in Slack in #core-customize by westonruter. View the logs.
9 years ago
#6
@
9 years ago
I've tested 33898.3.diff and it does provide some compelling server performance gains. Here are my numbers.
Before patch and widgets were added.
memory_get_peak_usage(): 45,144,424 memory_get_usage(): 43,918,288 page render time: 1442447924.82
After 100 heavy widgets were added.
memory_get_peak_usage(): 89,830,720 memory_get_usage(): 57,363,952 page render time: 1442447321.09
After the patch was applied. However, I did not save any data to the widgets so the gains were not as dramatic but still very good!
memory_get_peak_usage(): 57,615,968 memory_get_usage(): 56,713,744 page render time: 1442447292.99
#9
@
9 years ago
- Owner set to westonruter
- Resolution set to fixed
- Status changed from new to closed
In 34269:
#10
@
9 years ago
- Keywords commit removed
- Resolution fixed deleted
- Status changed from closed to reopened
Really nice job on the docs for these new methods and properties! Unfortunately, reopening because it looks like a few return descriptions got missed.
https://github.com/xwp/wordpress-develop/pull/121