JavaScript/jQuery optimization
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.';
开发者_StackOverflow $('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);
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.
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))});
精彩评论