[wp-trac] [WordPress Trac] #41305: Add lazily evaluated translations

WordPress Trac noreply at wordpress.org
Thu Jul 13 11:16:57 UTC 2017


#41305: Add lazily evaluated translations
-------------------------+-----------------------------
 Reporter:  schlessera   |      Owner:
     Type:  enhancement  |     Status:  new
 Priority:  normal       |  Milestone:  Awaiting Review
Component:  I18N         |    Version:  4.8
 Severity:  normal       |   Keywords:
  Focuses:  performance  |
-------------------------+-----------------------------
 In the context of #40988, I did a few performance tests and experimented
 with adding a lazily evaluated translation object.

 The general principle is this:

 Instead of returning the resulting string of a translation, return an
 object for which the `__toString()` and `jsonSerialize()` methods will
 fetch the resulting string instead.

 I tested by having the `__()` method return such a proxy object, instead
 of the actual translated string.

 From a quick profiling run on `wptrunk.dev/wp-json/wp/v2/posts`, I got the
 following results:

 Returning a `translate()` from `__()`:

 {{{
 Wall Time     162ms
 CPU Time      157ms
 I/O Time     5.48ms
 Memory       16.5MB
 Network         n/a     n/a     n/a
 SQL          4.41ms    13rq
 }}}

 Returning a `TranslationProxy` from `__()`:

 {{{
 Wall Time     144ms   -19ms  -14.9%
 CPU  Time     138ms   -18ms  -15.4%
 I/O  Time    5.33ms  -154µs   -3.0%
 Memory       16.6MB +81.6KB     n/s
 Network         n/a     n/a     n/a
 SQL          4.33ms    13rq
 }}}

 As you can see, this shaved off almost 15% from this simple request.

 It saved 2255 calls to `translate()`, 2157 calls to
 `get_translations_for_domain()` and, more importantly still, 2156 calls to
 `apply_filters()` (which could involve a lot of additional processing in
 some cases).

 The main problem with this approach is that WordPress does not contain
 real type-hinting, so BC is broken wherever the proxy is not echoed, but
 used directly.

 As we cannot possibly foresee how plugins might use their localized
 strings, I suggest adding new lazy variations of the translation
 functions. To mirror the "echo" variations that prefix the translation
 functions with an `e`, I'd suggest using the `l` prefix for these
 variations:

 {{{#!php
 // Lazily retrieve the translation of $text.
 _l( $text , $domain = 'default' );

 // Lazily retrieve the translation of $text and escape it for safe use in
 an attribute.
 esc_attr_l( $text, $domain = 'default' );

 // Lazily retrieve the translation of $text and escape it for safe use in
 HTML output.
 esc_html_l( $text, $domain = 'default' );

 // Lazily retrieve translated string with gettext context.
 _lx( $text, $context, $domain = 'default' );

 // Lazily translate string with gettext context, and escape it for safe
 use in an attribute.
 esc_attr_lx( $text, $context, $domain = 'default' );

 // Lazily translate string with gettext context, and escape it for safe
 use in HTML output.
 esc_html_lx( $text, $context, $domain = 'default' );
 }}}

 Arbitrary testing has shown that using such lazily evaluated translations
 strategically can improve the performance by 10-30% for certain scenarios.

 Implementing them in this BC fashion allows us to fine-tune Core usage and
 make it available to plugins, while playing it safe with existing code.

--
Ticket URL: <https://core.trac.wordpress.org/ticket/41305>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list