Open n1k0 opened 10 years ago
ping ;)
Ooops, pong.
I’m not sure yet I want webL10n to rely on mutation observers, but I can think of a quick function for that.
@fabi1cazenave by a quick function, I'm assuming you mean an imperative mechanism to apply localization instead of on DOM getting ready.
Is such a function present in the current API?
Looks like I found it:
document.webL10n.translate(element)
does the trick for me
for a single page application with a lot of DOM changes though, webL10n does not truly give declarative localization. Mutation Observers may be the answer.
@n1k0 this works for me:
_
- lodash
document.addEventListener('localized', function() {
var observer = new MutationObserver(function(mutations) {
_.forEach(_.pluck(mutations, 'target'), function(element) {
document.webL10n.translate(element);
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
Another variant that I tried:
document.addEventListener('localized', function() {
var translate = function() {
document.webL10n.translate();
};
var observer = new MutationObserver(function(mutations) {
_.debounce(translate, 250)();
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
From some rudimentary profiling it seemed like the first variant performed slightly better. Also, there is a slight delay in translation with the second variant.
@fabi1cazenave or @Rob--W if this doesn't hurt performance too much, I can submit a PR with this change (a modified version that does not use lodash). And maybe a config variable can be used to turn this on so that its an optin feature?
@gazal-k I'd not take such a PR because it would hurt performance in large applications.
FWIW, there are some implementation flaws in your snippet:
debounce
doesn't work, because you're creating a new debounced function at each call. At the very least the function created by _.debounce
should be stored outside the MO callback.Actually I did test both snippets in an application.
The first one does trigger the MO callback an extra time after the translation, but a subsequent call to translate does not modify the DOM, hence no more MO callback.
You're right about the debounce function on the second snippet. I'd originally written and tested it using polymer framework's debounce method which works a little differently from how lodash's works. So, the second snippet can be modified as:
document.addEventListener('localized', function() {
var translate = _.debounce(document.webL10n.translate, 250);
var observer = new MutationObserver(function(mutations) {
translate();
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
The profiling results seemed to indicate that MutationObservers are pretty fast. I might be able to tweak the first snippet further to filter just new non-text nodes and apply weL10n.translate on those. Will have to see whether more calls to translate with smaller sections of DOM or fewer calls with larger sections are faster.
@Rob--W what would you recommend for single page apps?
I'm trying to make this work in an application built using https://github.com/Polymer/polymer/. So another approach I can think of is to leverage polymer's behaviors feature to use the imperative API document.webL10n.get
in a template function, hence making it available in a more or less declarative way.
The profiling results seemed to indicate that MutationObservers are pretty fast.
Using documents of which complexity? What is "pretty fast"? My experience with permanent MOs and looking for elements (at document load, so when new nodes are being added) in the full subtree is that there are documents where the lot of DOM changes add 10-25% to the load time, and a significant increase in peak memory usage (900MB->2.2GB on http://dromaeo.com/?dom-mod, plus seconds freezing due to garbage collection). This is not a problem with mutation observers, but with using mutation observers on the whole document and reading properties of the mutations (many of these properties are lazily initialized, at least by Chrome).
@Rob--W what would you recommend for single page apps?
I have no definite recommendation, because I haven't found a library yet with which I was completely satisfied.
I'm trying to make this work in an application built using https://github.com/Polymer/polymer/. So another approach I can think of is to leverage polymer's behaviors feature to use the imperative API document.webL10n.get in a template function, hence making it available in a more or less declarative way.
If you use Polymer or web components, you could indeed use element creation / attribute change callbacks to detect a new item for translation.
:+1:
Right now when new elements are added using
data-l10n
attributes, they're not translated live. Using Mutation Observers may solve the issue and bring a nice feature to the lib.