I need to make this jquery run much faster, I did not create all of these functions, but need their methods, to do live translations of page content.
So I would appreciate any suggestions to refactor for better performance, the code below.
/* function 1 read json into array */
/* function 2 loop through array */
/* function 3 replace text nodes based on data from looped array */
var en_lang = new Array();
var fr_lang = new Array();
var frca_lang = new Array();
var my_data = null;
var en_count = 1;
var fr_count = 1;
var frca_count = 1;
if(typeof(language) != "undefined"){
var language = 'frca';
}
function replaceText(oldText, newText, node){
node = node || document.body; // base node
var childs = node.childNodes, i = 0;
while(node = childs[i]){
if (node.nodeType == 3){ // text node found, do the replacement
if (node.textContent) {
node.textContent = node.textContent.replace(oldText, newText);
} else { // support to IE
node.nodeValue = node.nodeValue.replace(oldText, newText);
}
} else { // not a text mode, look forward
replaceText(oldText, newText, node);
}
i++;
}
}
function parsejSON(my_data) {
/* THIS PART GRABS DATA FROM TOP OF JSON FILE */
/* grab recordcount */
var recordcount = my_data.recordcount;
/* grab columnlist */
var columnlist = my_data.columnlist;
/* grab json data */
var json_data = my_data.data;
/* PUTS JSON DATA INTO ARRAYS */
for(var x = 0; x < recordcount; x++) {
var lng = json_data.lng[x];
var phrase = json_data.phrase[x];
if (lng == 'french') {
fr_lang[fr_count] = phrase;
fr_count = fr_count + 1;
}
if (lng == 'french canadian') {
frca_lang[frca_count] = phrase;
frca_count = frca_count + 1;
}
if (lng == 'english') {
en_lang[en_count] = phrase;
en_count = en_count + 1;
}
}
/* use a replacetext function above to replace all text */
for(var x = 0; x < en_lang.length; x++) {
var from = en_lang[x];
if (language == 'fr') {
var to = fr_lang[x];
}
if (language == 'frca') {
var to = frca_lang[x];
}
replaceText(from, to);
}
}
Sorry, not quite sure how to get the code posting, formatted correctly, feel free to edit my post in that situation..
Thank you.
By examining your code I can tell you that your most overhead is created in replaceText function. For every text item, your code walks again and again through the whole DOM structure. Instead of doing this in one go, code goes through document
en_lang.lengthnumbers of times. Node manipulation is much slower then JavaScript code, so if you have a lot of items in your en_lang array and document structure is complex the rendering time can grow drastically. By doing the replacement of all text items in one loop would save a lot of time.Second. I can see, that on every node you perform assigning operation.
node.textContent = node.textContent.replace(oldText, newText);This operation is overkill if your node does not contain any match information. By doing DOM assignment only where it’s needed, you save yourself another ms of rendering time.
Third. Recursion. Really interesting topic. Can be used, can be not used. What you prefer. But sometimes recursion can be a bottleneck in a code. In this situation replaceText is an recusrive operation, which leads to unneeded memory ussage and CPU time. You can aquire all of the nodes in one step by asking it with getElementsByTagName function.Fourth one : “if” operations inside “parseJson” in first for loop. I do not know why, but you do not use if-else statements, but simple if. This means that runtime should go through all of the “if” statements even if it has already found the correct one. In this case for JavaScript efficiency, it’s better to use “switch” statement instead of “if” or “if-else”. It’s faster.
Fifth. Let’s look now in the second “for” loop. You should not use there any switch or if statement at all. The “if” statements in that part are complete overkill. You know the value of your “language” variable before for loop, so you can cache the “to” array before the for loop and use already cached array.
Six : Another small improevement, instead of using frca_count = frca_count + 1; you can just use incremental operator: frca_count++. It will also speedup the code.
Seven. In your second “for: statement you use en_lang.length in conditional part. If you look at the previous “for” loop you can see that it has the variable which holds the same valu : “en_count”. Use it instead of en_lang.length to speed up for loop itself.
Combining this all together, I came up with something like this.
}
All that should do the trick, I hope. Good luck
EDITED: Because getElementsByTagName(“*”) does not return #text nodes, I’ve changed solution to use recursive tree walker.