1

I have just finished my new portfolio site visible at http://www.pepkarsten.com/artdirection.

It is a single page that loads images (with loader animation, preloading and keyboard shortcuts).

Here is the JavaScript code (using jQuery). How can it be optimized?

$(document).ready(function() {
    function page(slide,width,height,color) {
        this.slide=slide;
        this.width=width;
        this.height=height;
        this.color=color;
    };

    var pages=[
        new page('alutech1',900,675,'1d486b'),
        new page('alutech2',900,675,'00ea00'),
        new page('mane3',675,900,'74878e'),
        new page('mane4',675,900,'74878e'),
        new page('mane1',900,675,'6ecb00'),
        new page('topfit_zen',900,675,'203400'),
        new page('topfit_muscu',900,675,'01acb3'),
        new page('topfit_stval',900,675,'525962'),
        new page('arles_1',636,900,'fb926d'),
        new page('arles_2',636,900,'c12f2f'),
        new page('arles_3',636,900,'cdc6b4'),
        new page('topsol',900,633,'f7e700'),
        new page('wak',900,675,'78f900')
    ];
    var imgDir='img/';
    var slidePrefix='pepkarsten_';
    var slideExt='.jpg';
    $.autoMouseOver();
    $.blurLinks();

    function prevPageNumber() {
        return currentPage>0?currentPage-1:pages.length-1;
    };

    function nextPageNumber() {
        return currentPage<pages.length-1?currentPage+1:0;
    };

    function displayPage(n) {
        $('#nav-top')
            .css('background-color','#'+pages[n].color);
        $('#slide')
            .addClass('loading')
            .find('img')
            .css('visibility','hidden')
            .css('width',pages[n].width)
            .css('height',pages[n].height)
            .unbind('load')
            .load(function() {
                $(this)
                    .css('visibility','visible');
                $('#slide')
                    .removeClass('loading');
                $.preloadImg(imgDir+slidePrefix+pages[nextPageNumber()].slide+slideExt,imgDir+slidePrefix+pages[prevPageNumber()].slide+slideExt);
            })
            .attr('src',imgDir+slidePrefix+pages[n].slide+slideExt);
        currentPage=n;
    };

    function homePage() {
        displayPage(0);
    };

    function nextPage() {
        displayPage(nextPageNumber());
    };

    function prevPage() {
        displayPage(prevPageNumber());
    };

    homePage();
    $('#home')
        .onclick(homePage)
        .shortcut('up');
    $('#next')
        .onclick(nextPage)
        .shortcut('right');
    $('#prev')
        .onclick(prevPage)
        .shortcut('left');
    $('#slide')
        .onclick(nextPage);
    $('#contact')
        .email('info','pepkarsten.com')
        .hover(
            function() {$('#tip-contact').slideDown(200)},
            function() {$('#tip-contact').stop(true,true).hide()});
    $('#linkedin')
        .onclick(function() {
            window.open('http://www.linkedin.com/in/pepkarsten');
        })
        .hover(
            function() {$('#tip-linkedin').slideDown(200)},
            function() {$('#tip-linkedin').stop(true,true).hide()});
});

(function($){
    var imgCache=new Array();
    $.preloadImg=function() {
        for(var i=0; i<arguments.length; i++) {
            var img=new Image();
            img.src=arguments[i];
            imgCache[img.src]=img;
        }
    };
    $.autoMouseOver=function(outStr,overStr) {
        if(!overStr) var outStr='-out.', overStr='-over.';
        $('img[src*='+ outStr +']')
            .each(function() {$.preloadImg($(this).attr("src").replace(outStr,overStr))})
            .hover(
                function() {$(this).attr("src",$(this).attr("src").replace(outStr,overStr))},
                function() {$(this).attr("src",$(this).attr("src").replace(overStr,outStr))});
    };
    $.blurLinks=function() {
        $("a").focusin(function() {
            this.blur();
        });
    };
    $.fn.onclick=function(f) {
        $(this).click(function() {
            f();
            return false;
        });
        return this;
    };
    $.address=function(u,d) {
        return u+'@'+d;
    };
    $.fn.email=function(u,d,s,b) {
            var l='mailto:'+$.address(u,d);
            if(s||b) {
                l+='?';
                if(s) {
                    l+='subject='+s;
                    if(b) l+='&';
                };
                if(b) l+='body='+b;
            };
        $(this).click(function() {
            window.open(l);
            return false;
        });
        return this;
    };
    $.fn.shortcut=function(key) {
        var code={'left':37,'up':38,'right':39,'down':40};
        var $this=$(this);
        $(document).keydown(function(e) {
            if(e.keyCode==code[key]) {
                $this.click();
                return false;
            };
        });
        window.focus();
        return this;
    };
})(jQuery);
6
  • Wow... we know JS sucks, but Jquery looks like it sucks too... You're better off with a rewrite using rich client technology (i.e. any RIA tech that is not JavaScript based)-- the code isn't readable enough for many people to be interested in helping to troubleshoot. Commented Oct 16, 2010 at 17:24
  • hehe, maybe it sucks because i am more a designer than a developper. I don't know anything about rich client tech... gonna search about this Commented Oct 16, 2010 at 17:29
  • 4
    @Pep: There's nothing wrong with the code. Crusader is probably just not used to reading Javascript. You're asking for a lot, though, since it's a bit of code, and figuring out what you do (or intend to do) requires a fair amount of time, just to get prepare for an answer. On a glance, as I said, the code looks fine, no matter what any troll says. ;) I suggest you ask for specific help if you notice something not working properly. Commented Oct 16, 2010 at 18:09
  • Thanks Thomas ! Everything is working properly. It's just that i don't know if there were simpler ways of coding all this. I know it would be time consumming to figure out what everything's doing but i am just asking for quick tips here and there (because i am not a developper). Commented Oct 16, 2010 at 18:24
  • Lol, how did the s in the title move like 5 places to the right? Commented Oct 16, 2010 at 18:32

2 Answers 2

4

Practical answer: No need for optimization, you have got smooth working preloading that minimize the effect of connection slowness. The impact of any speed-imperfections in the code is negligible, the network optimization is done correctly, that is what matters in this case.

Theoretical answer: If you truly worry about performance then don't use jQuery, you simply don't have the low level control required for making truly optimized JavaScript, and you generally end up with a lot of obfuscated overhead since what seems like a simple jQuery function may actually have a complex implementation and thus cost a lot of time.

For the record, I'd say you are the first designer I have met who can code. Of course there are others who can stick together some commands, but it seems like you actually know what you are doing. A piece of advice for the road, since I think you are the type who can manage it: Whatever people tell you, question it, try to find proof for the opposite and do your own research if necessary.

Edit: About jQuery vs. JavaScript
As I see it, the biggest advantage of jQuery is that it fixes a lot of browser differences so you don't have to worry whether the code will work in all browsers. jQuery also does a lot of "magic" which may make coding easier, but the magic typically cost a lot speed-wise, how much depends a lot on which functions you use, and how you use them. You easily toss a factor 10 on script execution, but most code continue to be limited by DOM manipulation, and jQuery does not slow that down.
I'm no fan of jQuery syntax, it is very much in line with a current trend of convoluting everything using closures and using the keyword this as much as possible. That is of course not to say that you have to write such unreadable code if you use jQuery, but it is hard not to drag in that direction. If you write something big I would prefer JavaScript, since readability is then a much bigger issue.

Sign up to request clarification or add additional context in comments.

2 Comments

+1 Pep, the code looks fine, like anything it could get better but might not be immediately necessary!
Thank you my friends. @ eBusiness : Very interesting points of view. I am new to jQuery and indeed still questionning myself about it versus hardcore javascript (as i used to do with my previous personal websites)...
0

Only a few minor things jumped out at me. Overall, it looks smooth in Chrome.

Before I get to those I'd like to suggest that you comment your code. It'll make it much easier on you a year from now when you go back and try to make a change! Also you might want to think about ordering your functions in some sensible manner (alphabetically for example, or whatever else you can think of that makes sense... they don't seem to be in any order that I can tell)

One thing I noticed is that you try to optimize your code by only creating the $(this) jQuery object once for each instance using var $this = $(this);. You use this even when $(this) is only used once, which is fine but unnecessary, but you forgot to do it in a few instances.

For example you have:

.....hover(function() { 
               $(this).attr("src",$(this).attr("src").replace(outStr,overStr))},
           function() {
               $(this).attr("src",$(this).attr("src").replace(overStr,outStr))});

This could be:

.....hover(function() { 
               var $this = $(this);
               $this.attr("src",$this.attr("src").replace(outStr,overStr))},
           function() {
               var $this = $(this);
               $this.attr("src",$this.attr("src").replace(overStr,outStr))});

4 Comments

blur is also a native JavaScript method, it is what is used, and that is perfectly legit. The $this = $(this) trick is as far as I can tell used for the purpose of passing the created jQuery object from one scope to another, but you are right that it could also be used for a slight performance enhancement in a few situations.
Thanks, i corrected the $this trick. However as i told to eBusiness i am wondering about Jquery versus hardcore javascript then i kept this.blur() and corrected the hover function with pure JS : this.src=this.src.replace(outStr,overStr). Do you think it is better to rely on jQuery even when it is as simple to write a line in pure JS ?
@Pep - Sorry, you're right. .blur() is a JS method. It's always better to use native JS than jQuery (as long as it's x-browser compatible).
@eBusiness - Yeah. Didn't realize .blur() was a JS method. var $this = $(this) is used so you only have to build the same jQuery object once... for that slight performance advantage..... You're right in that the same trick can be used to pass the context, but in that case it'd make more sense to not call it $this... maybe var $that = $(this); is you want to pass the context to another scope.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.