[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