In this major-minor update, we improved browser performance by up to 99% (not a typo) by exchanging over 300 jQuery calls for vanilla JS ones. We also added two new options for oEmbed, freed a dozen bugs that got stuck in the UI and generators, and improved accessibility.
Detailed log
> View code changes.
> View closed issues.
For everyone
- Added:
- New oEmbed settings:
- You can now choose whether to overwrite the oEmbed title with the SEO meta title (when manually filled).
- You can now choose to use the social image instead of the featured image.
- This can only work when you use the image uploader instead of manually filling in the URL.
- New oEmbed settings:
- Improved:
- Accessibility:
- On the SEO Settings screen, the taxonomy settings inferred robots (index/follow/archive) state is now conveyed when all its connected post types were checked.
- You won’t see a duplicated
[?]
notifier when you disable a post type or taxonomy–the most restricting option will convey its message. Another nice touch that you’ll probably never notice is there.
- You won’t see a duplicated
- When you downgrade to this version, or henceforth to a higher version (from an even higher version), you’ll now see a persistent one-time notification that informs you of a completed downgrade.
- On the SEO Settings screen, the taxonomy settings inferred robots (index/follow/archive) state is now conveyed when all its connected post types were checked.
- Compatibility:
- WooCommerce’s product category widget now evaluates TSF’s primary term selection.
- Performance:
- Up to 99% quicker browser rendering times and interaction (admin-area):
- Yes, 99%; because there’s a cache pollution bug in jQuery (in combination with Safari’s WebKit) we no longer interact with.
- We exchanged jQuery event handlers for native JS in various places, improving browser load time drastically (even further than v4.1.0 did).
- This also improves compatibility with non-jQuery driven APIs.
- We exchanged jQuery NodeList handlers for native JS in various places, improving browser load time drastically.
- This also resolves an issue where jQuery’s cache was polluted for unknown reasons (good luck debugging jQuery’s code), in combination with ACF Pro’s Flexible Content types, where the browser could hang for several minutes.
- We reduced the number of events marginally by exempting hidden fields from change listeners.
- Up to 0.2% faster server response times (admin and front):
- We looked at the PHP engine’s code and found that we could reduce the number of opcodes (CPU instructions) by adding backslashes to various internal PHP functions.
- 0.2% isn’t much. We spent (wasted) 14 hours on that. However, sometimes scrutiny really pays off, as was shown with the 4.0 and 4.1 releases.
- Nevertheless, we believe this will translate well into the PHP 8.0 release, especially on servers where the upcoming JIT compiler is implemented.
- We looked at the PHP engine’s code and found that we could reduce the number of opcodes (CPU instructions) by adding backslashes to various internal PHP functions.
- Up to 71% less memory consumption for the sitemap:
- When you don’t use an object caching plugin, the sitemap generator now clears the post’s memoized cache after each URL entry yielded.
- Up to 99% quicker browser rendering times and interaction (admin-area):
- Accessibility:
- Fixed:
- Past tense is easier to read and write than future tense; so, we now start with “Addressed an issue where…”
- Bugs introduced in v4.1.0:
- Generators:
- Addressed an issue where some byte sequences are improperly transformed on some PHP installations, that caused a malformed output of description and titles.
- Addressed an issue where on the SEO Settings screen, the blog name affix was not properly removed from the generated Homepage social titles when the related option is toggled.
- Upgrade:
- Addressed an issue where the
post_format
,category
, andtag
taxonomy robot’s settingsnoindex
,nofollow
andnoarchive
were accidentally asserted as activated when the site upgraded to4103
(TSF v4.1.0).- This issue rectified itself after the user saves the options once. This was caused by checking for “is set” (either 1 or 0 means enabled) instead of “is empty” (only 1 means enabled).
- This fix is applied both pro-and retroactively.
- Addressed an issue where the
- Generators:
- Bugs from earlier versions:
- Generators:
- Addressed an issue where inline line breaks (
<br>
) didn’t add spaces for description/excerpt generation; but, instead voided them.
- Addressed an issue where inline line breaks (
- UI Bugs and annoyances:
- Addressed an issue where the “Are you sure you want to leave this page” notification popped up on the block editor even when you didn’t change any SEO meta values.
- Addressed an issue where on the SEO Settings screen the pixel counter display was toggled when deselecting the character counter options.
- Upgrade:
- Addressed an issue where the database version wouldn’t update correctly when using an object caching plugin, causing the upgrade-cycle to run twice.
- This is probably why some users informed us of newly introduced settings being flipped, or that users were unable to access the SEO settings page until this resolved itself after a few cycles.
- Addressed an issue where the
attachment
post type robot’s settingsnofollow
andnoarchive
were accidentally asserted as activated when the site upgraded to3103
(TSF v3.1.0). Most likely,noindex
, too–but it’s unlikely users allow indexing.- This issue rectified itself after the user saves the options once. This was caused by checking for “is set” (either 1 or 0 means enabled) instead of “is empty” (only 1 means enabled).
- This fix is applied both pro-and retroactively.
- Addressed an issue where the database version wouldn’t update correctly when using an object caching plugin, causing the upgrade-cycle to run twice.
- Generators:
- Other:
- Reduced the filesize of the
le.min.js
(list edit) script by minifying repeated patterns. - All other scripts have increased in size, since we now barely rely on jQuery. Vanilla JS tends to grow more code since there’s not a single function that does everything.
- Our scripts can no longer invoke “are you sure”-change listeners autonomously. You’ll have to input or change something to invoke that manually.
- We always thought that we could at some point make a vital input-change for you in the browser, but we never did, nor do we think we ever will. We handle sanitization on the server, which is much neater. Moreover, if we do make such a change, we have methods that set the warning programmatically.
- Reduced the filesize of the
For translators
- Added: New sentences are now available.
- Changed: At some places, we exchanged “disabled” for “excluded”, which conveys the new options section introduced in TSF v4.1.0 better.
- Updated: POT translation file.
For developers
- Datebase note: This plugin now uses TSF database version
4110
. - Upgrade notes:
- When upgrading the options, no longer are the defaults considered.
- For multisite network owners: This means that filter
the_seo_framework_default_site_options
is ignored for sites that upgrade. But, it’s honored for new sites. - We made this change because we can’t predict the future: will the new settings be maintained indefinitely? What happens when the defaults are no longer registered? It’s much easier for us to just set and migrate new options without considering the default options.
- This also makes the upgrader them less prone to unexpected value changes we didn’t (or couldn’t) consider. We had several reports of this happening.
- For multisite network owners: This means that filter
- Upgrade
3060
(\The_SEO_Framework\Bootstrap\_do_upgrade_3060
) was removed–nothing happened there but clearing the sitemap cache.
- When upgrading the options, no longer are the defaults considered.
- Option notes:
- Under
THE_SEO_FRAMEWORK_SITE_OPTIONS
:- Added:
oembed_use_og_title
, either1
or0
.oembed_use_social_image
, either1
or0
.
- Added:
- Under
- Changed:
- We no longer use custom error handlers, but rely on the system-provided ones, instead.
- This is more harmonious with plugins like Query Monitor, and doesn’t override custom error loggers.
- HTMLElement class
tsf-disabled-post-types
is nowtsf-excluded-post-types
; this gave us a headache. - HTMLElement class
tsf-disabled-taxonomies
is nowtsf-excluded-taxonomies
; this, too, gave us a headache.
- We no longer use custom error handlers, but rely on the system-provided ones, instead.
- Filter notes:
- Added:
the_seo_framework_sitemap_blog_lastmod
string, allows you to set a custom lastmod timestamp for the blog page.
- Added:
- PHP notes:
- Method notes:
- For facade object
the_seo_framework()
:- Changed:
s_singleline()
:- Now uses real bytes, instead of sequences (causing uneven transformations, plausibly emptying content).
- No longer transforms horizontal tabs (this was added in 4.1.0, which we shouldn’t have). Use
s_tabs()
instead.
s_tabs()
now uses real bytes, instead of sequences (causing uneven transformations, plausibly emptying content).strip_tags_cs()
can now replace void elements with spaces when so inclined via the arguments (space vs clear).- Note that “clear” runs before “space”. Mind your duplicates.
is_post_type_robots_set()
now tests for not empty, instead of isset.is_taxonomy_robots_set()
now tests for not empty, instead of isset.get_image_generation_params()
now only the ‘social’ context will fetch images from the content (by default).- This affects the Articles extension, among other implementations.
- Within TSF, we use ‘social’ and (since this update, also) ‘oembed’.
- Changed:
- For object
\The_SEO_Framework\Bridges\Sitemap
:- Method
get_freed_memory()
is now available.
- Method
- For object
The_SEO_Framework\Interpreters\SeoBar
:- Method
collect_seo_bar_items()
is now static.- It should’ve been from the beginning. You can only access this method statically, anyway.
- Method
- For object
The_SEO_Framework\Builders\Sitemap
:- Protected method
create_xml_entry()
is now available.- We wanted to use
create_xml()
, but that was reserved in our Articles extension as a private member function–we required protected or lower (hindsight is 2020, and 2020 sucks).
- We wanted to use
- Protected method
- For object
The_SEO_Framework\Interpreters\SeoBar
:- Method
collect_seo_bar_items()
is now static.- It should’ve been from the beginning. You can only access this method statically, anyway.
- Method
- For facade object
- Action notes:
- Added:
the_seo_framework_sitemap_transient_cleared
, useful when you want to preemptively cache the sitemap before pinging.- For more details, see issue #540.
the_seo_framework_before_ping_search_engines
, useful when you want to redirect the pinger.
- Added:
- Performance:
- We now use fully qualified function names for pre-evaluated functions, where these functions are registered as opcodes from PHP 7.0 onward. This means that fewer CPU cycles are required every time we call such a function. In layman’s terms: you can see a 10~30% performance increase in some scenarios.
- Translated to this plugin, it’s about 0.1 ms improvement at most. That’s a 0.02% improvement on a clean WP install or about 0.2% of the plugin.
- Totally negligible. But, that’s probably because we optimized for opcodes in the past. We believe we’re in the 10% improvement range (of the total plugin load time) already, thanks to consistently optimizing this.
- We also created a PHPCS sniff for this.
- Translated to this plugin, it’s about 0.1 ms improvement at most. That’s a 0.02% improvement on a clean WP install or about 0.2% of the plugin.
- We now use fully qualified function names for pre-evaluated functions, where these functions are registered as opcodes from PHP 7.0 onward. This means that fewer CPU cycles are required every time we call such a function. In layman’s terms: you can see a 10~30% performance increase in some scenarios.
- Method notes:
- JS notes:
- Note: Only changes affecting the API are listed. “We improved performance,” and the like are exempted from this list.
- Object notes:
- Added:
tsfAys.areSettingsChanged()
, a clone oftsfAys.getChangedState()
with a better conveying meaning.
- Changed:
tsfAys.reset()
now debounces reloading of the listeners.tsfTitle.enqueueTriggerInput()
now accepts a first parameter, id; which is in line with thetsfDescription
object.
- Fixed:
tsfDescription.enqueueTriggerInput()
now passes the input ID to the input event.
- Added:
- Event notes:
- Added:
document.body.tsf-interactive
, used to indicate that TSF is interactive.- We required this to register the “Are you sure” script as late as possible, where all other scripts are sequenced before this point.
- Unfortunately, we still don’t honor this correctly since we debounce some interactions.
document.tsf-gutenberg-onsave-completed
, runs after Gutenberg/Block Editor is done saving.$window.tsf-post-type-robots-changed
, used to test for post type robots change states.$window.tsf-taxonomy-robots-change
, used to test for taxonomy robots change states.
- Changed:
tsf-gutenberg-saved-document
no longer supplies a second parameter for the event type. Instead, you can now find it inevent.detail.savedType
.tsf-title-sep-updated
no longer supplies a second parameter for the event type. Instead, you can now find it inevent.detail.separator
.- You can now use native JS event handlers on these events:
- document:
tsf-gutenberg-onpreview
- document:
tsf-gutenberg-onautosave
- document:
tsf-gutenberg-onsave
- document:
tsf-gutenberg-sidebar-opened
- document:
tsf-gutenberg-sidebar-closed
- document:
tsf-subscribed-to-gutenberg
- any description element:
tsf-update-description-counter
- any title element:
tsf-update-title-counter
- window:
tsf-title-sep-updated
- document:
- Fixed:
- window:
tsf-counter-updated
now works.
- window:
- Other:
- Because we used named event types with jQuery, we masked a few design flaws that came painfully apparent after we moved away from jQuery.
- Luckily, by trying the
isTrusted
event parameter, we can mitigate this flaw, and toggling its check allowed us to find and fix a few dependency errors where our logic was flawed.
- Luckily, by trying the
- Because we used named event types with jQuery, we masked a few design flaws that came painfully apparent after we moved away from jQuery.
- Added:
- Template notes:
wp.template( 'tsf-robots-pt-help' )
is now available on the settings page.
- Fixed:
- Two mistakes got through our error handler during development. If it can happen once, it can happen again. So, we reworked the error handler akin to WordPress’s, so that it’ll allow custom handlers to catch these errors and scream at us–instead of them being silently outputted by TSF.
- Now, WordPress controls whether errors should be displayed.
- Unchanged: Only when WordPress allows debugging, errors are handled. This means that no errors can be or could’ve been shown on websites in production.
- The freed memory value is now correctly populated for the sitemap.
- Two mistakes got through our error handler during development. If it can happen once, it can happen again. So, we reworked the error handler akin to WordPress’s, so that it’ll allow custom handlers to catch these errors and scream at us–instead of them being silently outputted by TSF.