[wp-trac] [WordPress Trac] #41305: Add lazily evaluated translations
WordPress Trac
noreply at wordpress.org
Mon Apr 30 07:40:33 UTC 2018
#41305: Add lazily evaluated translations
-----------------------------+------------------------------------
Reporter: schlessera | Owner: jnylen0
Type: enhancement | Status: assigned
Priority: normal | Milestone: Future Release
Component: I18N | Version: 4.8
Severity: normal | Resolution:
Keywords: has-patch early | Focuses: rest-api, performance
-----------------------------+------------------------------------
Comment (by schlessera):
As a follow-up to the discussions I had with some of the core folks at
WCUS, I produced a new patch
[https://core.trac.wordpress.org/attachment/ticket/41305/41305.all-in.diff
41305.all-in.diff] that skips producing alternate translation functions,
and immediately changes the default translation functions to return
lazily-translated proxies instead.
== Why not to play it safe (as the first patch does)?
The reasoning behind this is that this change has such a big impact on
performance that we shouldn't start with a compromise that only makes it
opt-in. We should properly investigate the expected amount of problems
this might cause to plugins and mitigate any breakage to the best of our
abilities, as this will benefit all WordPress users in a substantial way
in the long term. The discussions at WCUS led to the conclusion that these
are probably only edge cases and that the change is important enough to
warrant contacting a few plugin authors that might be impacted.
I added some minimal edge case handling code to make sure unit tests still
pass and plugins would just work. However, right now, there are still 7
unit tests that are breaking. For these, I think the unit tests might need
to be adapted instead, though.
== What are the breaking changes?
The translations are not real strings anymore, but proxy objects that
behave like strings whenever being cast to a string (like when being
echoed, concatenated, etc...). For most of the intended usage of
translations (sending them to templates to get rendered into HTML
responses), this just works without issues. However, three scenarios can
cause issues with this:
**1. Directly checking the type of the translation**
This mainly happens in unit tests. That's why I created an override in the
`WP_Unit_TestCase` for the `assertEquals()`, `assertSame()` and
`assertInternalType()` methods. Creating such overrides also fixes
breaking tests for any plugins that base their tests on `WP_UnitTestCase `
without needing further adaptations.
**2. Using the translation as an array index**
This is actually done by Core in places like the locale setup. I think
that there are not that many use cases for doing so, as you'd prefer
deterministic indexes most of the time. The solution to this is to just
cast to `(string)` before actually using the translation as the index.
**3. Making the result of the translation dependent on the timing of its
instantiation, instead of its usage**
I would be surprised to learn that plugins would ever use translations in
this way. However, Core unit tests currently do, and this also includes
the 7 unit tests that are currently still failing.
The failing unit tests do something like this: `add_filter(), __(),
remove_filter(), assert()`. So, they immediately remove the change they
want to test before asserting. They are all part of the
`Tests_L10n_loadTextdomainJustInTime` suite, and I'm not sure they need
fixing. If I understand correctly what they are testing, I think the tests
should just be adapted to move the `remove_filter()` calls after the
`assert()` instead of in front of it. I would love to get more insight
into this from @ocean90 & @swissspidy, as I think they had collaborated on
this feature & tests.
== Current results
What follows is a couple of screenshots to show the current results. The
tests were done as a call to `<domain>/wp-json/wp/v2/posts/1` to retrieve
the JSON representation of the `Hello World` default post. They have been
produced on my local system running PHP 7.1.17 with `xdebug` enabled. I
kept `xdebug` enabled because it makes everything slower, so the change is
more obvious. The setup was a fresh and default WP setup with `fr_FR` as
frontend language and `de_DE` as user language.
Also, please note that the screenshots represent 1 random run, chosen to
be somewhat representative. I will add real benchmark results (with
averaged values) as soon as I manage to properly configure my system to
run them again, as I had to find out this currently does not work.
**Wall time without this patch: ~1.6s**
**Wall time with this patch: ~1.1s**
You can also see that the query time is practically unchanged, so this is
pure processing logic to make the translations happen (which are not even
being used in this case).
--
Ticket URL: <https://core.trac.wordpress.org/ticket/41305#comment:18>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list