The gettext filter is a really handy filter that I’ve written about before. The filter provides a way to easily change international-ready text via a simple filter call, but it can also have a serious impact on performance if overused.
For the last several weeks one of my client sites has been having some serious server problems. The site in question has really large amount of traffic and runs on an extremely beefy Rackspace server, one that should be able to handle the traffic without any trouble.
To give an idea of the sort of problems this server was having, here are a few highlights:
- It would go down at least once per day
- Response times averaged around 1200 – 2400ms per request
- In NewRelic (a server monitoring app), the site has almost never seen anything but red
Tonight we finally discovered the source of our problems: a huge number gettext filter calls.
We had been using a string-swap plugin to modify some front-end strings, and usually these kind of plugins don’t cause any significant issues, since it is just a few strings that are usually being changed. What we had failed to realize was that this particular plugin was setup in such a way that nearly every single localized string on the site was being filtered. This was thousands and thousands of text strings.
When modifying a few text strings, the performance impact can be quite minimal, but when accidentally modifying thousands upon thousands, the impact can be disastrous. See the server response time graph below for proof:
[lightbox link=”https://pippinsplugins.com/wp-content/uploads/2013/11/Screenshot-from-2013-11-08-222413.png” thumb=”https://pippinsplugins.com/wp-content/uploads/2013/11/Screenshot-from-2013-11-08-222413.png” width=”511″ align=”none” title=”Screenshot from 2013-11-08 22:24:13″ frame=”true” icon=”image”]
It should be very apparent when the offending plugin was disabled.
16 thoughts so far
Have your say
Would be interesting to know which the offending plugin is. Not to point fingers, but to warn other users and to give the plugin author the chance to improve on the code.
The article as it is now, doesn’t make too much sense, imo.
He chose to not reveal it as he wanted the plugin developer to have a chance to fix it 🙂
Well, it’s a warning for other plugin devs who follow Pippin’s blog. I think Pippin probably reached out to the specific plugin devs in private.
Once the developer has had a chance to look into it I will post more details here.
Out of interest, how did you pin-point the problem. Was it through using some of the tools included with NewRelic, or did you use some other profiling tools?
We discovered it from error logs. I don’t know why, but the plugin had not been throwing errors for the last few months, then suddenly it started throwing a lot. I think the errors were suppressed.
You’ve left me confused, too. I can’t tell if the problem is specific to that plug-in or a generalised problem with get_text.
I’m not sure what you mean by “nearly every single localized string on the site was being filtered” because surely every localized string is being filtered, that’s the point.
Unless you mean text was being filtered even on pages where it is not being displayed or something?
The point is that gettext can be catastrophic if used inappropriately. When I said every string was being filtered, I don’t just meant that every string was passed through gettext (as that’s the point), I mean that every string was having “work” done on it by the plugin. At least that’s the best I’ve been able to determine now. Once I’ve worked with the developer to resolve the plugin issues, I’ll post an update here in case anything above was incorrect.
So what’s the solution? WP tells devs to wrap all text in
__()and the other translator functions.
I recently removed a call to
apply_filtersfrom a loop and it decreased the load time of a plugin by .2 seconds. Since
__x(), etc. use the
gettextfilter, maybe it’s the
apply_filtersitself that’s the problem?
Making strings ready for translation definitely adds some load time to the site, though it is a necessary evil.
The apply_filters() function will not introduce additional load unless there is another function tying into the filter that is resulting in the slow down.
Thanks for the link!
Sorry, Pippin, making strings ready for translation is NOT a “necessary evil”, absolutely not. It rather is a MUST if your plugin/ theme/ whatever should be ready for international usage. And it should be, as the non-English installs of WordPress grow and grow (for years already). Soon, there will be a time when the downloads of default WordPress package will be quite lower than all downloads of localized versions of WordPress (containing the translations of a users specific language)
To improve the translations management is a task for WordPress core – and of course there’s great room for improvement in that field. Over the years, a lot of WordPress developers & contributors, especially from Europe, did research, testing and also quite some patches. Still, only few of them did find their way into core. In my opinion, that’s a shame. Around the time of WP 3.0-3.2 a WP dev from Austria did extensive testing, only to find out that a localized version of WordPress is 44% slower. Not much has changed since then (if ever!). We are punished for nothing only because we’re running WordPress (and Themes and Plugins) in our own language.
Translation loading performance seems not a priority for WordPress core devs – but it should, considering the huge growth of non-English WordPress installs. And those installs all are directly effected by that whole, complex field within WordPress ecosystem!
Dave from Germany 🙂
Sorry, that made it sound way worse than I intended it.
What I meant is that localizing text strings is extremely important. Yes it does cause an impact on performance, but it is far more important for the text strings to be localized than the extra small bit of performance that would be attained by not localizing them.
Sorry, if I misunderstood you! Thanks for clarifying, I fully agree with your last statement! 🙂
I ran some tests and was going to post the numbers here, but it was too much, so I wrote a blog post about it.
Maybe the post misses the point, though: translation is the heavy item, not the functions!
Thanks for doing that! You seem to be one of the few from USA who are doing such things!
It is really important for us all so our eyes are opened to that issues, regarding performance & translations in WordPress.
To avoid the translation functions __(), _e() etc. is NOT a solution. Please don’t do that. Rather make your plugins/ themes even better compatible with the WordPress translation APIs.
There is room for improvement for POMO handling within WordPress core.
Judging from what was said during the last WordCamp Europe, I think the WordPress leads are very much aware of the importance of localization and are taking important steps to improve things.
Comments are closed.
Leave a reply
Join the discussion