How can I improve the performance of this script?

How can I improve the performance of this script?

Hi there.

I've been using jQuery and javascript for a while now, but recently I've been trying to up my game significantly. I decided to develop this script from scratch as I wanted it to do something specific and and I wanted to learn in the process. I was hoping to get a discussion going here and some advice from anyone willing to give it, on how to trim down, improve, and speed up the application. 

I'll make the code available for anyone who wants to use it and maybe turn it into a plugin at some point.  

So here is a link : http://staging.walkermultimedia.co.uk/slider/index.html

The script is for a basic slider with left and right buttons, but also a clickackable navigation bar at the bottom. The elements in the slider can be any width so I have to determine the widths and reflect that in the bottom navigation. There is a highlighter for the navigation that shows you where the viewport is in relation to the whole list.

Currently it works pretty well but it seems a bit bloated to me and there sometimes seems like there's a lag when you click the navigation. I'm concerned about memory leaks but not sure how to track them down properly

If you'd like to take a look and make a comment or ask questions I'd really appreciate it.

Here is the code in full (also attached as a txt file):

  1. function MXMSlider (slider) {

      var $this = this,
          sumwidth = 0,
          slider = $(slider),
          sliderlist = slider.children("ul.sliderlist"),
          itemImgs = sliderlist.find("img"),
          items = sliderlist.find('li'),
          nextBtn = $('<a />', {className:'next leftright',text:'next',click:clickNextPrev}).data('dir','next'),
          prevBtn = $('<a />', {className:'prev leftright',text:'prev',click:clickNextPrev}).data('dir','prev'),
          sliderwidth = 0,
          itemwidths = [],
          currentitem = 0,
          margin = 25,
          countImgs = 0,
          highlighter = $('<div />', {className:'highlighter'});

      // add buttons outside of slider div
      slider.append(nextBtn,prevBtn);
      // Image loading callback (we can't test the width of the images until they've loaded)
      itemImgs.one("load",function(){
        if (++countImgs == itemImgs.length)
          buildNav();
      }).each(function(){
        if(this.complete || (jQuery.browser.msie && parseInt(jQuery.browser.version) == 6)) $(this).trigger("load");
      });
     
     
      function buildNav () {
        var slidernav = $('<div />', {className:'slidernav'}),
            slidernavlist = sliderlist.clone(),
            scale = 30;
        // need to do this once we're sure all the images have loaded.  TODO: just have one loop on images
        itemImgs.each(function(){   
            var width = this.offsetWidth + margin;
            sliderwidth += width;
            itemwidths.push([width,sumwidth]);
            sumwidth -= width;
        });
       
        sliderlist.width(sliderwidth)
        slider.after(slidernav);
        highlighter.appendTo(slidernav);
       
        $this.slidernavlistitems = slidernavlist.children('li');
        $this.slidernavlistitems.each(function (i){
          this.innerHTML = '';
          this.style.width = parseInt(itemwidths[i][0]/scale) + 'px'
        });
        //set up click events for slider list
        slidernavlist.appendTo(slidernav).delegate("li","click",function(e){
          currentitem = $this.slidernavlistitems.index(e.target);
          animateList(itemwidths[currentitem][1],e.target.offsetLeft);
          return false;
        });

        highlighter.width((slider.width() - (margin * 2)) / scale).height('21px').css({opacity:'0.3', left:$this.slidernavlistitems.first().position().left});
        hideNextPrev();
      }
     
      function animateList (sliderleft,highlighterleft) {
        sliderlist.animate({left: sliderleft},400,hideNextPrev);
        highlighter.animate({left: highlighterleft},400);
      }
     
      function clickNextPrev (e) {
        if (!sliderlist.is(':animated')) {
          // next or previous (forwards or backwards)?
          ($(e.target).data('dir') == 'prev') ? currentitem -= 1 : currentitem += 1;
          // animate in the right direction
          animateList(itemwidths[currentitem][1],$this.slidernavlistitems.eq(currentitem).position().left);
        }
        return false;
      }
     
      function hideNextPrev () {
        // If scrollist is right of left terminus hide prev button
        if (sliderlist.position().left >= 0) {
          prevBtn.addClass('sliderdisabled').unbind('click');
          if (!nextBtn.data('events')) nextBtn.removeClass('sliderdisabled').bind('click',clickNextPrev);
          // Else if scrollist is left of right terminus hide next button
        } else if (sliderlist.position().left <= (slider.width() - sliderlist.width())) {
          nextBtn.addClass('sliderdisabled').unbind('click');
          if (!prevBtn.data('events')) prevBtn.removeClass('sliderdisabled').bind('click',clickNextPrev);
        } else if (!nextBtn.data('events')) {
          // Else show next buttons
          nextBtn.removeClass('sliderdisabled').bind('click',clickNextPrev);
        } else if (!prevBtn.data('events')) {
          // Else show prev buttons
          prevBtn.removeClass('sliderdisabled').bind('click',clickNextPrev);
        }
        return false;
      }
    };

    new MXMSlider("#slider1")