2009年6月30日星期二

[翻译]界面提示与感知延迟

对一般的用户而言,速度并不意味着性能。用户对网站速度的感知很大程度上取决于其整体感受,包括他们如何高效的从网站获取所需,以及网站反映出来的易响应性。

当设计 Web 站点或 Web 应用时,谨记用户来你的网站是有目的的。他们能越快(越容易)达到他们的访问目的越好。如果用户在获取内容时遇到了许多困难,他们将会离开你的网站,而去能让他们更快达成目标的其他网站。

节省用户时间,让他们感觉没那么慢有很多工作可以做,本文只涉及提示信息。

提示信息,要考虑三点:

  1. 网站是否足够简单和直观,首次访问者是否可以很容易上手?

    如果不是,花些时间去设计首次运行经验(first-run-experience)提示。

    比方说,你的网站是一个拥有数项功能的强大的 Web 应用。鉴于为此类型的应用程序设计一套直观的“开箱即用”(out-of-the-box )体验并不是一项容易的事情,用户可能需要一个入门帮助。

    首次运行经验简单的为用户说明产品是什么以及/或如何使用其亮点。从长远上看,花一点点时间让用户提前了解产品的一些关键点会给他们节省大量时间。

    提示:不要过头!不要阻止用户获取实际内容,这会令首次运行经验变成额外的一步(a cumbersome multi-step process)。

  2. 提示信息是否会中断或增加用户操作?

    仔细考虑如何显示信息会增加用户的操作流程。在不影响用户操作的情况下可能有更合适的方式去显示提示信息。

    想象一个场景,用户完成一个动作,你认为很完美的。你认为需要二次确认(double-checking)的,为了防止用户意外出错。所以你弹出一个提示“你确定这样做吗?”,这阻止了用户的一个大的错误操作,但对于确定要执行这个动作的用户来说,你增加了一个额外的操作。作为替代,你可以运行操作立即执行,同时在操作后增加一个撤消的功能。

  3. 等待时如何让用户静心(reassure)

    面对现实吧,有些时候用户不得不等待。然而,你可以做一些工作使不可避免的等待时间变得比较好度过(bearable)。

    如果用户等待的时间较长,使用进度条。进度条不只表明必须等待,同时粗略的显示要等多久。如果要更详细一点,甚至可以显示已经完成的数据(例如 40kb of 64kb)。尽量避免估算完成时间,因为连接速度波动时,没有什么比看到完成时间一直在增长更郁闷的了。

    当用户等待的时间较短时,可以用 loading 指示器。loading 指示器通常是一个旋转变化的小东东(a spinning doo-dad of sorts),但也可以是很简单的文字"loading"。

    你也许会问,为什么极短的时间也要显示这些?loading 指示器是给用户的反馈:用户的操作已经通过,网站正在执行。没有指示器的话,用户不确定是否执行,从而可能企图再次尝试。

延伸阅读

这些建议只是为用户设计时需铭记的事项中的冰山一角。下面是一些可以让你入门(get you started)的关于交互设计和 Web 设计原则的资料:

2009年6月29日星期一

[翻译]减少 reflow

浏览器为了重新渲染部分或整个页面,重新计算页面元素位置和几何结构(geometries)的进程叫做 reflow。由于 reflow 是一种浏览器中的用户拦截(user-blocking)操作,所以了解如何减少 reflow 次数,及不同的文档属性(DOM 层级(DOM depth),CSS 效率,不用类型的 style 变化)对 reflow 次数的影响对开发者来说非常必要。有时 reflow 页面中的一个元素会 reflow 它的父元素(译注:这里是复数)以及所有子元素。

有多种用户操作和 DHTML 变化可能会触发 reflow。调整浏览器窗口的大小,用 javascript 计算样式(computed styles),在 DOM 中创建删除元素,改变元素的 class 都会触发 reflow。值得注意的是,有些操作会多次触发 reflow,超出你的想象。下图源自 Steve Souders 的演讲 "Even Faster Web Sites":

从上表可以很明显的看出,在所有浏览器中并非所有 javascript 控制的样式都触发 reflow,即使触发了触发的次数也不尽相同。同时可以看出现代浏览器在控制 reflow 次数方面做的越来越好。

 在 Google,我们通过多种方式对我们的页面及 Web 应用测速,同时 reflow 是我们增加 UI 时考虑的一个关键因素。我们致力于传达轻快的(lively),交互性强的(interactive)和令人愉悦的(delightful)的用户体验。

原则

下面是一些减小 reflow 的原则:

  1. 减少不必要的 DOM 层级(DOM depth)。改变 DOM 树中的一级会导致所有层级的改变,上至根部,下至被改变节点的子节点。这导致大量时间耗费在执行 reflow 上面。
  2. 尽量减少 CSS 规则,去除未用到的 CSS。
  3. 如果做复杂的表现变化,如动画,让它脱离文档流。用绝对定位或 fixed 定位来完成。
  4. 避免不必要的复杂的 CSS 选择器,尤其是后代选择器(descendant selectors),因为为了匹配选择器将耗费更多的 CPU。

在下面的视频中(译注:引用自 youtube,请翻墙),Lindsey 介绍了一些减少 reflow 的方法。

延伸阅读

[翻译]减小 HTML 文件

改善网站速度的一个很明显的方法是减小 HTML 文件的大小。有一些方法,比如:硬压缩(rigid compression),acupuncture-like ID 及改变 class 名(译注:这一句不是很确定,原文:There are several ways to do this, from rigid compression to acupuncture-like ID and class name changes)。下面是一些我们总结的使 HTML 标记更精简的方法。

译注:上面是引用 youtube 的视频,请翻墙观看。

HTML 4

HTML (非XHTML),MIME type 为 text/html ,允许省略一些标签。通过 HTML 4 DTD,你可以省略以下标签(那些所谓可避免的元素,这里用删除线加以标记(感谢一楼的翻译))

</area>
</base>
<body>
</body>
</br>
</col>
</colgroup>
</dd>
</dt>
<head>
</head>
</hr>
<html>
</html>
</img>
</input>
</li>
</link>
</meta>
</option>
</p>
</param>
<tbody>
</tbody>
</td>
</tfoot>
</th>
</thead>
</tr>

比如,你的代码是

<li>List item</li>

可以写为

<li>List item

又比如段落要以

</p>

结尾,你可以只写

<p>My paragraph

甚至可以去掉 html,head,body(把这作为你的编码规范之前请确保这会令你舒服)。

省略标签后 HTML 依然有效,同时减小了文件大小。对一般的页面来说,可以节省 5-20%。

HTML 5

正在发展中的 HTML 5 提供了一些减小文件大小的方法。

比如,页面文档类型声明

<!DOCTYPE html>

对比

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

很显然 HTML 5 的 DTD 更短。

当为页面指定编码时,HTML 5 很易用而且更短:

<meta charset="utf-8">

代替

<meta http-equiv="content-type" content="text/html; charset=utf-8">

通常情况下,浏览器会正确处理 HTML。

另外,在今天的 HTML 5 中,你可以去除声明 MIME 类型的 type 属性,比如

type="text/css"
type="text/javascript"

你可以用

<script>
替代
<script type="text/javascript">
<style>
替代
<style type="text/css">

在所有类型的页面中(甚至是 XHTHML)你可以省略

type="text/css"

HTML 5 使这一切变得更简单。

同时使用上面所有的方法会使文件节省 10%-20%(甚至更多),这取决于你的编码风格和页面中的文本内容数量。代码将更干净,访问者会更快的获取网站内容。在隐私中心项目中我们采用很多这类技术,节省了原始文件大小的 20%。

2009年6月28日星期日

[翻译]谨慎使用 Iframe

使用 iframe 可以轻易的调用其他网站的页面,但应谨慎使用。它比创建其他 DOM 元素(包括 style 和 script)多耗费数十甚至数百倍的性能。增加100个不同元素的时间对比显示 iframe 是多么耗费性能:

使用 iframe 的页面通常没有这么多 iframe,所以创建 DOM 的时间不用多虑。更值得关心的是 onload 事件和连接池。

iframe 阻塞 onload

window 的 onload 事件尽快执行非常重要。这会让浏览器的载入进度指示器完成,用户依据此判断页面是否已经加载完。而 onload 事件延迟,会让用户感觉页面变慢。

window 的 onload 事件直到它所包含的所有 iframe,以及所有 iframe 中的资源完全加载完成后才会触发。在 Safari 和 Chrome 中,用 javascritpt 动态的给 iframe 的 src 赋值可以避免这种阻塞行为。

一个连接池

对每个 web 服务器来说,浏览器只打开极少的几个连接数。老的浏览器,包括 IE 6/7 和 Firefox 2,每个主机只有2个连接。在新的浏览器中,连接数增加鸟。Safari 3+ 和 Opera 9+ 增至4个,Chrome 1+ 、IE 8 及 Firefox 3 增至6个。对比表格详见《并行连接数总结》。

人们可能期望每个 iframe 有单独的连接池,但并非如此。在大多数浏览器中,连接被主页面和它的 iframe 所共享,这意味着有可能 iframe 中的资源占用了可用连接而阻塞了主页面的资源加载。如果 iframe 中的内容同等重要,或比主页面更重要,这很好。然而在通常情况下 iframe 中的内容对页面来说不太重要,iframe 占用连接数是不可取的。一个解决方案是在优先级更高的资源下载完成后再动态的给 iframe 的 src 赋值。

美国的10大网站中有5个使用了 iframe。它们多数用来加载广告。这不是很合适,但可以理解,这是一个简便的在内容中插入广告的途径。在很多情况下,使用 iframe 是合理的。但要意识到这对你的页面的性能影响。非必要时,请谨慎使用。

2009年6月23日星期二

谨慎使用 CSS Sprites

CSS sprites 是网站速度的优化很重要的一环,但也有其对性能的不利之处。

Vladimir Vukićević 的博文《To Sprite Or Not To Sprite》提到:

CSS sprites 的最大问题是内存占用。非精确构造的 sprite 图片会占用意想不到的内存空间。以 WHIT TV 网站为例,这里是一张 sprite 图片,1299x15,000 的png,已经经过很好的压缩,实际下载大小只有26K左右,但是浏览器不会转换压缩的图像数据。当图片下载并解压,将耗费75MB内存(1299 * 15000 * 4)。如果图片没有阿尔法透明,可能会减小到1299 * 15000 * 3,可往往还是牺牲了渲染速度。即便如此,我们占用了55MB内存。这张图片绝大部分是空白的,什么都没有,没有什么有用的内容。仅仅因为这张图片,当浏览器只加载WHIT 主页时会增加75+MB内存。

Mozilla Web Development Blog 在《 Use Sprites Wisely》中总结道:

简而言之,即使是很小的 sprite 图片也有可能吃掉大量的系统内存 -- 每个页面50M甚至100M或者更多。速度虽然至关重要,但要意识到 sprite 及其他 hacks 同样会影响用户体验。

现在再回过头看之前的《Yahoo与Gmail的CSS Sprites对比》,综合性能方面 Gmail 无疑占了上风。当然,这些只是前端层面的优化,从根源上来看,设计师用最少的图片来实现最优的效果才是王道。

正如雅虎女工程师 Nicole Sullivan 在 Velocity 2009 大会演讲 PPT 《The Fast And The Fabulous》所提到的:

consistent design = clean code = fast site(一致的设计 = 更干净的代码 = 更快的网站)

2009年6月19日星期五

[翻译]简化CSS选择器

本文是《Even Faster Web Sites: Performance Best Practices for Web Developers (Paperback)》的最后一章。上篇帖子《Performance Impact of CSS Selectors》(中文版)最后提出了一段假设:

对大多数网站而言,优化CSS选择器活得的性能提升很小,不值得去计较。有些配合Javascript交互的CSS规则会明显的拖慢页面。这是应该关注的焦点。所以我开始关注现实中影响页面性能的CSS样式相关的小问题。

我收到了很多反馈。David Hyatt的文章《Writing Efficient CSS for use in the Mozilla UI》披露:

样式系统渲染一条规则是从最右边开始之后依次向左移动。在你的小子树(subtree)持续检测的时候,样式系统将继续向左侧移动直到它不匹配CSS规则或匹配错误。

由此得出,我们优化工作的重点应该是:匹配大量页面元素的最右侧的CSS选择器。我上篇博文测试的CSS选择器看起来很费性能,但是按这条新观点审视,我们发觉这其实不值得担心,比如:

DIV DIV DIV P A.class0007 {}

这个选择器有5层,看起来很复杂,但是我们来看最右侧的选择器 A.class0007 ,我们发现,在整个页面中需要浏览器逆向匹配的只有一个元素。

优化CSS选择器的关键点在于最右侧的选择器,也叫做key selector (巧合?)。有一个更昂贵的选择器

A.class0007 * {}

尽管这个选择器看起来更简单,但对浏览器匹配而言更昂贵。因为浏览器要从右至左,开始后要检查匹配 * 的所有元素。这意味着浏览器会尝试匹配页面中的所有元素。下图为普通选择器与先前的后代选择器加载时间的对比:

它清晰的反映出一个匹配很多元素的key selector会严重的拖慢页面。其他可能会大量增加浏览器工作的key selector包括:

A.class0007 DIV {}
#id0007 > A {}
.class0007 [href] {}
DIV:first-child {}

不是所有的CSS选择器伤害性能,尽管看起来如此。CSS选择器的关键点在于泛匹配的key selector。这对于含有大量DOM元素、CSS规则,更高 reflow 的Web 2.0应用更加重要。

[翻译]CSS选择器的性能影响

一些关于CSS选择器性能的讨论引起了我的兴趣。

第一个是Shaun Inman写的《合格的CSS选择器(CSS Qualified Selectors)》,实际上这篇博文并没有提到CSS性能,不过有一个来自David Hyatt(Safari 和 WebKit 的架构师,同时为 Mozilla, Camino, Firefox 工作)的评论:

如果你非常在意页面的性能那千万别使用CSS3选择器。实际上,在所有浏览器中,用 class 和 id 来渲染,比那些使用同胞,后代选择器,子选择器(sibling, descendant and child selectors)对页面性能的改善更值得关注。

接下来的一篇博文很神奇。Jon Sykes做了一个系列的文章来测试CSS性能:第一部分, 第二部分, 第三部分,其中 第三部分非常值得一读。这使我确信优化CSS选择器是页面性能优化的一个关键步骤。

但是,有两件事一直困扰着我。首先,大量的DOM元素和CSS规则。页面包含60000个DOM元素和20000条CSS规则。这使浏览器非正常的运行(下面将证明这点)。下面的统计表格为美国10大网站的比较:

网站名称 CSS规则 DOM元素
AOL 2289 1628
eBay 305 588
Facebook 2882 1966
Google 92 552
Live Search 376 449
MSN 1038 886
MySpace 932 444
Wikipedia 795 1333
Yahoo! 800 564
YouTube 821 817
平均值 1033 923

第二件困扰我的事情是测试以多大页面为基准?我想解决的问题是:无效率的CSS选择器会拖慢页面吗?所有测试的5个页面包含20000个a元素(嵌套在P, DIV, DIV, DIV内部)(译注:使用同样的HTML页面),不同的是CSS:基准(没有CSS)(译注:下图中的baseline),标签选择器(tag selector )(a标签有一条CSS规则)(译注:下图中的tag),20000个class选择器(class selectors)(译注:下图中的class),20000个子选择器(child selectors)(译注:下图中的child),20000个后代选择器(descendant selectors)(译注:下图中的descendant)。后面3个页面的大小都超过了3M,而基准及标签选择器的页面则只有1.8M。

接下来调整为:

  • 2000个a标签和2000条CSS规则(原先是20000),这实际上有6000个左右的DOM元素,因为a嵌套在P, DIV, DIV, DIV内部
  • 基准页面和标签选择器页面像其他页面一样有2000条CSS规则,不过只有简单的class规则生效,不会影响其他含有class属性的标签

我在12个浏览器上进行了测试 。页面呈现时间是用嵌在头部和底部的脚本来测量(所有测试在本地运行)。测试结果如下图(我没有测试Oprea 9.63,你可以下载csv格式的数据这里是测试页面):

性能随浏览器而改变;奇怪的是,两个新浏览器IE 8 和 Firefox 3.1反而是最慢的 所有测试是在同一台PC机的不同浏览器,不同PC机的不同浏览器可能有不同的性能特点。这个测试的目的不是比较各浏览器的性能,而是为了测试浏览器如何处理逐渐复杂的CSS选择器。

【修订:更深入的比较Firefox 3.0和3.1,我发现这台PC上的Firefox 3.1和IE 8逊于其他PC机。即使再进行测试,也会由于不同PC的硬件差异导致不同的结果,所以,不要用这些数据来比较浏览器。】

毫不意外,越复杂的页面(子选择器和后代选择器)通常性能越差。最大的意外在于第四个页面居然是最差的。所有的浏览器平均慢了50毫秒,观察最大的(IE 6&7, FF3)平均只有20毫秒。对现在70%+的用户来说,改进CSS选择器只能提高20毫秒。

请记住,这些测试接近最坏的情况。20个a标签嵌在P, DIV, DIV, DIV导致总共有6000个DOM元素,这是10大站点中最复杂两个网站(见表一)的两倍大。另外,测试的页面含有2000个极端无效的CSS规则,一般的网站大约有三分之一(译注:网站本身的CSS规则)的子选择器及后代选择器。以Fackbook为例,2882个CSS规则里只有750个极端无效的规则。

为什么我的测试结果和之前其他人的有些不同?一个不同来自于这极其极端。它成倍的放大于我们通常所用的页面。在这种情况下,浏览器面对3M的页面,60000个DOM元素及20000条CSS规则会有不同的表现。我注意到,我的测试结果在IE6&7中非常不同。我想知道IE在处理CSS选择器时是否某个规则。为此我测试了子选择器和后代选择器页面,从1000至20000逐渐增加a标签和CSS规则的数量,结果如下图所示,IE在18000条CSS规则时陡增。但是IE 6&7 渲染页面更接近实际,因为在我的测试中,他们的性能竟然是最高的。

基于这些测试我有以下假设:对大多数网站而言,优化CSS选择器活得的性能提升很小,不值得去计较。有些配合Javascript交互的CSS规则会明显的拖慢页面。这是应该关注的焦点。所以我开始关注现实中影响页面性能的CSS样式相关的小问题(offsetWidth, :hover)。

译注:

  • 这是本人的处女翻
  • 并非一字一句的直翻,原则是尽量保留有用的内容
  • 水平有限,难免糟蹋了大师的作品,有疑问请自行到原文查阅
2009年6月13日星期六

RSS全文Feed集中贴(2009-9-27更新)

2009-9-28

2009-9-27

2009-7-23

2009-7-15

2009-7-14

之前的:

以后发布的feed集中在此帖更新(删除的话也在写在这里)。

2009年6月4日星期四

Google Reader的新功能?

像往常一样使用GR,不过有时会莫名其妙多出一个搜索框,如图:

不过这个表单还用不了,让我们拭目以待!

给博客套了个域名

Blogger被墙,为了照顾不会翻墙的众粉丝,特套上一闲置已久的域名99css.com(缘自某著名H站99**s)。图片已改为pisaca上的链接,墙内粉丝也可以访问,评论页面目前也很正常。

订阅地址依然是:http://feeds2.feedburner.com/ytzong

已订阅blogspot的话不用更改,blogspot会自动转向

目前还是用Blogger来写,前两天试了下,可以很轻松的将文章及评论转到wordpress,不过习惯股沟的产品了,暂时不会转。

再强调一下:是昨天晚上套的域名,不是今天

2009年6月1日星期一

折腾下 Chrome

前言

Chrome 2 开始支持Greasemonkey,Chrome 3 开始支持扩展...离我们换浏览器越来越近了。

自定义用户数据目录

以XP为例,下同

默认位置 C:\Documents and Settings\Administrator\Local Settings\Application Data\Google\Chrome\User Data

要更换到 E:\Chrome 的话:

  1. 在快捷方式上点右键,选属性,切换到快捷方式选项卡,在目标一项中加上 --user-data-dir=e:chrome
  2. 形如 "C:\Documents and Settings\Administrator\Local Settings\Application Data\Google\Chrome\Application\chrome.exe" --user-data-dir=e:chrome
  3. 点击确定
  4. 重启Chrome后 E:\Chrome 文件夹中会自动生成相关数据。

自定义升级版本

下载并运行 Google Chrome Channel Changer ,有3个选项可供选择:

  • stable,稳定版,推荐追求稳定的普通用户使用,更新最慢。
  • beta,测试版,有一定新功能,但是可能会存在不稳定情况,适合喜欢尝鲜的朋友使用,更新速度一般。
  • dev,开发版,更新最快,新功能最多,但是可能非常不稳定,适合开发人员使用。

Chrome 2+ 开启Greasemonkey

  1. 在快捷方式上点右键,选属性,切换到快捷方式选项卡,在目标一项中加上 --enable-user-scripts
  2. 形如 "C:\Documents and Settings\Administrator\Local Settings\Application Data\Google\Chrome\Application\chrome.exe" --user-data-dir=e:chrome --enable-user-scripts
  3. 点击确定
  4. 将你想要的脚步拷到 E:\Chrome\Default\User Scripts 中
  5. 重启 Chrome

获取 Greasemonkey 请到 http://userscripts.org/

另外一部分 stylish 也提供用户脚本,比如我写的这个Gmail去广告stylish:http://userstyles.org/styles/15631

Chrome 3+ 开启扩展

  1. 在快捷方式上点右键,选属性,切换到快捷方式选项卡,在目标一项中加上 --enable-extensions
  2. 形如 "C:\Documents and Settings\Administrator\Local Settings\Application Data\Google\Chrome\Application\chrome.exe" --user-data-dir=e:chrome --enable-user-scripts --enable-extensions
  3. 点击确定
  4. 重启 Chrome

开启后用Chrome打开以下站点,点击安装即可(类似 Firefox) 目前有几下扩展可用:

  • Gmail Checker:该扩展可以显示你Gmail 里有多少封新邮件 点此安装(可能需翻墙)
  • Subscribe in Google Reader:该扩展可以帮助你订阅站点的RSS 到Google Reader, 已经订阅的站点会显示打勾状态 点此安装(可能需翻墙)
  • AdSweep 一个类似AdBlock的扩展,可以隐藏页面上的广告。它通过JavaScript调整页面的CSS,也可以当做一个用户脚本 点此安装
  • Page Rank for Chrome 显示当前页面的PR值 点此安装
  • Cleeki 类似IE8的加速器 点此安装

参考文献: