岁月如歌

用开放的心态,打造专业的人生。

空路径对页面性能的影响

with 19 comments

今天同事小凡反馈,淘宝有个商品详情页,旺铺皮肤的 CSS 文件在 Firefox 下很奇怪的被加载了两次。最近对 detail 的渲染速度进行了优化,因此遇到 bug 第一反应是往优化方面找原因。然而调试了许久才发现,该 bug 居然是一个在淘宝深藏了很久的 bug, 在 IE 下会导致一些糟糕的情况产生。一身冷汗,立刻分析解决之。

这个 bug 并不新鲜。早在 2009 年,Nicholas C. Zakas 就发现了空 src 的危害性:Empty image src can destroy your site.

Nicholas 的发现可以概括为一句话:img, script, link 的 src/href 为空时,有可能会导致冗余请求。

今天这个 bug 的起因,可以补充 Nicholas 的发现:CSS 里,background url 为空时,也有可能会导致冗余请求。

除了空值,还有一个值也会出问题:#值。 比如 <img src=”#”>

具体测试结果请看:test.html

从测试结果中可以看出,#值比空值更糟糕。比如 background: url(#), 直接会触发一个新请求。这次旺铺皮肤的样式文件在 Firefox 下被加载两次,就是因为第三方设计师在 css 里写入了 url(#). css 外链时,考虑静态资源的缓存,重复请求引发的问题并不大。但当 css 内嵌时,在 IE 下会引发一个相对于当前页面的 index 请求,这就比较糟糕了。

解决方案:

  1. 等待浏览器自身的改进。Nicholas 在 2009 年就开始推动各浏览器厂商,现在看起来就 IE 修复得还可以,Firefox 依旧会从本地缓存中读取一次(重复读取有可能会导致 js/css 的再次 parse + execute,浪费呀)。对于#值,则目前所有浏览器都未考虑周全。
  2. 改变代码习惯。严禁代码中,url/href/src 值为空或 # . 这应该是目前最好的一种方式。
  3. 经验教训:对于开放 CSS 的系统,源码检查时,要加入对 background/background-image: url()/url(#) 的检查。

点滴经验,与君共勉。

Advertisements

Written by lifesinger

September 22, 2011 at 23:13

Posted in Articles

19 Responses

Subscribe to comments with RSS.

  1. 对于空的url引用我在使用中一直使用着这种写法background-image: url(about:blank)
    这也只是在解决IE的一些bug时用到,实际中到真的没有留空过。
    像link的src也都是在使用时通过创建标签的方式,没出现过空的情况!

    asinsimples

    September 23, 2011 at 00:52

    • 前端一般不会犯这个错误。出现这个问题,经常是因为开放 css 导致。比如 wordpress 主题、淘宝旺铺皮肤等,这时很难保证所有提交的代码都无此类问题,因此需要经过校验,将空路径添加到校验规则里。

      lifesinger

      September 23, 2011 at 07:33

      • 少数前端会留意这个问题,大多数前端压根没考虑过这个

        杜仲

        March 14, 2014 at 11:54

  2. 类似问题两周前刚在收藏夹需求中遇到过。CSS中,url为空的情况的检查是不是能放到RMS中来做?

    Adam Lau (@helloleo)

    September 23, 2011 at 01:01

    • 好建议,我反馈给云翼,看能否做一下。

      lifesinger

      September 23, 2011 at 07:31

  3. 哈哈,1年前写项目时候遇到过,当时是jsp页面,过滤器每次都有2次 或者更多请求。
    当时主要是img src=“”

    mysoko

    September 23, 2011 at 08:28

  4. 没想到链接被转码了:(
    很想了解一下,<a href=”#” >这种写法会出现什么问题么?会在哪些浏览器中出现问题呢?我看了淘宝首页的代码,href的# 被 href=”javascript:void(0);” 替代了。

    泡面

    September 23, 2011 at 09:50

    • a href 和 iframe src 一样,为空值和#值不会引发问题。

      lifesinger

      September 23, 2011 at 11:00

      • 那可以说一下淘宝首页空链接使用a href=”javascript:void(0);” 么?是为了避免使用#号而没有return false而导致页面滚动回顶部么?还是有啥其他原因?因为我接手的一个项目里面空链接全部使用了a href=”javascript:void(0);”,而我一直使用#和用脚本return false的方式来阻止空链接的点击返回,本来准备把原来项目中的 href=”javascript:void(0);”全部换掉,现在看了您这篇文章,我又犹豫了。

        泡面

        September 23, 2011 at 12:17

    • @泡面:这篇文章不涉及 a 的 href. 对于 <a href=””> 来说,用 # 或 void(0) 都没问题的,看个人喜好了。

      lifesinger

      September 23, 2011 at 13:19

      • 明白了,是我理解错误了,感谢您耐心的回复。

        泡面

        September 23, 2011 at 15:40

    • 用a href=”javascript:void(0);”的方式也会出现问题,在IE6下就遇到过阻断socket的情况

      TerryLee

      September 23, 2011 at 13:27

  5. 我这有一篇 background:url(#)的性能问题 http://www.99css.com/archives/528
    评论里有两个方法不错 background:url(data:) url(about:blank)
    鉴于此,CssGaga 已经早就默默把url(#)转换为url(about:blank),恩哼~

    ytzong

    September 23, 2011 at 18:38

  6. background:url(localhost);

    看来我比较损。。。。

    fengyin

    September 23, 2011 at 23:35

  7. 感謝分享,這文章的確讓我瞭解些前端的小問題

    Caesar Chi (@clonncd)

    September 26, 2011 at 01:15

  8. […] 空路徑對頁面性能的影響 […]

  9. […] Reader 中看到玉伯博客的分享——空路径对页面性能的影响。确实,在写 CSS 的时候,用 […]

  10. 您好,请问这样的写法会不会产生冗余的请求?或者兼容性之类的问题?

    hm

    September 30, 2011 at 16:01


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s