Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a bind-translate directive #72

Open
gunta opened this issue Jun 16, 2014 · 10 comments
Open

Add a bind-translate directive #72

gunta opened this issue Jun 16, 2014 · 10 comments

Comments

@gunta
Copy link

gunta commented Jun 16, 2014

Hi!

I'm creating a big application with lot's of translated data where performance is suffering, so while debugging the bottlenecks with Batarang I found that it would be required to have a bind-translated directive.

Why?

Visibility:
While AngularJS is bootstrapping, the user might see your placed brackets in the html. This can be handled with ng-cloak. But for me this is a workaround, that I don't need to use, if I use ng-bind.

Performance:
The {{}} is much slower.
This ng-bind is a directive and will place a watcher on the passed variable. So the ng-bind will only apply, when the passed value does actually change.

The brackets on the other hand will be dirty checked and refreshed in every $digest, even if it's not necessary.

In my experiments, changing from {{}} to strict ng-bind saves around 20~40% in every scope.$digest.

Suggestion:

Use a directive instead of the brackets annotation.
Instead of

{{'Hello'|translate}}

use↓

 <span bind-translate="Hello"></span>

For example angular-translate does this with the directive ng-translate.

@rubenv
Copy link
Owner

rubenv commented Jun 16, 2014

This is interesting. How does ng-bind work if it doesn't do dirty-checks?

@rubenv
Copy link
Owner

rubenv commented Jun 16, 2014

Looking at the source of ng-bind, it appears that it uses $scope.$watch, so it will use exactly the same dirty-checking mechanism.

In theory this means there shouldn't be a difference. Do you have an example of this speed difference?

@gunta
Copy link
Author

gunta commented Jun 16, 2014

The final dirty checking code is the same, however the differences are:

  1. Filters are very expensive and set up too many watch expressions.
  2. Parsing the string {{}} takes time.
  3. The ng-cloak problem.

So the biggest performance difference comes from using filters vs. using directives.
See here.

@rubenv
Copy link
Owner

rubenv commented Jun 16, 2014

The page you linked to says nothing about performance. Seems like your issue is based on this, which also doesn't list any verifiable numbers (so it's worthless).

As a general principle, I don't accept any arguments about performance unless they're backed up by numbers (which can be validated).

I can see (intuitively) where the difference comes from, but unless we have measurable numbers, it's just feelings and speculation. It's not worth adding extra functionality if the difference is negligible.

You said you did some tests and measurements, can you share them?

@rubenv
Copy link
Owner

rubenv commented Jun 16, 2014

Also, not that you don't have to use filters, you can just do this:

<span translate>Hello</span>

@gunta
Copy link
Author

gunta commented Jun 17, 2014

The numbers I got were from Batarang, but since it's not a reliable source (it might just be the difference of filters vs directives, or some random stuff).
I'll try to make some jsperf tests.

@gunta
Copy link
Author

gunta commented Jun 19, 2014

Ok, before discuss the performance details,
let's solve the obvious penalty of using directives vs. filters.

Given the following use cases:

  1. Directive with brackets: Doesn't work
<button translate>
    {{ someText }}
</button>
  1. Directive with bind: Doesn't work
<button ng-bind="someText" translate>
</button>
  1. Filter with brackets: Works
<button>
    {{ someText | translate }}
</button>
  1. Filter with bind: Works
<button ng-bind="someText | translate">
</button>
  1. Directive including bind: Ideal
<button translate="someText">
</button>

Note: someText is a variable which has already been gettext'd in the controller.

One wouldn't really expect case 1) to work, but 2) can be expected.
And 5) is the most concise one.

If 2) or 5) are implemented, it will solve the biggest performance (and usability) factor.

@michi88
Copy link

michi88 commented Jul 22, 2014

+1 for translate="someText". I've also encountered this issue and I'm ng-cloaking stuff now. Works but I think this would be a nice feature.

Nice project BTW!

@elemoine
Copy link

@gunta, interested to know if you're still considering adding some like bind-translate to angular-gettext?

@gabegorelick
Copy link
Collaborator

Please take a look at #141. I have no problem supporting translate="foo" for convenience or to prevent flickering. But the linked PR currently won't fix what I consider the main source of flicker: when you transition from en to the real language. Not sure how to address that. Also, please post performance numbers if you have them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants