简体   繁体   中英

Ways to improve performance of this javascript code?

Don't be frightened, its a very basic code. Just wanted to check with you guys if you know any methods to make it faster ? (still learning) It looks so ugly :)

Or, if you notice anything which could be made differently... Thanks!

function pic_form_function(form, nr, val) {
    document.getElementById("image_to_delete").value=0;
    var re = /\..+$/;
    var extension = val.match(re);
    if (extension==".jpg" || extension==".jpeg" || extension==".gif" || extension==".png" || extension==".bmp") {
        if (nr==1){
            var ID_file1 = document.getElementById("pic_id_nr1").value;
            window.parent.document.getElementById("pic1_filename").value=ID_file1+extension;
            window.parent.document.getElementById("annonsera_nr_pics").value=1;
            window.parent.document.getElementById("iframe_upload_pic").style.height="180px";
            document.getElementById("pic_target").style.height="160px";
            document.getElementById("pic_target").style.display="block";
            document.getElementById("remove_pic").value=0;
            document.getElementById("extra_pic_checkbox").style.display="inline";
            document.getElementById("extra_pic_fnt").style.display="inline";
        }
        else if (nr==2){
            var ID_file2 = document.getElementById("pic_id_nr2").value;
            window.parent.document.getElementById("pic2_filename").value=ID_file2+extension; //Passing fileInputName to parent window...
            window.parent.document.getElementById("annonsera_nr_pics").value=2;
            document.getElementById("extrapic").value=2;
            document.getElementById("pic_file3").disabled=false;
        }
        else if (nr==3){
            var ID_file3 = document.getElementById("pic_id_nr3").value;
            window.parent.document.getElementById("annonsera_nr_pics").value=3;
            window.parent.document.getElementById("pic3_filename").value=ID_file3+extension;

            document.getElementById("extrapic").value=3;
            document.getElementById("pic_file4").disabled=false;
        }
        else if (nr==4){
            var ID_file4 = document.getElementById("pic_id_nr4").value;
            window.parent.document.getElementById("annonsera_nr_pics").value=4;
            window.parent.document.getElementById("pic4_filename").value=ID_file4+extension;

            document.getElementById("extrapic").value=4;
            document.getElementById("pic_file5").disabled=false;
        }
        else if (nr==5){
            var ID_file5 = document.getElementById("pic_id_nr5").value;
            window.parent.document.getElementById("annonsera_nr_pics").value=5;
            window.parent.document.getElementById("pic5_filename").value=ID_file5+extension;

            document.getElementById("extrapic").value=5;
        }
    }
    if (extension!=".jpg" && extension!=".jpeg" && extension!=".gif" && extension!=".png" && extension!=".bmp") { 
        window.parent.document.getElementById("annonsera_imagenotvalid_error").style.display="block";
    }
    else {
        window.parent.document.getElementById("annonsera_imagenotvalid_error").style.display="none";
        form.submit();
    }
}

If me, I will define following on the top.

$=function(x){return document.getElementById(x);}

will replace all the document.getElementById to $ first.

or better user jQuery .

About performance:

To extract the file extension you can use the String.substring method instead of a RegExp , the performance improvement would be negligible but I think it gains readability:

var extension = val.substring(val.lastIndexOf('.'));

About the code:

  1. You could have only one ID_file variable declared at the top of your function, and use it in the if blocks.

  2. The else if blocks where nr==2 , 3 , and 4 are really similar, and you could do the same for those three cases:

//..
else if (nr >= 2 && nr <= 4){
  ID_file = document.getElementById("pic_id_nr"+nr).value; // point #1 assumed
  window.parent.document.getElementById("pic"+nr+"_filename").value=ID_file+extension;
  window.parent.document.getElementById("annonsera_nr_pics").value = nr;
  document.getElementById("extrapic").value = nr;
  document.getElementById("pic_file"+(+nr+1)).disabled=false;
}

About readability:

You could define shorthands to common and verbose function calls at the beginning as S.Mark also suggests:

var el = document.getElementById,
    parentEl = window.parent.document.getElementById;
  • Continuing what CMS did with code repetition, you can refactor the common code outside the sequence of else if blocks.
  • The switch statement was made to replace a sequence of if s.
  • Instead of the above two suggestions, you could define functions do to the same tasks for a more readable implementation.
  • If you continue to use regexps (I personally find them very readable), remember that match returns an array.
  • Also, the .+ will greedily match all characters after the first period. Better to only match non-periods with [^.]+ .
  • Instead of the long sequence of string comparisons, you can use objects as associative arrays:

     var imageExtensions = {'.jpg': 1, '.jpeg': 1, '.gif': 1, '.png': 1, '.bmp': 1}; if (imageExtensions[extension]) { 
  • The last if ... else ... is unnecessary, considering that the condition checks for the negation of the condition in the first if . Just move the else block to the end of the first if and turn the last if (...) to an else .

  • Personally, I find short error handling code more readable when placed next to the if statement that detected the error, rather than after a long block handling the non-error case. After the previous refactor, let's swap the if block with the else block and negate the conditional.

Taking all the above together, we get:

function pic_form_function(form, nr, val) {
    document.getElementById("image_to_delete").value=0;
    var extension = val.match(/\.[^.]+$/);
    if (extension) {
        extension = extension[0];
    }
    var imageExtensions = {'.jpg': 1, '.jpeg': 1, '.gif': 1, '.png': 1, '.bmp': 1};
    if (! imageExtensions[extension]) {
        window.parent.document.getElementById("annonsera_imagenotvalid_error").style.display="block";
    } else {
        var ID_file = document.getElementById("pic_id_nr" + nr).value;
        window.parent.document.getElementById("pic"+nr+"_filename").value=ID_file+extension;
        window.parent.document.getElementById("annonsera_nr_pics").value=nr;

        switch (nr) {
        case 1:
            window.parent.document.getElementById("iframe_upload_pic").style.height="180px";
            document.getElementById("pic_target").style.height="160px";
            document.getElementById("pic_target").style.display="block";
            document.getElementById("remove_pic").value=0;
            document.getElementById("extra_pic_checkbox").style.display="inline";
            document.getElementById("extra_pic_fnt").style.display="inline";
            break;
        case 2: // FALLTHRU
        case 3: // FALLTHRU
        case 4:
            document.getElementById("pic_file"+nr).disabled=false;
            // FALLTHRU
        case 5:
            document.getElementById("extrapic").value=nr;
            break;
        }
        window.parent.document.getElementById("annonsera_imagenotvalid_error").style.display="none";
        form.submit();
    }
}

which is shorter, but could be more readable.

Note that if the $ wrapper is defined in 'window.parent', you should be able to call it as window.parent.$ in the child:

window.parent.$("annonsera_imagenotvalid_error").style.display="none";

There isn't any special computation being done beside traversing elements and assigning their attributes some values. So the code is not performing much to try to improve its performance.

On the other hand, you should use a library like jQuery for the kind of work you are doing. You might be able to cut short many traversals because you can have jQuery reuse the object it found and continue further from this point to look for other objects...

You should cache your dom lookups eg

var pic_target = document.getElementById("pic_target");

You can then use this variable to to apply the style and it only does the dom lookup once. I think this is a key thing to speeding up the js

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM