Web开发中你注意这些前台开发问题了吗?(前台构架篇)

       Web2.0带给我们更好的用户体验和更炫更酷的效果,javascriptflash, Silverlight都是跃跃欲试。目前应用最多的还是javascript,所以你会经常看到很多web2.0网站有n多的jscss,这时管理这些文件和如此多的代码怎么提性能提升的问题也来了。以下就来讲讲我目前想到的一些问题吧。

       1jscss引用时如何做到让请求进行并发下载。

       我们通过firebug,就会发现通过linkscript标记在页面上的引用资源每个请求都是以一个队列形式排队等候,一个资源下载完成后才会下载别外一个请求资源。它不像我们页面里面的图片(img标记和样式中引用的图片,样式里面引用的图片必须等到css文件加载完毕后才能下载图片),可以并发下载资源文件。YSlow曾经对Web站点优化中提出,尽量把css放在head(样式突然在其它资源下载完毕后才展现,那太有戏剧性了),但是有点搞不明白,为什么浏览对css加载也是一个队列,难道怕在样式中有重名部份的冲突?YSlow还提出过把js放在页面的尾部,那样的话整个页面下载js资源差不多在onload完在。这点很是深有体会,当你的script放在head的时候,整个页面展现都得script一个个加载完毕再发生,这直接影响着Web性能,我想比网站的速度比用户体验来得更重要吧,所以我们应该把js放在尾部。那么是不是说直接放在尾部就好了呢?我想还有一点可以优化的,就是让其并发下载。那么如何解决这些资源的并发下载问题呢?

       我的方法是通过动态追加dom的方法(appendChild,动态追加linkscript节点标记到head下)。使用这种方式,我们会发现我们的队列突然变得成了百米冲刺了,一声哨下,都冲向终点了(当然每个并发请求数肯定还是有一定限制的)。不过在ieappendChild这种方法在window.onload事件无法引用资源的函数,所以在ie时我用docoument.write去输出(ie下用document.write也是并发下载,而firefox是不行的)。所以通常在引用文件的时候使用include的方法,以下列出include代码。

var $include=function(filecallback){
    
var isScript=file.indexOf(".css")==-1;
    
var attLink,path,extName="";
    
if(isScript){
        
attLink="src";
        
path=COREJSPATH;
        
scripts $tag("script");
        
if(file.indexOf(".js")==-1extName=".js";
    }
else{
        
scripts $tag("link");
        
attLink="href";
        
path=CORECSSPATH;
    }
    
if(file.indexOf("/")==-1){
        
file=path+file+extName;
    }
    
for (var 0scripts.lengthi++) {
        
if(scripts[i][attLink]==file){
            
return;
        }
    }
    
var fileref;
    
if (isScript){ //If object is a js file
        
if(window.ie){
            
fileref="script"+$time;
            
document.write("<script src=\""+file+"\" id=\""+fileref+"\" type=\"text/javascript\"></script>");
        }
else{
            
fileref=$create('script');
            
fileref.setAttribute("type","text/javascript");
            
fileref.setAttribute("src"file);
            
document.head.appendChild(fileref);
        }
    }
    
else //If object is a css file
        
if(window.ie){
            
fileref="script"+$time;
            
document.write("<link rel=\"stylesheet\" rev=\"stylesheet\" href=\""+f+"\"  id=\""+fileref+"\"  type=\"text/css\" media=\"screen\"/>");
        }
else{
            
fileref=$create("link");
            
fileref.setAttribute("rel""stylesheet");
            
fileref.setAttribute("type""text/css");
            
fileref.setAttribute("href"file);
            
document.head.appendChild(fileref);
        }
    }
    
if(callback) {
        
fileref=$(fileref);
        
addEvent(fileref,'load',callback);
        
fileref.onreadystatechange function(){
            
if(this.readyState=="loaded" || this.readyState=="complete"){
                
callback();
            }
        };
    }
};

注:

1.CORECSSPATH(当前css存放的相对路径)COREJSPATH(当前js存放的相对路径),用这个原因主要是路径问题,这个稍后再讲。

2.callback是当文件加载完成后再调用方法。

3.顺便说一下我主要用mootools的一些函数

   2.我们的js文件管理及引用太讲究了,侵入性太强了,一个小心把顺序弄错或者依赖没引用那就惨遭了,如果像有C#using引用多好呀!

项目一天一天在扩大,此时发现已经有一大堆js文件了,问题就来了——管理这些文件依赖和顺序很麻烦。js类库中可能存在着依赖关系,每个引用都得知道该类的依赖关系然后再写入<script src="你的js文件" type="text/javascript"></script>,而且说不定你的js有装载前的依赖关系(也就是说引用一个js前,需要把某个js放在你的引用的那个js前面),不然你运行结果肯定是error,所以我们急需管理这样一些类的解决方案,这方面看到JSI好像做的挺不错的。(JSI还没深入研究,不太懂其原理,看似好复杂)

js的依赖关系示例(引自JSI的文档说明)

3个类:动物(Animal),猫(Cat),老鼠(Mouse);

他们有如下依赖关系:

猫、鼠 装载前依赖动物类(装载这两个类时,需要创建动物实例作为其原型;该操作必须在装载时完成,为装载前依赖

猫鼠装载后,在使用过程中,相互依赖(猫鼠的行为中需要判别对方的行为,使用到了相互的引用,为相互装载后依赖)。

     可表示为如下图例:红色代表装载前依赖,浅绿色表示装载后依赖:

     

来说说我的想法(目前还未实现),最好存在一个依赖关系的配置文件,而且所有的依赖关系都存放在一个配置文件中并说明依赖关系(呵呵,最好vs自动能生成关系),我看到JSI好像每个依赖得写一个__package___.js文件,那样是不是麻烦了?(呵呵,不太懂)

   3.关于路径问题。

js,css的路径管理也是我们管理的一部份,哪天我们的页面换了个文件夹位置,就得改代码里的路径那实在是太糟糕了。所以我用上面的$include方法,只要你的核心js文件路径确定,其它路径也随之确定($include方法引进的资源文件)。如果你想通过改变文件位置后不用改路径的话,那么通过核心文件在服务器输出核心js ,那问题也就迎刃而解了(图片的路径也是一道理,所以w3c好像要取消img标记,统一放css)。但是这样做会产生对某种开发语言的依赖,不知道园子里的朋友有没有更好的解决办法?

   4.关于jscss的缓存。

我的解决办法是:通过你的核心部份的js后加参数(随后include进来的js后面都给其定意和核心js一样的参数),而如果你想所有控制所有页面,只能在服务器端输出核心脚本(同路径问题的服务器端输出)

   5.如何减小多张图片的连接数

可以合并一张图片,用css样式定位。如:

.afirst,.alast,.anext,.apre,.nnext,.nlast,.nfirst,.npre{background:url(imgs/grid/gridbg.gif) 0px -116px;}

.anext{background-position:0px -153px;}

.alast{background-position:0px -221px;}

.apre{background-position:0px -185px;}

.nnext{background-position:0px -135px;}

.nlast{background-position:0px -200px;}

.nfirst{background-position:0px -97px;}

.npre{background-position:0px -169px;}

其实上面图片是同一张,只是定位在不同位置吧!(css的路径引用图片的路径好像比js好)

上而合并一张图片还有一个好处是,比如当你按钮可能onmouseover时一一张图片,而onmouserout又是一另张图片,用户鼠标经过就会有感觉闪了一下,如果网速慢还要再去下载那个图片的过程,这是呈现的是一片空明(呵呵,在一定程度上提升用户体验)

  6.站点发布后css,js压缩

我的想法是这样的(没实现),当我们的vs在生成网站的时候可以自动将js或者css自动压缩 (当然可能还是会遇到点问题的,因为很有可能js压缩后出现问题,你在写js的时可能会少了一个分号,那样必定会造成出错)

  7.按需装载和延迟装载问题

上面如果我用$include引进文件还得在window.onload事件里面去执行,如果能在$include下面的代码能可引用包含进来的文件的function的话,那就可以实现按需装载的过程了。可是通常这种解决办法是通过一种同步的阻塞式的装载过程,用户体验很差(电脑像死机一样了)。JSI号称可以延迟装载这个过程,不知道这个过程是怎么实现的。

 

以上是我在Web开发和构架中的一些待解决问题,不知道园子里的朋友,还遇到哪些问题,希望能一起分享和探讨。

posted @ 2008-08-04 12:35  netcorner  阅读(3997)  评论(31编辑  收藏  举报