The WordPress coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. development team builds WordPress! Follow this site for general updates, status reports, and the occasional code debate. There’s lots of ways to contribute:
Found a bugbugA bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority.?Create a ticket in the bug tracker.
This post has been superseded by the post WordPress 6.5 release delayed 1 week, in which it’s announced fonts will be uploaded to the fonts sub-directory of the uploads folder.
The Font Library, a new feature of WordPress 6.5, will allow users of blockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. editor themes to upload and customize their site’s fonts. You can learn about the full set of Font Library features in the #dev-note.
As fonts are a new first-class object, there has been some discussion around where to store the associated files while accounting for different file systems used by WordPress sites. The particular challenge has been for file systems that do not allow for the writing of files outside the uploads directory (See Gutenberg#59417 and Gutenberg#59699).
To account for such file systems, it was originally decided to natively fallback to the uploads directory natively in WordPress CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress..
Revised approach to font file storage
Exploratory work on supporting a fallback directory natively has demonstrated that this approach would lead to a high risk of bugs. Therefore, the original decision is being modified and the new approach will be:
WordPress Core will by default only attempt to store font files in the wp-content/fonts directory,
For file systems unable to write to or persistently store files in the new directory it is recommended to install the pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-partyFonts to Uploads to store the files in the under existing uploads directory, in wp-content/uploads/fonts
Developers wishing to modify the directory without using a plugin can use the font_dirfilterFilterFilters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output.documented in the announcement post.
Props @mmaattiiaass and other contributors for working on the exploratory pull request.
Welcome back to a new issue of Week in CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress.. Let’s take a look at what changed on TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. between February 5 and February 12, 2024.
71 commits
245 contributors
82 tickets created
11 tickets reopened
82 tickets closed
TicketticketCreated for both bug reports and feature development on the bug tracker. numbers are based on the Trac timeline for the period above. The following is a summary of commits, organized by component and/or focus.
Code changes
Administration
Improve contrast and consistency of focus styles – #51870
Bundled Themes
Twenty Fifteen: Add top margin to the File blockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. button styles – #58498
Twenty Nineteen: Add border-radius to avatarAvatarAn avatar is an image or illustration that specifically refers to a character that represents an online user. It’s usually a square box that appears next to the user’s name. images in the editor – #59285
Twenty Nineteen: Correct line height for Button block – #58443
Twenty Nineteen: Restore transition property to a single line – #58443
Twenty Sixteen: Add border-radius to avatar images in the editor – #59253
Twenty Twenty-Four: Add missing translationtranslationThe process (or result) of changing text, words, and display formatting to support another language. Also see localization, internationalization. functions to text strings – #60298
Twenty Twenty-Four: Prefix the block pattern categoryCategoryThe 'category' taxonomy lets you group posts / content together that share a common bond. Categories are pre-defined and broad ranging. name – #59839
Twenty Twenty-Three: Include Latin-extended characters in DM Sans font files – #59008
Twenty Twenty-Two: Prefix the pages block pattern category name – #59839
Twenty Twenty: Scope .privacy-policy styles to the footer only – #60469
Improve focus outline in Twenty Twenty-Four – #60334
Cast font URLURLA specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org functions to string for add_editor_style() – #59704
Build/Test Tools
Fix bugbugA bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority. pulling local environment containers on Apple silicone – #59930
Generate a human-readable HTMLHTMLHyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. coverage report – #60476
Unpin PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher 7.4 from the test coverage workflow – #59647
Adjust the metaMetaMeta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. key time in wp_scheduled_delete() tests – #59938
Canonical
Introduce admin_canonical_urlfilterFilterFilters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. – #59545
Coding Standards
Add missing fullstop to docblocks in wp-includes/vars.php – #41877
Add viewScriptModule handling to block.json metadata – #60233
Add wakeup magic method to the block bindings registry – #60282
Avoid double escaping on value passed for attribute in HTML tagtagA directory in Subversion. WordPress uses tags to store a single snapshot of a version (3.6, 3.6.1, etc.), the common convention of tags in version control systems. (Not to be confused with post tags.) processor
Update pattern overrides attribute format – #60456
Update the WordPress packages to GutenbergGutenbergThe Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/ 17.7RC1 – #60315
Block HooksHooksIn WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same.: Inject hooked blocks into modified templates and parts – #59646
Blocks: Allow reading the script handle from asset files – #60485
Interactivity APIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways.: Integrate Server Directive Processing – #60356
Add an option to configure the site icon in general settings – #54370, #16434
Remove ableist language from code comments – #60247
HTML API
Add subclassed has_bookmark() and fix seek() – #60474
Join text nodes on invalidinvalidA resolution on the bug tracker (and generally common in software development, sometimes also notabug) that indicates the ticket is not a bug, is a support request, or is generally invalid.-tag-name boundaries – #60385
I18Ni18nInternationalization, or the act of writing and preparing code to be fully translatable into other languages. Also see localization. Often written with a lowercase i so it is not confused with a lowercase L or the numeral 1. Often an acquired skill.
Store pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party deletion results in temporary option – #59433
Quick/Bulk Edit
Pre-fill category fields with their status – #11302
REST APIREST APIThe REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/.
Add featured_media field to attachments endpoint – #41692
Improve error handling in REST meta fields – #48823
Introduce the necessary endpoints for the font library – #59166
Provide detailed error data in REST API response – #60014
Script Loader
Add a timezone offset display value to wp.date.setSettings – #60105
Improve translators comments for wp.date.setSettings in compat file – #60412
always output core block global styles after base global styles – #60280
Micro-optimizations for getting plugin_file in plugins loader loopLoopThe Loop is PHP code used by WordPress to display posts. Using The Loop, WordPress processes each post to be displayed on the current page, and formats it according to how it matches specified criteria within The Loop tags. Any HTML or PHP code in the Loop will be processed on each post. https://codex.wordpress.org/The_Loop. – #60510
Remove unnecessary individual subfiles from $_old_files array – #58995
Users
Replace table tags for color palettes in profiles – #53157
Welcome back to a new issue of Week in CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress.. Let’s take a look at what changed on TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. between August 21 and September 4, 2023.
75 commits
150 contributors (!)
25 new contributors (!)
129 tickets created
13 tickets reopened
117 tickets closed
TicketticketCreated for both bug reports and feature development on the bug tracker. numbers are based on the Trac timeline for the period above. The following is a summary of commits, organized by component and/or focus.
Code changes
Administration
Escape post type output as field attribute – #59190
Build/Test Tools
Avoid doing copy:dynamic when running grunt watch when using --dev option – #59196
Change the version of Node.js in the Codespaces container – #56658
Compare results in performance measurement workflow – #58358, #58359
Enable running the tests on PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher 8.3 – #59231
Ensure database containers are prepared for commands – #30462, #58867
Expand database testing to account for all supported versions and types – #30462
Implicitly pass secrets to the called workflow – #30462
Twenty Nineteen: Improve social media icon dimension attributes – #45950
Ensure that pull quotes are able to use the correct font size – #57854
Coding Standards
Remove unused global variables in various /wp-admin/includes/ files – #59254
Use strict comparison in wp-includes/class-wp-hook.php – #58831
Use strict comparison in wp-includes/class-wp-widget.php – #58831
Use strict comparison in wp-includes/ms-files.php – #58831
Use strict comparison in wp-includes/ms-site.php – #58831
CustomizerCustomizerTool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings.
use the correct X-Robots-TagheaderHeaderThe header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitor’s opinion about your content and you/ your organization’s brand. It may also look different on different screen sizes. – #58865
Database
Improve the documentation for various methods in the wpdb class – #58833
Add missing param description in WP_Comment class – #58890
Clarify post_date_column_timefilterFilterFilters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. description – #59029
Correct default post type in page_template_dropdown()docblockdocblock(phpdoc, xref, inline docs) – #58972
Docblock improvements in _deprecated_class() function, as per docblocks standards – #58833
Fix typo in a translator comment in _deprecated_class() – #58833
Add relative time strings for the wp-date inline script output – #59219, #47373
Don’t use fluid layout value in typography – #58754
Ensure main query loopLoopThe Loop is PHP code used by WordPress to display posts. Using The Loop, WordPress processes each post to be displayed on the current page, and formats it according to how it matches specified criteria within The Loop tags. Any HTML or PHP code in the Loop will be processed on each post. https://codex.wordpress.org/The_Loop. is entered for singular content in blockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. themes – #58154
Optimize wp_get_block_css_selector to remove array_merge calls for better performance – #59178
Preserve block style variations when securing theme – #59108
Introduce font-face styles generator and printer – #59165
Replace two esc_url_raw() calls in core with sanitize_url() – #59247
Use regular core button styles for page header actions – #41986
HTMLHTMLHyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers.APIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways.
Stop processing HTML when encountering unsupported markup – #59167
Update WP_Http class to avoid PHP deprecation warnings – #58876
Help/About
Match icon and text in Help for bulk edit button – #58785
Login and Registration
Improve test coverage for sign on related functions – #36476
Media
Add a filter to the get_available_post_mime_types() function to allow overriding its database query – #52759
Prevent warning if shortcodeShortcodeA shortcode is a placeholder used within a WordPress post, page, or widget to insert a form or function generated by a plugin in a specific location on your site. is used without attributes – #59206
Remove unused $is_IE and $is_opera globals in media_upload_form() – #59254
Menus
Fix proximity of controls to Save and Delete menus – #56594
Options, MetaMetaMeta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. APIs
Introduce prime_options() to load multiple options with a single database request – #58962
Reinstate missing sort_column options in get_pages() – #59226
Remove redundant function calls in get_body_class() – #43661
REST APIREST APIThe REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/.
Remove misleading comment in WP_REST_Blocks_Controller->get_item_schema – #59193
RevisionsRevisionsThe WordPress revisions system stores a record of each saved draft or published update. The revision system allows you to see what changes were made in each revision by dragging a slider (or using the Next/Previous buttons). The display indicates what has changed in each revision.
Add missing escaping function for $post_edit_link in wp-admin/revision.php – #59141
Rewrite Rules
Prevent stampedes when flush_rewrite_rules() is called – #58998
Site Health
Show correct debug value for file uploads – #58737
fix check name used for REST API permission checks – #59236
Upgrade/Install
Add missing escaping function for get_option( 'home' ) in upgrade.php – #59199
Remove unused globals in core_upgrade_preamble() – #59254
Upload
Add a MIME type exception for .docx generated by Google Docs – #57898
Correct duplicate MIME type for .xlsx files generated by Google Docs – #57898
Users
Call add_user_meta() instead of update_user_meta() when adding metadata to a new user – #59212
Properly deprecate both constructors in WP_User_Search – #41125
Remove unused wpdb global in check_password_reset_key() – #59185
Widgets
Improve performance of has_content method in WP_Widget_Media_Gallery class – #58757
XML-RPC
Remove unused wpdb global in wp_xmlrpc_server::mw_newMediaObject() – #59185
Props
Thanks to the 150 (!) people who contributed to WordPress Core on Trac last week:
Welcome back to a new issue of Week in CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress.. Let’s take a look at what changed on TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. between July 31 and August 14, 2023.
40 commits
50 contributors
164 tickets created
15 tickets reopened
138 tickets closed
TicketticketCreated for both bug reports and feature development on the bug tracker. numbers are based on the Trac timeline for the period above. The following is a summary of commits, organized by component and/or focus.
Code changes
Build/Test Tools
Bump the required versions of Node.js and npm – #56658
Correct two @covers annotations to use the recommended pattern – #59069
Update 3rd-party GitHubGitHubGitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/ Actions – #58867
Update all build tool related dependencies – #58863
Update the README file to reflect new Node.js/npm versions – #59071, #56658
Fix leakage in WP_List_Table tests – #58955, #58896
Code Modernization
Deprecate dynamic properties in WP_List_Table magic methods – #58896, #56034
Deprecate dynamic properties in WP_Text_Diff_Renderer_Table magic methods – #58898, #56034
Deprecate dynamic properties in WP_User_Query magic methods – #58897, #56034
Use “declare” in WP_List_Table magic methods deprecation message – #58896
Coding Standards
Bring more consistency to Last-Modified and ETag checks – #58831
Rewrite loose comparison in wp_list_categories() – #58831
Use instanceof keyword instead of the is_a() function – #58943
Use strict comparison in wp-admin/includes/class-wp-importer.php – #58831
Use strict comparison in wp-includes/class-wp-image-editor.php – #58831
Use strict comparison in wp-includes/class-wp.php – #58831
Use strict comparison in wp-includes/cron.php – #58831
Use strict comparison in wp-includes/kses.php – #58831
Use strict comparison in wp-includes/revision.php – #58831
Docs
Correct duplicate hook reference for wp_min_priority_img_pixels – #59067
Remove @see references for SimplePie classes – #59030
Editor
Only exclude auto-generated blockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. files from coding standards checks – #50010
Simplify usage of block_has_support() function by supporting a string – #58532
Embeds
Modernize wp-embed script with removal of obsolete IE10/IE11 code and support for WP 4.4 and below – #58974
Emoji
Suppress console errors from sessionStorage usage in sandboxed post embed iframeiframeiFrame is an acronym for an inline frame. An iFrame is used inside a webpage to load another HTML document and render it. This HTML document may also contain JavaScript and/or CSS which is loaded at the time when iframe tag is parsed by the user’s browser. – #58978, #58472
HTMLHTMLHyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers.APIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways.
Adjust code styling to GutenbergGutenbergThe Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/’s linter’s preferences – #58918
Simplify logic in wp_get_loading_optimization_attributes() – #58891
Options, MetaMetaMeta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. APIs
Use defer loading strategy for wp-embed script and move to head (in block themes) – #58931
Site Health
Use PHP_SAPI constant instead of the php_sapi_name() function – #58942
Themes
Avoid unnecessary check whether parent template file exists when not using a child themeChild themeA Child Theme is a customized theme based upon a Parent Theme. It’s considered best practice to create a child theme if you want to modify the CSS of your theme. https://developer.wordpress.org/themes/advanced-topics/child-themes/. – #58576
add wp_get_theme_data_template_parts function – #59003
A recent in-depth performance analysis of WordPress core showed that loading translations had a significant hit on a site’s server response time. Given that more than half of all WordPress sites use a language other than English (US), the performance team identified this as an area worth looking into more closely. The team spent the last couple of months exploring this in more detail and the results are now shared in this blogblog(versus network, site) post.
This is merely an analysis of the current i18ni18nInternationalization, or the act of writing and preparing code to be fully translatable into other languages. Also see localization. Often written with a lowercase i so it is not confused with a lowercase L or the numeral 1. Often an acquired skill. system in WordPress with some proposed under-the-hood performance improvements. No decisions have been made on any of these proposals.
Context
Initial benchmarks showed that the median loading time for a localized site can be up to 50% slower than for non-localized sites, depending on which themes and plugins are being used. This was measured using both the wpp-research CLI tool and also a dedicated benchmark environment (as elaborated in the Comparison section towards the end).
The WordPress i18n system is based on gettext, which uses source .po (Portable Object) files and binary .mo (Machine Object) files for storing and loading translations. It is not using the C gettext APIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. itself but a custom userland implementation that works without any external dependencies.
In addition to coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. itself, each pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party and theme has its own translationtranslationThe process (or result) of changing text, words, and display formatting to support another language. Also see localization, internationalization. file, which has to be loaded and parsed on every request. Loading and parsing all these translation files is an expensive task.
In the past, various solutions have been discussed and explored to improve the i18n performance of WordPress. A non-exhaustive list:
Use a more lightweight MO parser
Improve translation lookups by using the hash map in MO files (e.g. with DynaMo)
Caching translations in the object cache
Caching translations in APCu (an in-memory key-value store for PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher)
Other more elaborated forms of caching (e.g. per request)
Using the native PHP gettext extension
Use a custom PHP extension to handle the MO file parsing)
Using lazily evaluated translation calls (see #41305 for details)
Using a different file format than .mo files, e.g. plain .php files
For this analysis, many of these solutions were looked at, focusing on their advantages and disadvantages. At the end of this post there is a comparison table with some much needed numbers as well, based on custom-built benchmarks.
Solutions
Solution A: Use different file format
Use a different file format for translations instead of .mo files to avoid the overhead of loading and parsing binary files.
Design considerations
With this solution, translations will be stored in plain .php files returning an associative array of translation strings. Whenever a .php file is available, it will be preferred over the .mo file, which is still used as a fallback. The rest of the architecture remains the same.
When a localized WordPress site downloads language packs from the translate.wordpress.org translation platform, it downloads .po and .mo files containing all the translations. This will be modified to include .php files. GlotPress, which the platform is built on, will be updated to support this new output format. Additionally, WordPress core itself could be modified to generate PHP files whenever they are missing.
In theory, nothing is faster in PHP than loading and executing another PHP file. .json, .ini, or .xml would all be much slower.
Initial benchmarks show consistent significant performance improvements
Relatively trivial to implement
Maintains backward compatibility thanks to graceful fallback
Makes it easier for users to inspect and change translations (no need to compile .po to .mo)
Avoids loading and parsing binary .mo files, which is the main bottleneck
Lets PHP store translations in OPcache for an additional performance benefit
Battle-tested approach in the PHP ecosystem (for example in Laravel)
Caveats and risks
Requires not only changes to WordPress core, but also tools like GlotPress and WP-CLIWP-CLIWP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/https://make.wordpress.org/cli/
Adds maintenance overhead by introducing a new file format on top of the existing one
As shown by the proof of concept, the overhead is minimal
In the long term, .mo support could be deprecated
Security considerations due to essentially executing remotely fetched PHP files
Not really different from downloading plugins/themes from WordPress.org
WordPress considers translations to be trusted
Hosting providers could be blocking PHP execution in wp-content/languages
Could potentially use checksum verifications or static analysis at install time to detect anomalies
Effort and timeline
The proof of concept using PHP files is in a very solid state already. There are also examples for changes to WP-CLI (PR) and GlotPress (PR). This makes it suitable for a feature project to expand testing with very little effort required. Even a core merge would be very straightforward in a relatively short time, potentially already in Q4 2023. The security aspect when using PHP files could be a potential blockerblockerA bug which is so severe that it blocks a release., so it’s important to loopLoopThe Loop is PHP code used by WordPress to display posts. Using The Loop, WordPress processes each post to be displayed on the current page, and formats it according to how it matches specified criteria within The Loop tags. Any HTML or PHP code in the Loop will be processed on each post. https://codex.wordpress.org/The_Loop. in the WordPress security team and hosting providers early on.
More time is required to test other file formats and compare results.
Solution B: Native gettext extension
Use the native gettext PHP extension written in C when available, instead of the custom built-in parser in WordPress.
Design considerations
WordPress has always used a custom MO file parser, because the native gettext extension is not necessarily available on the server. With this solution, the existing system is adapted to use the extension whenever available and falling back to the custom implementation if not.
This has been previously explored in #17268 and implemented in WP Performance Pack and Native Gettext. These implementations can serve as inspiration for the initial design. They all work similarly in that they symlink or copy the translation files to a new directory structure that is compatible with the gettext extension.
As of July 2023, around 66% of all localized WordPress sites have the gettext extension installed, according to information from the WordPress update requests.
Benefits
Significant performance improvements for eligible sites
Initial benchmarks show that loading time and memory usage basically do not differ from non-localized sites
Caveats and risks
The gettext extension is not commonly available
Smaller incentive to implement and lower impact overall
Requires locales to be installed on the server
Servers rarely have many installed locales
Locales often need to be compiled first and take up a lot of space
WordPress on the other hand supports over 200 locales
Potential clashes with the custom locales WordPress supports
For example, locales like pt_PT_ao90, de_DE_formal or roh might not even be supported
Outreach to hosting providers would be necessary
Adds maintenance overhead by essentially adding a second gettext implementation
Poor API
Requires setting environment variables (such as LC_MESSAGES and LANGUAGE), which might not be possible or cause conflicts on certain servers/sites
Requires symlinks or hard file copies
Symlinks might not be possible on the server; copying all translation files means doubling disk usage
Translation files are cached by PHP, thus any translation change requires restarting the web server
There are workarounds such as cache busting using random file names or fstat, however they might not work on all environments
Has not been tested on a wider scale, despite being discussed for years
While there are existing implementations that could be leveraged for this solution, further field testing is required to assess whether the extension actually works under all circumstances. Given the limitations around the poor API and requirements for installing locales, it does not seem like a viable solution at all.
Solution C: Cache translations
Cache translations somehow to avoid expensive .mo parsing.
Design considerations
Cache translations either on disk, in the database, or the object cache to avoid expensive .mo file parsing on subsequent requests. This can be done in a generalized manner or also on a per-request basis to only load translations required for the current URLURLA specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org.
Many different caching strategies have been explored in various forms in the past, each with their own pros and cons. Some could even be combined. Defining the exact implementation requires further exploration and testing, which warrants its own exploration post.
Benefits
Caching translations after one time .mo parsing potentially improves performance for future requests
Caveats and risks
Caching using persistent object cache (e.g. Memcached, Redis) or APCu:
Not available on most sites, making this not an ideal solution
Availability according to data from WordPress update requests:
Memcached: ~25%
Redis: ~25%
APCu: ~6%
Can potentially significantly increase cache size or exceed cache key limits
Database caching:
Moves the problem from disk reads to database reads
Can potentially significantly increase database size
Alternatively, use sqlite as a cache backend
Untested approach
Available on around 90% of sites
Disk caching:
Not always possible, depending on server environment
Still causes file reads, only with fewer or other files
Multiple cache groups (e.g. per-request or frontend/adminadmin(and super admin) split)
Smarter cache logic to only load translations that are needed for the majority of requests
Can potentially significantly increase cache size
Unlikely that different requests use very different translations
Cache retrieval adds overhead
Exact performance gains depend on implementation method and need to be measured first
No performance gains with cold cache
Cache invalidation logic TBD
Effort and timeline
Given the existing solutions in the ecosystem, the engineering effort itself would not be too big, but the right caching implementation (e.g. disk cache or object cache) needs to be evaluated first.
However, the right caching strategy probably does not exist because of all the different hosting environments. Since it’s unrealistic for core to support multiple types of caching, this solution seems better suited for plugins rather than core.
Solution D: Lazily evaluated translation calls
Use lazily evaluated translation calls to reduce the number of function calls in certain cases, leading to improved performance.
Design considerations
The idea of lazily evaluated translation calls has been first discussed in #41305. It enables avoiding string-specific expensive translation lookups until the translations are actually needed, by passing around proxy objects.
In other words: beyond just-in-time loading of translation files (which WordPress already does), this would add just-in-time lookup of individual strings in the translations. Check out this proof of concept to get a better picture.
It can be integrated essentially in two ways, both of which are explained on the core ticketticketCreated for both bug reports and feature development on the bug tracker.:
Change all translation calls to be lazily evaluated by default
Make this opt-in, either with new function arguments or new functions altogether
Benefits
Reduces the number of translation lookups, in some scenarios drastically
On a regular home page request there are ~60% less translation calls, saving around ~10ms (as measured by XHProf)
As a side effect, solves UXUXUser experience issues such as #38643
Caveats and risks
Depending on implementation this either breaks backward compatibility or risks not gaining enough adoption
Documentation, tooling, and developer education can help mitigate this to a certain extent
Adoption could be done gradually, e.g. starting with an opt-in approach and eventually making it the default
Likely will not have a significant impact on typical frontend page loads, as it’s mostly useful for areas like the REST APIREST APIThe REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. schema output, where a lot of translation calls are made without actually using the translations
Needs analysis in more scenarios to measure impact
The REST API schema already has a workaround by using a cache in a static variable
Does not improve situation for actually loading translation files
Initial testing shows that this actually hurts performance due to the additional thousands of proxy objects being created
Effort and timeline
Gradual adoption would mean a multi-year effort to establish lazily evaluated translation calls, while enabling this by default is a significant backward compatibility break that could affect thousands of plugins and themes in the ecosystem. And since it does actually slow down performance in some cases, this solution is not a great candidate for implementation.
Solution E: Optimize/Rewrite existing MO parser
Refactor the existing MO parser in WordPress to be more performant.
Design considerations
Completely overhaul the existing MO translation file parser in WordPress with performance in mind. For example by using Ginger MO, WP Performance Pack, or other existing solutions as a base.
While for instance Altis DXP (Human Made) have actually replaced the existing MO parser with a custom-made PHP extension written in Rust, such an approach is obviously not feasible for core. The new solution needs to be written in userland PHP.
Initial testings with an updated fork of Ginger MO show some noticeable speedups and lower memory usage. It also supports multiple translation files per text domain and multiple locales loaded at once, which could prove beneficial for improving the localeLocaleA locale is a combination of language and regional dialect. Usually locales correspond to countries, as is the case with Portuguese (Portugal) and Portuguese (Brazil). Other examples of locales include Canadian English and U.S. English. switching functionality in WordPress core.
Besides that, plugins like WP Performance Pack and DynaMo have implemented partial lookups using the MO hash table or binary search, avoiding reading the whole file and storing it in memory. That slightly reduces memory usage and performance.
Benefits
Can be used without necessarily introducing another file format
Opens up potential performance enhancements in other areas, i.e. locale switching
Mostly maintains backward compatibility
Caveats and risks
Still a risk of breaking backward compatibility
Effort and timeline
There already is a working proof of concept for this solution, but more testing is required to further refine it and improve its backward compatibility layer. With such an effort being an ideal candidate for a feature pluginFeature PluginA plugin that was created with the intention of eventually being proposed for inclusion in WordPress Core. See Features as Plugins., this could be achieved relatively quickly in a few months.
Solution F: Splitting up translation files
Split translation files from plugins and themes into smaller chunks to make loading them more efficient.
Design considerations
Depending on the project’s size, translation files can be quite big. That’s why WordPress itself uses separate translation files for the admin and everything else, so that not too many strings are unnecessarily loaded.
This strategy could be applied to plugins and themes as well. Either by allowing them to use multiple text domains (which would require developer education and changes to tooling), or by somehow doing this automatically (exact method TBD)
Benefits
Faster loading times due to loading smaller files
Caveats and risks
Risk of breaking backward compatibility
Opt-in approach requires tooling and distribution changes and risks slow adoption
Effort and timeline
Further research is required to evaluate this properly.
Comparison
At first glance, solution A (PHP translation files) is a relatively straightforward enhancementenhancementEnhancements are simple improvements to WordPress, such as the addition of a hook, a new feature, or an improvement to an existing feature. that maintains backward compatibility and shows promising improvements. However, it does not only require changes to core itself, but also to the translation platform. The security aspect remains a risk, although discussing it early on with stakeholders and gathering more testers would help mitigate it.
Leveraging the native gettext extension as in solution B shows stunning results, but the lack of availability and the non-ideal API are a concern. Still, it’s a progressive enhancement that cannot be ignored. Especially since it could pretty much eliminate the need for additional caching as in solution C.
Caching already loaded translations as in solution C does not eliminate the root cause of the i18n slowness, but can speed up subsequent requests. Unfortunately, persistent object caches or APCu are rather uncommon (though we do not have exact data on the former yet, see #58808), and implementing more complex types of caching (e.g. per-request caching) would require significant exploration effort before becoming a viable option.
Lazily evaluated translation calls (solution D) can shave time off translation calls in some situations, but overall actually decrease performance. While it could help solve some actual UX issues in core, the backward compatibility and adoption concerns make it even less of a suitable solution.
Existing plugins like Ginger MO and WP Performance Pack show that the existing MO parser in WordPress can be further improved (solution E).
Benchmarks
Now to the most interesting part: the hard numbers!
These benchmarks are powered by a custom-built performance testing environment using @wordpress/env and Playwright. The environment has been configured with some additional plugins and the PHP extensions required for some of the solutions. Tests have been performed against the 6.3 RCrelease candidateOne of the final stages in the version release cycle, this version signals the potential to be a final release to the public. Also see alpha (beta). by visiting the home page and the dashboard 30 times each and then using the median values.
BlockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. Theme
Locale
Scenario
Object Cache
Memory Usage
Total Load Time
en_US
Default
15.60 MB
133.58 ms
de_DE
Default
29.14 MB
181.95 ms
de_DE
Ginger MO (MO)
19.24 MB
159.18 ms
de_DE
Ginger MO (PHP)
16.98 MB
138.14 ms
de_DE
Ginger MO (JSONJSONJSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML.)
19.24 MB
153.39 ms
de_DE
Native Gettext
15.99 MB
142.12 ms
de_DE
DynaMo
19.62 MB
157.93 ms
de_DE
Cache in APCu
50.37 MB
181.51 ms
en_US
Default
✅
15.67 MB
121.53 ms
de_DE
Default
✅
29.01 MB
167.67 ms
de_DE
Ginger MO (MO)
✅
19.11 MB
147.19 ms
de_DE
Ginger MO (PHP)
✅
16.85 MB
127.97 ms
de_DE
Ginger MO (JSON)
✅
19.11 MB
144.43 ms
de_DE
Native Gettext
✅
15.86 MB
129.19 ms
de_DE
DynaMo
✅
18.57 MB
133.46 ms
de_DE
Cache in APCu
✅
50.30 MB
170.19 ms
de_DE
Cache in object cache
✅
29.07 MB
173.19 ms
Benchmarks using the Twenty Twenty-Three block theme
Classic Theme
Locale
Scenario
Object Cache
Memory Usage
Total Load Time
en_US
Default
15.35 MB
120.79 ms
de_DE
Default
28.79 MB
172.10 ms
de_DE
Ginger MO (MO)
18.85 MB
145.68 ms
de_DE
Ginger MO (PHP)
16.56 MB
124.73 ms
de_DE
Ginger MO (JSON)
18.84 MB
140.78 ms
de_DE
Native Gettext
15.58 MB
128.26 ms
de_DE
DynaMo
19.24 MB
146.09 ms
de_DE
Cache in APCu
50.13 MB
167.28 ms
en_US
Default
✅
15.19 MB
107.26 ms
de_DE
Default
✅
28.59 MB
154.30 ms
de_DE
Ginger MO (MO)
✅
18.64 MB
133.21 ms
de_DE
Ginger MO (PHP)
✅
16.37 MB
112.94 ms
de_DE
Ginger MO (JSON)
✅
18.64 MB
128.94 ms
de_DE
Native Gettext
✅
15.38 MB
115.11 ms
de_DE
DynaMo
✅
18.10 MB
120.72 ms
de_DE
Cache in APCu
✅
49.99 MB
151.82 ms
de_DE
Cache in object cache
✅
28.65 MB
156.36 ms
Benchmarks using the Twenty Twenty-One classic theme
Admin
Locale
Scenario
Object Cache
Memory Usage
Total Load Time
en_US
Default
15.42 MB
139.83 ms
de_DE
Default
31.92 MB
187.76 ms
de_DE
Ginger MO (MO)
20.07 MB
164.94 ms
de_DE
Ginger MO (PHP)
17.09 MB
139.66 ms
de_DE
Ginger MO (JSON)
20.06 MB
160.87 ms
de_DE
Native Gettext
15.95 MB
143.43 ms
de_DE
DynaMo
20.58 MB
166.79 ms
de_DE
Cache in APCu
58.13 MB
190.38 ms
en_US
Default
✅
15.66 MB
112.69 ms
de_DE
Default
✅
31.84 MB
164.26 ms
de_DE
Ginger MO (MO)
✅
19.99 MB
140.70 ms
de_DE
Ginger MO (PHP)
✅
17.01 MB
118.52 ms
de_DE
Ginger MO (JSON)
✅
19.98 MB
138.49 ms
de_DE
Native Gettext
✅
15.87 MB
120.01 ms
de_DE
DynaMo
✅
19.73 MB
120.26 ms
de_DE
Cache in APCu
✅
58.07 MB
162.41 ms
de_DE
Cache in object cache
✅
31.86 MB
164.28 ms
Benchmarks visiting the WordPress admin
Conclusion
Finding the right path forward means weighing all the pros and cons of each solution and looking at both horizontal and vertical impact, i.e. how much faster can i18n be made for how many sites.
When looking at all these factors, it appears that a revamped translations parser (solution E) could bring the most significant improvements to all localized WordPress sites. Especially when combined with a new PHP translation file format (solution A), which Ginger MO supports, the i18n overhead becomes negligible. Of course the same risks associated with introducing a new format apply.
On top of that, a revamped i18n library like Ginger MO could also be combined with other solutions such as caching or dynamic MO loading to potentially gain further improvements. However, those routes have yet to be explored.
Next steps
The WordPress performance team wants to further dive into this topic and test some of the above solutions (and combinations thereof) on a wider scale through efforts like the Performance Lab feature project. We are looking forward to hearing your feedback on this analysis and welcome any additional comments, insights, and tinkering.
Deadline August 6, 2023
After the deadline passes, the performance team will discuss the received feedback and determine next steps.
Welcome back to a new issue of Week in CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress.. Let’s take a look at what changed on TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. between June 19 and June 26, 2023.
112 commits
192 contributors
68 tickets created
16 tickets reopened
107 tickets closed
TicketticketCreated for both bug reports and feature development on the bug tracker. numbers are based on the Trac timeline for the period above. The following is a summary of commits, organized by component and/or focus.
Code changes
Administration
Add the no-store and private directives to the Cache-ControlheaderHeaderThe header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitor’s opinion about your content and you/ your organization’s brand. It may also look different on different screen sizes. when preventing caching for logged in users – #21938, #57627
Backwards compatibility for new sortable keys – #32170
Consistent positioning and size of search form – #57949
Fix visual regressionregressionA software bug that breaks or degrades something that previously worked. Regressions are often treated as critical bugs or blockers. Recent regressions may be given higher priorities. A "3.6 regression" would be a bug in 3.6 that worked as intended in 3.5. in media search input – #57949
Reduce translationtranslationThe process (or result) of changing text, words, and display formatting to support another language. Also see localization, internationalization. calls after [55969] – #57675
Replace Tagline option placeholder with a description – #57675
Replace contracted verb forms for better consistency – #30796
Set accessible state for list table headers – #32170
Bootstrap/Load
Require wp-includes/compat.php earlier in wp-settings.php – #58206
Require wp-includes/compat.php in wp-load.php – #58206
Update URLURLA specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org of theme unit testunit testCode written to test a small piece of code or functionality within a larger application. Everything from themes to WordPress core have a series of unit tests. Also see regression. data – #58569
Update the test for pre_wp_setup_nav_menu_itemfilterFilterFilters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. – #56577
Bundled Themes
Twenty Fifteen: Fix Letter Case implementation – #58526
Twenty Fifteen: Remove IE specific resources – #56699
Twenty Fourteen: Fix Letter Case implementation – #58526
Twenty Nineteen: Always set background color and foreground color together – #45916
Twenty Nineteen: Ensure Separator blockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. supports theme colors in editor – #58558
Twenty Nineteen: Fix a JSJSJavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors. coding standard issue found after [55970] – #46474
Twenty Nineteen: Prevent a console error related to the main navigation on Firefox – #46474
Twenty Nineteen: Remove unused function parameters and variables – #57397
Twenty Twenty: Fix Letter Case implementation – #58526
Twenty Twenty: Fix an RTL style issue leading to failed Test Default Themes & Create ZIPs workflow – #58396
Twenty Twenty: Fix left margin in Latest Posts & Latest Comments blocks – #58396
Twenty Twenty: Inherit Quote block’s paragraph custom letter spacing in the editor – #58033
Twenty Twenty: Remove various unused function parameters and variables – #57371
Twenty Twenty: Revert [56034] pending further investigation – #58396
Cache APIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways.
Remove unused usermeta global cache group – #58175
Code Modernization
Replace usage of strpos() with str_contains() – #58206
Replace usage of substr() with str_starts_with() and str_ends_with() – #58220
Fix block editor styles being registered with frontend stylesheets – #58605
Fix block template utils test: use template part instead of template object – #58540
Improve accessibilityAccessibilityAccessibility (commonly shortened to a11y) refers to the design of products, devices, services, or environments for people with disabilities. The concept of accessible design ensures both “direct access” (i.e. unassisted) and “indirect access” meaning compatibility with a person’s assistive technology (for example, computer screen readers). (https://en.wikipedia.org/wiki/Accessibility) of new custom fieldCustom FieldCustom Field, also referred to as post meta, is a feature in WordPress. It allows users to add additional information when writing a post, eg contributors’ names, auth. WordPress stores this information as metadata. Users can display this meta data by using template tags in their WordPress themes.UIUIUser interface – #15631
Introduce WP_Theme_JSON::prepend_to_selector() to improve code quality and performance – #58193, #58457
fix site editor layout bugbugA bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority. – #56228
Improve Dashboard screen options behavior on small screens – #57977
I18Ni18nInternationalization, or the act of writing and preparing code to be fully translatable into other languages. Also see localization. Often written with a lowercase i so it is not confused with a lowercase L or the numeral 1. Often an acquired skill.
Ensure determine_locale() does not potentially return an empty string – #58317
Add a $previous_status parameter to wp_trash_post() related hooksHooksIn WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same. – #58392
Quick/Bulk Edit
Don’t set publish date when editing drafts – #19907
REST APIREST APIThe REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/.
Indicate when a theme supports the Site editor in the Themes REST API response – #58123
Return post modified datetime for Templates – #58540
Script Loader
Add support for HTMLHTMLHyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. 5 “async” and “defer” attributes – #12009
Replace str_contains() usage in wp-includes/script-loader.php – #58206
Themes
Allow non-block themes to add theme support for border settings – #58598
Allow non-block themes to add theme support for link color settings – #58597
Change the order of path check in is_block_theme method – #58520
Fix caching issue in get_post_templates method in WP_Theme – #57886
Tools
Fix unresolvable conflicts computation in package sync script – #58628
Upgrade/Install
Add aria-describedby for input descriptions – #58613
Move location of $upgrade_notice for better consistency – #57939
Prevent users from sending multiple bulk pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party updates – #40966
Agreed to postpone this to Tuesday June 20 to support several team members being out for the US holiday
Upcoming BetaBetaA pre-release of software that is given out to a large group of users to trial under real conditions. Beta versions have gone through alpha testing in-house and are generally fairly close in look, feel and function to the final product; however, design changes often occur as part of the process. 1 for the 6.3 release on Tuesday June 27, 2023
Updates to our CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress. Performance Handbook with the introduction of the Profiling PHP performance with XHProf article
JavaScriptJavaScriptJavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. & CSSCSSCascading Style Sheets.
Most of the PR for adding support for `async` and `defer` has been approved for commit. Unfortunately, keeping in support for inline scripts is blocking the current PR, so we’re going to remove that part of the implementation this week and commit the rest. This just means that if anyone tries to add an `async` or `defer` strategy to a handle that has an inline script attached in an `after` position, the original script will be loaded with a blocking strategy instead.
@spacedmonkey I code reviewed the above and approved it for commit
@joemcgill we will likely ask for another review once we’ve implemented the changes
@10upsimon Nothing more from my side, I’ll be working with @joemcgill on the reversal of delayed after inline scripts, and further testing
@10upsimon this is the same level of push back we’re receiving on the Trac ticket itself. It’s a long standing aversion to support delayed inline scripts. I’d like to see it in core as well, if possible.
@joemcgill I think we’ve exhausted this conversation for now. The focus this week should be to get the majority of this feature committed and we can advocate for extending support for inline scripts during the beta period.
@spacedmonkey Could it be commit before the beta and then if we can resolve the inline style stuff, then we can do a part revert?
@joemcgill Andrew has indicated in the PR thread that we could continue that conversation during the beta period, yes
@adamsilverstein Some recent developments on the modern image front: the new version of Safari includes JpegXL support which was a bit of a surprise and somewhat exciting. If other browsers follow suit, maybe the format will become useful for the web and WordPress?! In addition, Edge canary has apparently added AVIF support, so we will hopefully see all major browsers supporting AVIF soon. I created a patchpatchA special text file that describes changes to code, by identifying the files and lines which are added, removed, and altered. It may also be referred to as a diff. A patch can be applied to a codebase for testing. to add AVIF support to core on the existing ticketticketCreated for both bug reports and feature development on the bug tracker. that is ready for testing – https://core.trac.wordpress.org/ticket/51228
@spacedmonkey I have been code review and profiling this. We are awaiting a new version that improves PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher performance.
@joemcgill Over the weekend, the Theme Unit Testunit testCode written to test a small piece of code or functionality within a larger application. Everything from themes to WordPress core have a series of unit tests. Also see regression. data that we rely on briefly went offline and broke the automated performance tests in Core. There is an open ticket about bringing that code directly into our repo, rather than relying on the Theme Unit Test data, but there is also conversation happening about moving all of that code into the WP organization. Original thread: https://wordpress.slack.com/archives/C02RQBWTW/p1687140431658569 For now, I don’t think we need to take immediate action, but is something to consider over the coming weeks.
@joegrainger We are working on the last check for Milestone 2 for the Plugin Checker. Once complete we’ll be moving onto further QA/Testing and remediating over this week and next. Progress can be seen on the GitHub repo here. Feel free to take a look and leave any thoughts/ideas you may have in the repo. Thanks!
@flixos90 Still awaiting approval of the Dominant Color Images pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party in the plugin repo
TLDR, WP_Commey_Query does count queries using order by, resulting in bad performance. Comment type is not a database index.
@joemcgill That ticket needs an owner and and agreed upon patch in the next week. Seems like a stretch at the moment.
@spacedmonkey I am not sure we can add indexes easily to a table like comments. The person on the ticket has 5 million comments in this database. Adding an index normally locks a table on a high traffic like that, it could be a problem. I think we will have to puntpuntContributors sometimes use the verb "punt" when talking about a ticket. This means it is being pushed out to a future release. This typically occurs for lower priority tickets near the end of the release cycle that don't "make the cut." In this is colloquial usage of the word, it means to delay or equivocate. (It also describes a play in American football where a team essentially passes up on an opportunity, hoping to put themselves in a better position later to try again.) to 6.4. I will update the ticket.
@rmccue I think we’ve added indexes on large tables before, seem to recall .com needing to orchestrate a slow rollout of them
@joemcgill Do we know who is ensuring the fix for https://core.trac.wordpress.org/ticket/58457 is getting synced from the GutenbergGutenbergThe Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/ repo? This process still seems very manual and error prone to me.
@joemcgill That ticket seems to include references to two Gutenberg PRs, and a newly updated patch on that ticket. It would be good to have someone making sure that all of this gets resolved correctly.
@flixos90 I hadn’t seen that ticket. Seems like the reporter found the same issue but fixed it in a different way. The patches on that ticket are effectively obsolete if my above PR is committed. I’ll leave a comment
Welcome back to a new issue of Week in CoreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress.. Let’s take a look at what changed on TracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. between May 8 and May 22, 2023 (sorry for not being able to publish a post last week, this one will cover two weeks!).
TicketticketCreated for both bug reports and feature development on the bug tracker. numbers are based on the Trac timeline for the period above. The following is a summary of commits, organized by component and/or focus.
Code changes
Administration
Add missing escaping for CSSCSSCascading Style Sheets. classes on the body tagtagA directory in Subversion. WordPress uses tags to store a single snapshot of a version (3.6, 3.6.1, etc.), the common convention of tags in version control systems. (Not to be confused with post tags.) in the adminadmin(and super admin) – #58336
Build/Test Tools
Call wp_cache_flush_runtime in WP_UnitTestCase. – #31463
Move wp_cache_flush_runtime() next to wp_cache_flush() – #57841
Remove expectation of a deprecation notice from WP_Posts_List_Table tests – #58157
Split the tests from user/author.php into individual test classes – #57841
Use the function get_num_queries across all unit tests – #57841
Code Modernization
Correct fallback return value in get_the_author() – #58157
Explicitly declare all properties in Text_Diff_Engine_native – #58298
Coding Standards
Use esc_url() to escape link URLURLA specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org value in wp-admin/edit-link-form.php – #58282
Comments
Always lazily load comment metaMetaMeta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. – #57801
Docs
A host of corrections and improvements to inline documentation – #57840
Clarify @param types on get_sample_permalink_htmlfilterFilterFilters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. – #58322
Correct default value for the $optimize option in Style Engine – #57840
Fix a few more typos in DocBlocks and inline comments – #57840
Fix a few more typos in inline comments – #58334, #57840
Fix typo in a comment in Bulk_Upgrader_Skin::header() and ::footer() – #58334
Improve HTMLHTMLHyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers.APIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. file and class headers per the documentation standards – #57840
Improve Style Engine DocBlocks per the documentation standards – #57840
Improve Style Engine file and class headers per the documentation standards – #57840
Improve a few DocBlocks in wp-includes/formatting.php – #58316
Update code examples formatting in WP_HTML_Tag_Processor documentation – #58028
Various corrections and improvements to inline docsinline docs(phpdoc, docblock, xref) and docblocks – #57840
describe return type of _get_block_template_file() – #57756
Editor
Disable lazy loading term meta in get_block_templates – #58230
Ensure blockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. comments are of a valid form
Remove shortcodeShortcodeA shortcode is a placeholder used within a WordPress post, page, or widget to insert a form or function generated by a plugin in a specific location on your site. support from block templates
Restore shortcode support for block templates – #58333
Update block editor packages to the latest patchpatchA special text file that describes changes to code, by identifying the files and lines which are added, removed, and altered. It may also be referred to as a diff. A patch can be applied to a codebase for testing. releases – #58274
Embeds
Add protocol validation for WordPress Embed code
General
Remove a few is_object() checks followed by instanceof operator – #58309
Use static on closures whenever $this is not used to avoid memory leaks – #58323
Help/About
Remove unwanted space in a link located on about.php – #58373
I18Ni18nInternationalization, or the act of writing and preparing code to be fully translatable into other languages. Also see localization. Often written with a lowercase i so it is not confused with a lowercase L or the numeral 1. Often an acquired skill.
Introduce sanitization function for localeLocaleA locale is a combination of language and regional dialect. Usually locales correspond to countries, as is the case with Portuguese (Portugal) and Portuguese (Brazil). Other examples of locales include Canadian English and U.S. English.
Replace “Roll back” with “Restore” in user facing strings – #58282
Media
Conditionally skip lazy-loading on images before the loopLoopThe Loop is PHP code used by WordPress to display posts. Using The Loop, WordPress processes each post to be displayed on the current page, and formats it according to how it matches specified criteria within The Loop tags. Any HTML or PHP code in the Loop will be processed on each post. https://codex.wordpress.org/The_Loop. to improve LCP performance – #58211
Increase default for wp_omit_loading_attr_threshold to 3 – #58213
Load WP_Metadata_Lazyloader class file if class does not exist – #58185
Load WP_Metadata_Lazyloader class file if class in meta.php – #58185
Plugins
Remove is_object() check in WP_Hook:build_preinitialized_hooks() – #58290
Posts, Post Types
Add a new filter for query arguments in get_pages – #12821
RevisionsRevisionsThe WordPress revisions system stores a record of each saved draft or published update. The revision system allows you to see what changes were made in each revision by dragging a slider (or using the Next/Previous buttons). The display indicates what has changed in each revision.
Add edit link functionality for the wp_template and wp_template_part post types – #57709
Updated the cadence of bugbugA bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority. scrubs to be every 2 weeks – next one scheduled for April 26, 2023 at 15:00 UTC.
Discussion regarding the decoupling of the SQLite pluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-partyfrom the performance lab work. In reference to this conversation that came up in a previous performance chat. Would love to have an open discussion about peoples preferences here and whether we do decouple this?
@olliejones I favor that approach. It will usually be deployedDeployLaunching code from a local development environment to the production web server, so that it's available to visitors. independently of the stuff in PL.
@10upsimon I tend to lean more toward an agreement with @rmccue in that SQLite is not necessarily performance improvements focused (or at least that is not the primary goal), and probably belongs outside of the realm of the performance lab work.
@spacedmonkey To be clear, I think that performance team should continue to support SQlite getting into coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress., to much sure it done in a performant way. But SQlite is not a performance benefit on the face of it, so it is confusing why we part of performance lab plugin.
@rmccue Yeah, that was basically my thought; I think it’s beneficial all-round to separate it out (but with performance still consulting as @spacedmonkey says)
@olliejones yes, having SQLite headed for core is good. I believe the issue is about monorepo and multifunction plugins on the one hand and a separate repo and plugin on the other.
@aristath I agree with what was mentioned above 100%. SQLite can be related to performance, but is not in itself a “performance” module/plugin. It should be developed in collaboration with the performance team since it can have a big impact, but I’d vote to decouple it from the performance-lab plugin
@olliejones Maybe in a parallel universe or another year, there can be a separate database team. But for now the perf. team has the talent.
@spacedmonkey If you want to setup a meeting for a database team, that could work. Many component meetings have less than 5 people.
@flixos90 To clarify, this conversation is slightly different and mostly unrelated to the “unbundling Performance Lab plugin” effort. While we are publishing other PL modules as standalone plugins, those standalone plugins will still be directly associated with the performance team, developed in the monorepo, referenced from the PL main plugin etc. Removing / decoupling SQLite from PL would be different: We would still support getting the plugin towards WP core of course, but it wouldn’t be in any way connected to PL anymore. Maybe that was clear, but just in case.
Next steps clarification:
@aristath I think the only thing to do here would be to remove the module from PL, and add a notice so in case the user previously had the module activated, they’ll be prompted to install the standalone plugin
@joemcgill I assume we’ll remove the module from the performance lab plugin in the same release where we remove other modules. How we handle the transition so as to not break any active sites, is not clear to me at the moment.
@olliejones Do we have any usage telemetry to help guide that decision?
@flixos90 Potentially. As mentioned, I think this conversation is decoupled from the general PL unbundling effort, so we could do it at the same time, but also sooner. I would love to find a way to make the transition smooth though. For sites that already have the SQLite module active, we should probably recommend activating the SQLite plugin before deactivating the feature.
@flixos90 Has anyone tried yet to activate the SQLite standalone plugin on a site where the PL SQLite module is already active? We need to make sure it doesn’t throw fatal errors
@aristath Adding it on my TODO list for tomorrow, though from what I recall I tried it last month and I there were no issues. I’ll need to test that again just to be sure, it’s been a long time
@10upsimon I feel strongly about not intentionally breaking users sites, however few are using it. Perhaps we need to defer the removal to 2 versions from now, and raise a notice or similar in the adminadmin(and super admin) making it very clear that from version n it will no longer be supported as a core PL module.
@flixos90 agreed @10upsimon adding though that for a smooth transition the plugin should be activated before deactivating the PL module, so we have to make sure that that is actually possible
@joemcgill A similar transition plan will be good for all of the modules, to be honest, even though SQLite is the most critical due to potential breakage.
@flixos90@joemcgill I think for the other modules we’ll handle that in a central effort as part of unbundling, but with SQLite it will now be bit different, since that plugin will not be referenced directly from PL in the future. But I agree it’s most critical there to have a smooth transition since switching back to a MySQLMySQLMySQL is a relational database management system. A database is a structured collection of data where content, configuration and other options are stored. https://www.mysql.com/. / MariaDB database accidentally will break any site that actually relies on SQLite right now
@joemcgill This is a huge one that I had noticed in my profiling research, so nice to see this already addressed!
@10upsimon Call me cheesy, but 15% server time alone across many WP hosts is a positive contribution to the environment alone
@mukesh27 With all this improvement, 6.3 is faster than 6.2
@flixos90 Yeah, this alone will make blockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. theme performance in 6.3 almost as much faster as it got faster in 6.2
@flixos90 Certainly the highest performance improvement in a single PR that I’ve seen so far
@joemcgill Worth noting that the 15% improvement on that PR is compared against WP 6.1.1, not the commit prior to that one, so it would be interesting to A/B against the commit prior (if I’m reading the workflow correctly)
@flixos90 No, the 15% is against today’s trunk. The original metrics on the PR are incorrect, but then I measured it against trunk and that’s where the 15% come from
@olliejones I’ve been on the SQLite Object Cache, making it more useful for @spacedmonkey hopefully – Nothing on the bigger SQLite project.
@spacedmonkey Not related to database, but object caching. I have been working WP CLICLICommand Line Interface. Terminal (Bash) in Mac, Command Prompt in Windows, or WP-CLI for WordPress. support new functionality object cache
JavaScriptJavaScriptJavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. & CSSCSSCascading Style Sheets.
@10upsimon Regarding “Enhancing the WP Scripts APIAPIAn API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. with a Loading Strategy”:
We’ve had a good amount of feedback and iteration on our draft PR
We’ve had some valuable feedback come in this week, so we’ll be addressing that with the goal of opening a PR against core later this week. Thanks @joemcgill@adamsilverstein and @westonruter for the invaluable feedback thus far (and to @spacedmonkey)
We’ve established a mostly approved documentation plan/roadmap, with slight ongoing tweaks thereto. Draft documentation and documentation updates can commence soon
@flixos90 One more thing regarding JSJSJavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors. & CSS, last week I opened https://github.com/WordPress/gutenberg/issues/49927 to optimize how block CSS is loaded in classic themes (it’s great in block themes, but not so much for classic themes, and we can probably improve that). There have been some great conversations on that. @aristath has pointed out a detailed code example with how we could improve this by printing inline styles per block type right before the first block of each type is rendered
@aristath If you have some capacity to work on a PR, I think that would be a great next step
@flixos90 If we can find a solution that works reliably, maybe we can eventually even change the default behavior so that it’s no longer opt-in but just works out of the box
@joemcgill I’ve been working to prioritize a set of “next steps” for automated performance testing. For me, the “next step” is to turn these tasks into tracTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. tickets that we can address as capacity allows.
One of the big ones is to improve the stability of the results and make them more atomic, so we can use them to evaluate specific PRs (like the discussion we had earlier about the get_block_templates PR)
@joegrainger We’re still progressing through the issues raised in the Plugin Checker Milestone 1 Review/QA and will continue to be working on these over the coming weeks. You can follow the progress on the GitHub repo and any thoughts/ideas/comments are welcome. Thanks!
@flixos90 We’re still waiting to get the Fetchpriority standalone plugin approved, beyond that and then the same for Dominant Color, we have basically completed the work for “Milestone 1” in https://github.com/WordPress/performance/issues/656
@flixos90 Separately, we need to explore what we want the user experience for “Milestone 2” to look like, both in terms of the regular UIUIUser interface of the PL plugin going forward (in which it controls certain plugins as well as the Site Health modules), and for a smooth migrationMigrationMoving the code, database and media files for a website site from one server to another. Most typically done when changing hosting companies. from the modules to remove to their standalone plugins
My two focuses, get lazy loading metaMetaMeta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. across the line for term meta (working on comment meta) and implementing wp_cache_get_multiple in more places in coreCoreCore is the set of software required to run WordPress. The Core Development Team builds WordPress.
@aristath work continues in the SQLite project – as well as the php autoloader for wp-core
@joemcgill I’m just wrapping up an initial round of profiling observations, and plan to have something written up to share soon. Some highlights are that there are lots of places where we could try to reduce the use of file system reads associated with blockBlockBlock is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. registration and template rendering that we wanna look into. There is also a potential opportunity for some improvements to the way translations are being handled and classic seems that we also want to review.
@spacedmonkey already has some fixes in the works for some issues we discovered while comparing notes. I continue to be somewhat hampered by only being able to use one arm, but I’m working through it.
@rmccue As an aside, I noticed that the method of merging translationtranslationThe process (or result) of changing text, words, and display formatting to support another language. Also see localization, internationalization. files in memory is probably suboptimal and we might be able to avoid that. (I’ve been reimplementing pomo in native code, and noticed it there)
@olliejones Work continues on SQLite, next is to load woocommerce and beat on it.
Future project: identify as many places in core where the SQL is non-portable MySQLMySQLMySQL is a relational database management system. A database is a structured collection of data where content, configuration and other options are stored. https://www.mysql.com/. specific stuff and work on making it standard. Should that be a TRACTracAn open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress.ticketticketCreated for both bug reports and feature development on the bug tracker.?
@joemcgill I definitely think that having trac tickets that describe any improvements you’d like to see made would be useful.
JavaScriptJavaScriptJavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. & CSSCSSCascading Style Sheets.
@10upsimon We are addressing the issue(s) around script concatenation, work is in progress and in the final stages of review, with minor iterations ongoing. Unit tests are being implemented to validate the approach and should be ready for final review today or tomorrow.
We are entering into a more holistic/overall code review of work done to date, essentially a code review of all work done thus far as part of the epic. Minor iteration is anticipated as part of this review process and will be executed as required.
@flixos90 I have been continuing on the lazy-loading exploration and am getting close to opening Trac tickets for the individual pieces of work
To clarify, this is about avoiding to lazy-load LCP images, or rather in-viewport images in general
@flixos90 I have also been thinking a bit about the fetchpriority="high" feature for which we already have a module. One thing that we may need to iterate on there is that it just adds the attribute to whichever first image doesn’t have loading="lazy". This is not terrible, but it’s also probably not the best way to go about it, since the two attributes should not simply be mutually exclusive. The guidance is rather:
fetchpriority="high" should be only on the LCP image.
loading="lazy" should be omitted on images above the fold (i.e. potentially more images than just the LCP image).
@joemcgill I am in the very early stages of looking into ways we can improve the way WordPress calculates the sizes attribute.
@joegrainger We have 2 tasks remaining for the PluginPluginA plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party Checker infrastructure with plans to complete this week. Once done, we will start performing initial testing and review the infrastructure holistically before working on the additional checks. Progress can be seen on the GitHub repo here. As always, feel free to take a look and leave any thoughts/ideas you may have in the repo. Thanks!
@spacedmonkey Just flagging, I want to get the core unit tests running against redis. In my research, more hosts are using redis then memcache, so we could test against this and change our thinking of object caching in WP space from memcache to redis https://core.trac.wordpress.org/ticket/58000
@olliejones fwiw the SQlite Object Cache plugin has extensive perf. instrumentation built in.
Open Floor
@rmccue Re SQLite, I’m moderately concerned about the potential performance impact that introducing another layer of abstraction may introduce there. A traditional reason that WP hasn’t been DB-independent is because of (theoretical) performance gains by tightly coupling the two and taking advantage of that. (Which are assumptions I think do need to be tested.) I realise I’m coming in late to this, but I guess I’m just not seeing how the SQLite work ties into performance specifically. (I see a clear case for the non-performance benefits.)
@aristath Well, I admit that the tie between SQLite and performance is a bit weird… but the way I see it, it comes down to this: on a small, lower-end server, the server’s resources are shared between a php server, apacheApacheApache is the most widely used web server software. Developed and maintained by Apache Software Foundation. Apache is an Open Source software available for free., and a MySQL server. By using SQLite, the server can allocate its limited resources to php and therefore achieve better performance. It’s better for sustainability mostly, and for performance on smaller sites (that usually are hosted on cheap servers) the performance gains will be there
@rmccue I can see how eliminating the latency and translation between two separate servers for PHPPHPThe web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher and MySQL could help performance, not sure of the overhead if it’s on the same server; that said, it feels like the primary goals of the project are not performance related
@olliejones It might ??? be a good idea sometime to spin off a team to do dbms-independence work, the target of which would be support for SQL Server, postgreSQL, SQLite, and, gag, Oracle. Having those would help scale up WordPress sites. postgreSQL especially because it can do wildcard searches with indexes. But that imaginary project’s connection to this team is a bit tenuous, as you mention.
Discussions here continued beyond the end of the meeting