| 订阅 RSS

如何提高页面响应速度

August 21st, 2008 | No Comments | 目录: javascript, xhtml+css

访问速度缓慢的互联网已经成为过去,但页面能瞬时呈现也只是未来才会发生的事情. Christianheilmann的一些技巧,现在就可以令你的网站访问起来更为流畅。

页面首次访问时的延时是网站和Web应用设计中遇到的一个很重要的问题。用户总是感觉页面相应的不够快。
为什么用户会有这样的感觉?也许用户还保留多年前那种按分钟计费的接入网方式的使用习惯(现在的饭店或机场还保持那种接入方式);也许是因为用户觉得页面要有足够快的响应才能称得上所谓的信息高速路。但在我看来这是好莱坞的责任。在每部好莱坞的动作大片中:敲击一下键盘的同时,电脑屏幕上就会出现超高分辨率,有着密密麻麻数据显示的精美网站操作界面;而且网站上读取一部百科全书也不过短短几毫秒就可以完成。
但在现实生活中却完全不是这么回事,因为无论你如何尽量简化你的页面,延迟还是存在的。而且为了使页面更绚丽,通常会使用flash,但如果滥用flash会严重影响页面的响应速度。作为网络应用,还必须保证页面元素的加载顺序,不会因为页面上未完全加载的元素被用户访问而造成异常。

哪些因素造成网站响应缓慢?

当谈到提高网站响应速度,最通常的做法就是尽可能的减少网站文件的尺寸。(这也导致针对JavaScript库文件大小的无休止的讨论,但最终也没什么结果。)实际上,有许多因素会影响到网页初次访问的响应速度:

* HTML文档的大小。
* 页面中嵌入的脚本、图像、多媒体元素文档的大小。
* HTML页面的复杂程度。(浏览器可以很快的展现简单的页面)
* 用户的接入速度
* 会被页面访问的第三方内容所在服务器的访问速度。
* 网站域名及其页面包含的外部域名的DNS解析速度。
* 用户计算机的性能。(浏览器会因为系统消耗过多的资源在其他任务上而变得响应缓慢)。
* 服务器的相应速度。

除了以上的技术上的因素会导致网站响应变慢以外,还有一些人为设计上的因素。例如:为了避免页面加载过程中出现的页面区域错乱和无图像显示;页面被设计为需要页面内容完全加载完毕后才一起显示。
让网站响应便快的方法

经过实践,以下经验对于解决由于技术和人为因素造成网站响应变慢的问题会有所帮助。

* 在不影响页面显示质量的前提下,尽可能的优化HTML代码。(这包括在发布页面时,去掉HTML文档中的注释以及冗余的换行标记。但为了保证页面的可读性,这些代码还应当保留在源代码中)
* 页面中尽可能少的包含其他外部引用,减少文档之间的依赖。(可以将多个脚本放入一个脚本文件,用CSS的sprite技巧将多个小图片合并为一个大图,这样就只需要加载一次)
* 确保你没有从外部服务器上引用第三方的内容:用一个脚本将远程的RSS源缓存在本地。这样不仅可以避免DNS解析所造成的延时,而且也不会因为外部服务器的宕机影响你的服务。
* 尽可能的制定图片及包含图片的元素的尺寸。这样可以避免页面展现时由于图片陆续加载而造成页面元素跳动的现象。
* 在页面的末端加载大的脚本,这样页面的可以在大的脚本加载完成前展示出来。如果把大的脚本在页面头元素中加载,则浏览器会等到脚本完全加载完成后才显示页面内容。

web开发准则与提高响应速度

可惜上文提到的这些计巧与我们通常认为的web开发的准则有冲突。例如减少页面包含文件数量会造成产品的可维护性变差。为了使网站的不用页面(首页,文章页,存档页)保持不同的页面风格最简单的方法是不同类型的页面的特殊的样式存放在他们各自的样式文件中。一个页面可以有一个最基本的样式文件,然后根据页面的不同类型再包含该类型页面的指定的样式文件。
脚本的存放也可以用相同的方法,将功能相近的脚本放到一个文件中。这样有助于代码的维护。你不用察看所有的脚本代码就可以很快的找到你需要的函数。此外,将脚本加入到页面的主体部分通常被认为是不良的编码习惯,因为他将用户的行为控制逻辑嵌入的页面的结构中。

幸好有技术方案可以解决这些问题。

用一个包含来引用多个样式或脚本。

爱德华艾略特提出的解决方法是用一个PHP的脚本将多个CSS样式或脚本整理成单一的档案。这个脚本对于javascript还可以调用DouglasCrockford’s的JSmin进行压缩。这个脚本使用很简单,而且可以缓存归并后的文件,直到这些被归并的文件被修改。这就意味着当你修改被归并的某个文件后,脚本会自动重新打包缓存。这样就很简单的解决了代码维护和页面响应速度间的矛盾。
解决页面加载的问题

另一个棘手的问题是,嵌入在页面头元素的脚本,必要要等页面加载完成后才能被调用。这样就会有些延时 ,而且还会产生问题。

延时是由于浏览器加载,解析和展现文档的方式造成的。当你用window的onload事件加载脚本时,浏览器的处理顺序是这样的:

* 解析HTML代码装载外部脚本和样式表
* 执行被解析后的脚本
* 建立HTML的DOM树
* 装载图片和其它外部引用内容
* 页面装载完毕

在大多数情况下这样的加载会比较慢,而有些步骤需要提前。许多聪明的程序员致力于解决这个问题,不时的会有新的解决方案出现。大多数的javascript脚本都会有针对onAvailable或onDocumentReady的事件处理。这类事件会在部分文档装载完成后就会被触发,而不用等到大量图片被加载。但通过实践和反复测试,针对旧的浏览器和操作系统并没有无懈可击的解决方案。但我相信只要我们继续努力,再加上那么点运气一定会找到最终的解决方案的。

对于web应用由于调用未加载完成的元素而导致异常是很致命的问题。如果这类问题时发生在页面美化部分,则会有一些解决方法。

为了解决一次加载过多内容的问题,可以采按需分别加载内容。

为了更好的装饰页面一次载入大量的内容,往往会产生问题。大量的内容有可能是每个标签中都包含过多的文字或者是一个有四级的导航栏。运用javacript脚本可以很轻松的动态展示这些内容。但是如果脚本被禁用,则这些动态内容就会失去样式而被打乱,无法正确地展示,这当然不是一个好主意。页面也没有必要一次将所有的动态展示内容都一次加载,这样会增加页面载入的负载。

解决方法是当用户触发标签时再用javascript动态的加载显示的内容。当用户关闭脚本后也会显示一个基本的静态文本。

用什么方法来加载额外的内容取决于你需要引用的是什么。最简单的方法是动态的生成脚本标签。这是一个很早就有的方法,被用来引入大量的javascript数据集或在页面加载后再引入脚本。


function pull(){
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = 'largeJavaScriptBlock.js';
document.getElementsByTagName('head')[0].appendChild(s);
}
window.onload = pull;

del.icio.us页面就到这种方法来引入由json返回的数据。由于json返回的不过是一堆javascript代码,你可以在页面装载完成后,生成javascript脚本标签包含这些代码;然后执行这些代码原来替换页面中某个元素的内容。Dishy作为封装了json的对象可以让你很轻松的完成这些。另一个列子是不太显眼的Flickr头像,Flickr用json输出显示你最新相片,当用户禁用脚本,哪个位置显示的只是一个链接。

如果你要引入的是非javascript的内容,你可以使用Ajax或者AHAH或者Hijax或者其他不包含xml的ajax(你愿意把称作什么名称都可以)。例如,一个用ajax实现的导航,它甚至可以根据用户需要可选择的加载更为复杂的界面。

Imaging trickery 图像显示技巧
最后一个方法的渊源会追溯到可能你还没开始接触网站开发时。那时浏览器大战中最为ie的竞争对手苦命的Netscape(但在我看来那时还是不错的)浏览器支持一个自定义的HTML属性‘lowsrc’,这个属性可以指定一个小图片提前加载作为大图载入时的替代显示图片。这样即使用户的接入速度很慢,也可以看到即将呈现图片的一个预览。
你可以重用这一想法,当页面加载时不要嵌入过大的图片而是载入更为规范化的小图片;等页面加载完成后再用大图片进行替换。你甚至可以简化到开始只载入背景色,然后等页面载入完成再用javascript或者DOM加载原图进行覆盖。
这种方法还适用于你需要从多个服务器取得许多不能被缓存的图片。(例如gravatars)通常可以先载入一个占位的图片,等页面加载完成后再动态取得分散在其他服务器上的小图片。

CSS 清除浮动的三种方式

August 19th, 2008 | No Comments | 目录: xhtml+css

用空标签清除

.clr {clear: both;}
<div id="layout">
<div id="left">Left</div>
<div id="right">Right</div>
<p class="clr"></p>
</div>

使用 overflow 属性


#layout {overflow:auto; zoom:1;}
<div id="layout">
<div id="left">Left</div>
<div id="right">Right</div>
</div>

使用 :after (非 IE 浏览器)

#layout:after{
display: block;
clear: both; content: "";
visibility:hidden; height: 0;
}
<div id="layout">
<div id="left">Left</div>
<div id="right">Right</div>
</div>

注:使用 :after 需要注意几点,设置高度为零(height: 0;);content 是必须的,但其值可以为空。

段正淳的css笔记

August 18th, 2008 | No Comments | 目录: xhtml+css

试想过总结出这几年来写css与xhtml的经验 ,汇总成一片”旷世奇文”分享给大家。无奈寡人年世已高,真是有点力不从心了。于是转念一想,可以用笔记的形式展现,这样就不用担心写不出来了。

现在就来说个淘宝首页上的一个小技巧。

类目之间的横竖线

从很久很久以前开始,类目间的竖线无非都只有三种。

  1. 背景图
    在a标签设置一个padding 用宽1px高不等的背景图来position到右侧。
    缺点:最后一个还是要用class来隐藏掉背景。
  2. 符号
    在每个a标签之间用”|”符号来填充。
    缺点:html文件变大,文件维护变得很麻烦,而且在html中毫无意义。
  3. a标签右侧的boder。
    同背景图一样,只不过使用border-right来代替。缺点也同上。

看到这里,可能已经有人打开淘宝首页用firebug查看源码来看是怎么做了。

其实现有是利用ul的overflow:hidden 再将li的margin-left:-1px的做法做出来的。这样的做法就可以同时避免以上的缺点了。
为什么之前都没有那么做的,寡人也不知道了。难道寡人是第一个发现这样的做法?
不管是谁先此之前利用了这样的方法实现类目间竖线。
不过在淘宝首页上线后不久就有同行的网站在首页改版中也用了这样的方法。
那个网站不看也罢。class实在是写的有点多。加载html会变得多得多。
反正一个首页需要加载1.17m的网页我的大脑会自动屏蔽。

圆角的做法.

为了这个圆角,前段开发们付出的努力是在是太多了.又要考虑http连接数,又要考虑css与html的代码量与语义.
贴出的是最近考虑替换现有圆角做法的方案,可能还有许多未考虑的状况.但是大体的编写方式便是如下.
好处是便于维护,只有一个图片.还可以某种程度上的任意缩放.缺点是多了无意义的html代码.

css:
.c,.c i,.c i i,.c b,.c b b,.c p{
background-image:url(http://pics.taobao.com/bao/album/promotion/uiblog/purple.png);/*背景图片*/
background-repeat:no-repeat;
}
.c{
width:200px;/*临时定的宽度*/
background-position:0 -4px;
}
.c i{
display:block;
height:4px;
}
.c i i{
margin:0 0 0 4px;
background-position:right 0;
}
.c b{
display:block;
height:4px;
background-position:0 bottom;
}
.c b b{
margin:0 0 0 4px;
background-position:right bottom;
}
.c p{
margin:0 0 0 4px;
padding:0 4px 0 0;
background-position:right -4px;
}

html:
< div class="c">
< i>< i>< /i>< /i>
< p>
按钮按钮按钮按钮按钮按钮
按按按按按钮按钮按钮按钮按钮按钮按钮按钮按钮按钮按钮按钮
< /p>
< b>< b>< /b>< /b>
< /div>

table的全局定义

caption这个标签在firefox下会有左边有1px空隙的bug,很讨厌.能想到的简单的方法只有-1px的margin了.

css:
table{
border-collapse:collapse;
}
table caption,table td,table th{
border:1px solid #a2bbdd;/*边框颜色*/
background:#c3d9ff;/*背景颜色*/
}
table caption{
text-align:left;
border-bottom:none;
margin-left:-1px;
}

html:
< table>
< caption>表格标题< /caption>
< tr>
< th>标题< /th>
< th>标题< /th>
< th>标题< /th>
< th>标题< /th>
< /tr>
< tr>
< td> 内容< /td>
< td> 内容< /td>
< td> 内容< /td>
< td> 内容< /td>
< /tr>
< /table>

需要正视的二个标签

  1. acronym这个标签用来解释名词很爽,但是用得太少.(我也一直想用来着,所以记下了.)
    css:
    acronym{cursor:help}
    html:
    < acronym title=”段正淳又是金庸笔下一个十分奇特的人物。他奇特在到处留情,情人极多,见一个爱一个,而又绝不是徒然风流薄幸,当他是单独对着一个情人的时候,他真是真心真意爱这个情人的,只好说这个人的感情特别丰富,别无其他解释。” >文字< /acronym>
  2. ins这个标签忘记是在哪个网站上看到过用来在h2里显示更多的链接,后来查了书,大家都觉得有点欠妥,有点争议.
    css:
    还未写入css组件…欠奉上了
    html:

    标题更多>>

    标题右侧“更多”的实现

    曾经做上图所示的效果,会使用到position来相对定位到h2标签的右侧.这样的做法,代码确实会多好几行. 其实可以用个笨一点的办法来实现的:

    譬如html代码如下:

    < h2>< a h ref=”#” >标题< /a> < span>更多…< /span> < /h2>

    使用potsition的css差不多如下:

    h2{
    position:relative;
    height:20px;
    }
    span{
    position:absolute;
    right:0;
    top:0;
    display:block;
    height:20px;
    }

    这样才能实现更多在右侧.其实真的还可以更简单:

    h2{
    height:20px;
    }
    span{
    float:right;
    display:block;
    margin:-10px 0 0 0;
    height:20px;
    }

    其实只是利用了margin-top 的负数来实现,因为默认的float会换行到h2标签下面去,所以让它自个跳上去。大致代码就是如此了,是不是很简单?我说很简单嘛!由于很简单,所以就不放出单独的测试页面了.

    ps:我说咱们啥时候也得搞个和蓝色理想一样的编辑器吧…

    淘宝的css属性顺序书写规范

    以前部门的同事们,每个人都有一套书写的规范,导致看对方的css代码非常吃力,所以就推行了一套书写标准 ,或许对您也有帮助。

    *{
    /*显示属性*/
    display
    position
    float
    clear
    cursor
    /*盒模型*/
    margin
    padding
    width
    height
    /*排版*/
    vertical-align
    white-space
    text-decoration
    text-align

    /*文字*/
    color
    font
    content

    /*边框背景 为什么要把 boder和background放在最后的原因是修改的频率会较之前的频繁,放在最后查看起来方便,哈哈。*/
    border
    background
    }

    说到底其实属性的书写顺序规范就是:神仙?妖怪? – 身材怎么样!- 服装类型(比基尼?棉袄?) – 服装款式(黑色?白色?纽扣?拉链?) – 用了啥化妆品和发型.
    这个书写标准小部分并不是浏览器厂商推行的书写规范,所以可能被广大标准推广者所不认同 。但这些个都是弟兄几个实践出来认为最符合现有淘宝环境的。

    css代码的简写

    css缩写的语法,对新手有一定帮助,老鸟就不用看了.

    1. 0px不需要单位,直接:margin:0
    2. 盒模型的缩写,语法是margin:上 右 下 左;.甚至可以简写成margin:上 (右左) 下,当然右左的值应该是一样的
    3. css属性的最后一项”;”号省略。(不建议 ^_^)
    4. 字体宽度normal用400代替,bold用700代替。
    5. 16进制的色彩值,如果每两位的值相同,可以缩写一半,例如:#000000可以缩写为#000;#0044DD可以缩写为#04D;
    6. border边框的缩写,语法是border:width style color,类似boder:1px solid red;
    7. 背景background的缩写,语法是color image repeat attachment position.类似:background:#f00 url(background.gif) no-repeat fixed 0 0( 为什么我从不写fixed呢?)
    8. 字体的缩写,类似font:italic small-caps bold 1em/140% “SimSun”,sans-serif,可以省略到最简单font:12px “SimSun”.
    9. list的属性缩写,语法list-style:square inside url(image.gif) ,不过一般咱们都不用.
    10. 想凑10条, 还真难.就把删除无用换行符和空格算一个吧

    一天大家在团队中讨论“未知图片垂直居中”的问题,突发奇想用vertical-align:middle这个属性来实现,于是抽了时间做了下面这个不成熟的例子:

    CSS:

     div{
      width:140px;
      height:140px;
      text-indent:-8px;
      text-align:center;
      line-height:138px;
      background:red;
      font-size:12px;
      *font-size:120px;
      *text-indent:-60px;
    }
    img{
      width:100px;
      height:100px;
      vertical-align:middle;
    }

    HTML:

    < div>& nbsp;<img src="ipodclassics.jpg" alt="iPod classic" />

    初衷是不想用position来做,毕竟 大量的图片显示浏览器在渲染的时候会消耗 较多的资源。

    缺点是 输出了 无意义的nbsp;, 而且font-size和font-indentd的计算公式不是很简单(所以以上的数字都是凑的^_^).

    后来小马见了这个思路,用了点时间升级了代码,用:after输出代替了无趣nbsp ,代码见下。

    CSS:

     .tb-p-c{
      display: block;
      width:140px;
      height:140px;
      line-height:140px;
      text-align:center;
      *font-size:123px;
    }
    .tb-p-c img{
      vertical-align:middle;
    }
    .tb-p-c:after {
      content: ".";
      visibility: hidden;
      font-size: 12px;
      margin-left: -5px;
    }

    HTML:

    <a class="tb-p-c"><img src="jishi070912_2.jpg" /></a>

    这样子,恼人的nbsp消失了。大家对vertical-align:middle的渲染方式有了更进一步的了解了。还让很多同志发现了after这个伪类还可以用来hack.

    结果圆心又给CSS升了次级:

    CSS:

     .tb-p-c{
      display: table-cell;
      vertical-align:middle;
      width:140px;
      height:140px;
      text-align:center;
      *display: block;
      *font-size: 122px;
      background:red;
    }
    .tb-p-c img {
      vertical-align:middle;
    }

    这是第三次的升级,由于时间关系,没有测试上面的代码,原因是利用了display来渲染,感觉上还是会让浏览器多次渲染,所以偶没测试 。
    这次探讨给了我们很多很多的收获,相信如果有大家的参与,会有更多方式和我们没发现的观点。大伙别小气,多发表回复,一起提高。