rainlab/translate-plugin

Bad Performance with collection of data

tombien opened this issue · 4 comments

Hello,
I have a translatable model.
I have a JSON response with about 150 items of this model.
There is a very big difference in response time (1sec in default language vs 9sec where site is in another language).

For example:

function onGetProducts() {

    $tests = Product::select('id', 'code', 'name', 'description')->take(100)->get();

    return Response::json($tests);
}

Product is a model implementing RainLab.Translate.Behaviors.TranslatableModel

I call this function by ajax. When site is on default language //example.cz/cs/products - it takes about 1 sec.
On //example.cz/en/products - it takes about 8-10sec.

I tested it for only 10 items and it is 500ms vs 1,4s. I think this is a noticeable difference in performance, when using this plugin.

This looks like it could be related to the n+1 query problem. It is overcome in Laravel using eager loading. This is where the code uses the with method to eager load the relations.

$tests = Product::with('translations')->select('id', 'code', 'name', 'description')->take(100)->get();

Alternatively, you can do this "after the fact" using the loadMissing method.

$tests = Product::select('id', 'code', 'name', 'description')->take(100)->get();

$tests->loadMissing('translations');

return Response::json($tests);

I hope this helps.

@daftspunk - thank you very much, it helps. Is this a standard approach to translatable data collection (for me to keep on mind for future) or you will make some changes in plugin?

No problem. This is the standard approach; Laravel wants us to be explicit about the queries. The n+1 problem is something to always be mindful of when working with models and their relationships. In this case, the translate plugin stores its translated messages as a relation, so it is important to be mindful of that.