西红柿爱番茄

Feed Rss

这几天没发博文,一是忙着开发自己的Perl编译脚本,另一方面是连续几天的上线,倒腾到深夜,所以来公司比较晚,就间歇了几天功夫没进行站点分析的事情。今天早上又早来了,兴奋中。。。

奇艺网(http://www.qiyi.com/)

  1. 页面对ipad、iphone、android等移动设备进行了检测,并对这些移动设备做不同的处理。不过页面头部的那两段对iphone、android的处理,长的很像,或许可以抽取出来,封装为独立的功能函数,对于不同的地方使用参数自定义。
  2. 页面的html、js、css之间混合有些多。在html标签中使用了行内的样式和on事件声明,这个从自定义出发、或者说这个模块修改比较频繁、不是由开发人员维护,那么使用这样的方式,或许会更好一点,至少不会添加整个页面的css样式文件对这些经常变化的内容进行样式、脚本的管理。
  3. 页脚footer的标签的处理,完全可以不对那个灰掉的竖线进行span加class的方式处理,因为其他的都是链接,折行的文本又加了class fEn,那么就在footer中声明整体的颜色为灰色的就可以了,可以删掉一坨<span class=“fGray”></span>。
  4. 对页面中的资源进行了分域名处理。static.qiyi.com,qiyipic.com,根据Page Speed的建议,页面中全部的影视介绍图片,都是来自qiyipic.com域下,图片量达到了一百多个,那么就很有必要需要对这些图片再进行一次域名划分,来增加并行加载的数量。
  5. 对ipad的处理算是废了很多苦心了,页面中很多的行内脚本、行内style标签都是为了处理在ipad下的特殊行为,包括lib.ipad、!lib.ipad都有处理。这个从整体上样式、脚本、结构的整合看起来有些混乱,维护起来有些困难。页面内也穿插了比较多外链的js文件。
  6. 整个页面对ipod、iphone、ipad、android都进行了处理,这个似乎是视频网站都必须具备的检测功能,优酷目前也还没有对android进行检测。稍微对比了一下奇艺跟优酷的页面源码,在页面结构、样式、行为的架构上都类似,有些乱,难道是通病,还是有其他更多的原因?

BBC(http://www.bbc.com/)

  1. Head标签中使用了IE特有的判断,对不同的IE版本使用了不同的css主文件。如果页面还使用HTML5的HTML页面模板,那么就基本吻合HTML5模板页面的。这一点是微不足道的,还有一点值得说的是:对js、css文件版本的控制。这个控制版本升级,使得用户的浏览器总能够下载到最新的版本很重要,一般有两种方式:使用时间戳;版本号。而这里,简单的一个“53”,估计也是版本号。头部对IE特有注释使用的可谓是够绝的了。
  2. Head标签中js、css文件的加载顺序似乎并没有怎么讲究,穿插其中,有些混乱。使用了很大的js篇幅来初始化页面,而且document.write有点横行。
  3. 看到一个比较新奇的js加载modulo的方式:
    [javascript]
    gloader.map.add("modulo", {
    $version: "1.0.0",
    $base: "http://static.bbc.co.uk/wwhomepage/js",
    "modulo": "{$base}/bundles/international/main.js?53",
    "modulo.delegate":"{$base}/bundles/international/main.js?53",
    "modulo.storage": "{$base}/bundles/international/main.js?53",
    "modulo.ajaxbuffer": "{$base}/bundles/international/main.js?53"
    });
    [/javascript]
    使用上面的编写方式,还是挺有意思的。
    同时,在js的加载方面,也使用了下面的方式:
    [html]
    <script type="text/javascript" src="http://node1.bbcimg.co.uk/glow/gloader.0.1.3.js">
    gloader.use("glow", {map: "http://node1.bbcimg.co.uk/glow/glow/map.1.7.3.js"});
    </script>
    [/html]
  4. 从网站性质以及页面的设计方式来说,BBC是一个新闻网站,信息的分类自然很重要,对于不同的用户对BBC网站所提供的内容的需求是不一样的,那么就很有必要的需要提供自定义的功能,让用户可以定制自己想要的信息。所以,BBC将整个页面基本设置为自定义、排序、语言选择、信息选择等等。从用户体验上来说,很到位。
  5. 页面中很多内容都是使用BBC.adverts.write生成,整个页面中js行内脚本穿行,这样做造成的问题是:整个页面的渲染都受到了N多个行内script标签的阻塞。行内脚本对页面渲染的阻塞是完全的。在新版本的FF下,js的加载可以跟css等资源并行加载,但是在IE下,就比较杯具了,页面的渲染到最终显示花了比较长的时间,而且还是在公司M级的网络。统计了下,页面中script标签有52个。
  6. 看到了一个比较贴切的满足某种统计(或者其他的需求)的方式:
    [html]
    <noscript>
    <div>
    <img src="http://pixel.quantserve.com/pixel/p-ccrmZLtMqYB8w.gif" style="display: none;" height="1" width="1" alt="Quantcast"/>
    </div>
    </noscript>
    [/html]
    根据这个图片的展示率可以得到某种统计,在淘宝的页面也看到了同样的方式。

淘宝网(http://www.taobao.com/)

  1. 在页面中,有些img标签使用了自定义属性:data-ks-lazyload。并且这个自定义属性的属性值是图片URL,这个很容易让人想到这个是用于delay加载图片的方式,或者是按需加载。使用自定义字段的方式,处理起来比较简单,通过一个循环就可以处理得来。或者使用textarea控件,里面放img的全部的url,按需从textarea控件里去url,读取图片。
  2. 对于页面中的会根据用户是否登陆来显示不同的信息的部分,比如右栏上角的用户信息区域,会根据用户是否登陆来显示不同的信息,而这些显示的内容(HTML代码),是储存在每一个textarea控件中的。并且使用rel作为“编号”。这个跟使用json的方式也还是可以的,不过json还需要解析,如果使用的还是“裸”数据的话,还得进行一次HTML的拼装,处理起来相对来说比较麻烦。但是如果是对于HTML结构类似,数据形式相似的情况下,从节省宽带上考虑,使用json还是比较好的选择。
  3. http://a.tbcdn.cn/??s/kissy/1.1.3/kissy-min.js,p/header/header-v8-min.js?t=20101221.js
    这个js文件放到的head部分加载,先不说是架构上的考虑,也或者页面中其他功能的初始化需要立即使用到这个js文件所提供的功能,在页面初始化的时候,最快的方式使得页面的功能能够使用,提高可用性,避免用户在跟页面交互的时候没响应的情况,出于这个因素考虑的话,还是有一定的道理。但是它必定会对页面的后续资源造成阻塞。
  4. 在head标签内使用了base标签来定义超链接的默认打开方式为_blank,查询了页面超链接target的声明,_self等的声明还是比较少的,这个做法比较好。但是有些链接中还是多余的声明了target为_blank。
  5. 对一些资源的加载使用了按需加载的方式,比如检测scroll事件来加载下一屏幕的资源。这个对于一些门户网站在宽带上的节省还是比较有效的。但是要考虑到这样的一种情况:如果使用的宽屏的屏幕的时候,页面的全部内容在整屏幕都展示了,而没有出现垂直滚动条,这个时候应该加上监控document的viewport的功能来判断是否加载后续的资源。
  6. 页面的头部还声明了一些样式属性,这个从代码上看,应该是针对首页的特定部分所使用到的样式,既然都使用了合并几个css文件进行加载了,那么定义一个该页面的私有css样式文件会不会更好点呢?从这点考虑,口碑所实行的方式,还是比较优越的。
  7. 在body标签的开始处,出现了两段长的很像的js代码,从代码可复用性来看,或许可以对它们进行函数封装。
  8. 从减少一点点代码来考虑,左边导航处的li标签,可以使用id来代替class,因为对于每一个li的私有样式都是唯一的。
  9. 页面的HTML代码没有进行相应的压缩,所以整个页面的代码看起来很庞大,或者可以试行HTML代码压缩的方式。
  10. 页面中标签自定义字段的名称的命名方式有几种:data、data-resid,data-active-index,在超链接中阻止超链接默认行为的方式也出现两种:javascript:void(0)、javascript:;。
  11. 页面中有很多隐藏的信息都放置在一个隐藏掉的textarea控件中,这个不从动态加载速度、渲染速度上考虑,出于这种方式的选择,而不是采用基于用户事件驱动动态请求内容的方式,有一个原因就是用户对于这些隐藏的内容的显示需求相对较高,很大比例的用户会去查看隐藏的内容,那么这个时候就要考虑到可用性、用户体验方面的问题了,最快速的显示给用户所需要的内容。否则,使用基于用户事件驱动的动态加载方式,在节省带宽上的收益更明显。

经过几个晚上的一点点升级,将之前搞的perl编译脚本进行了重构,并添加了一些功能,包括文件嵌套编译、添加对html文件的简单压缩、添加Google Compiler的压缩模式、修改了文件输出的方式等等。(具体的教程,可以查看:自动化工具提高工作效率中的描述)

在perl文件的头部,添加了几个配置项:
$yui_compressor_path:YUI compressor 的jar文件的路径(建议是本地的绝对路径)
$google_compiler_path:Google Compiler的jar文件的路径(建议是本地的绝对路径)
$compress_type:所使用的压缩方式,值可以为:yui/gc。
$compilation_level:Google Compiler压缩的级别,值可以为:SIMPLE_OPTIMIZATIONS/ADVANCED_OPTIMIZATIONS/WHITESPACE_ONLY
$output_dir:编译后的文件的输出目录(建议是跟当前需要编译的文件同一目录下)

建议是在每一个开发目录下配置一个build.pl文件,那么就可以对在当前的目录下进行开发,最后build编译。如今编译的文件都会保存在当前目录下的output文件夹里,文件名不变,可以直接使用编译好的文件进行测试、发布。

如下图所示的嵌套包含示意图,理论上可以无限级的嵌套,压缩:

可以对当前级声明compress:true进行压缩,嵌套之后,在output文件夹中会有中间产物页面产生,但是对于最终页面是没影响的。这样,就可以将几个页面中通用的部分抽取出来,统一管理

最新的build程序:build_1_0_3_linux.rarbuild_1_0_3_win.rar

土豆网(http://www.tudou.com/)

  1. 查看Http瀑布图,http://js.tudouui.com/js/lib/tuilib_57.js,加载这个js文件对后续的资源的阻塞比较严重。这个是土豆网内部的一个库吧,可是对它的加载,却阻塞了后续使用js来加载的内容。可能是后续js的解析需要使用到这个库,是否可以将这个使用js动态创建HTML的功能跟这个库分离呢。
  2. 在资源的分配上,对js、css、image等资源都分域名处理,js.tudouui.com,css.tudouui.com…在图片上,又进一步划分。就tudou内部的资源的域名划分,就达到了十几个。DNS lookups花费的时间会比较多,但是如果从资源管理方面来衡量,也会有一定的合理之处。Yahoo的减少DNS lookups的优化规则在一些特定的需求的衡量下,或许可以不考虑。但是一个DNS lookup的时间消耗大概都会在20ms左右。
  3. 通过page speed查看首页的分析分数,得到了97。偌大一个首页的页面,在代码层面做的优化还是比较好的,比如:代码压缩(js、css、html)、优化图片、合并css、js等等。
  4. 整个页面的HTML代码进行了压缩,而这个工作我想并不是通过在后端输出数据的时候,对代码进行空格删除那么简单,而是通过一个系统的工具,对每一个模块的HTML代码进行压缩。
  5. 页面中的超链接中有很多的target=”_blank”(通过查找,发现有四百多个),是否可以作出这样的权衡:如果页面中内容模块的超链接大部分是需要新窗口打开的,那么就在head标签内声明一个base标签来默认超链接的显示效果,而对于需要target=”_self”的在做显式的声明。
  6. 页面还有一些的内容是通过js来动态加载的,页面源码的底部有很多的js代码就是为了处理这个事情。同时,页面中的广告也是动态加载的。
  7. 对页面中的图片都做了优化,显式声明了height、width属性,这个一方面需要跟后端进行约定对图片的这一处理,同时,还应该需要有这样的一个工具来检测页面的图片是否显式声明了width、height。
  8. 对class的使用上,很简洁,也没有使用命名空间的方式,在语意化方面理解起来有些难度。

FACEBOOK(http://www.facebook.com/)

  1. 在html标签中添加class来标识浏览器是否开启了Javascript功能,并且在body标签中使用class来标识当前所使用的浏览器,并对该浏览器使用相应的样式,这个是优雅的伪hack的方式。
  2. 同样是使用了跟Twitter一样的noscript标签的检测,但是使用了这个之后,再在html标签里使用class来标识当前页面是否开启了Javascript功能,缈似有些多余。
  3. 将页面的HTML代码最大化的压缩。由于facebook的页面很大一部分是有js生成的,数据是json的结构,这个比HTML包装好的数据会小很多,所以在加载上会更快一些,至于到了使用js将json解析出来并且渲染开来的时间跟直接在服务端拼装好HTML代码直接由服务端返回来进行对比,那么就需要一个可靠的工具来衡量了,不能直接通过理论来分析。
    将页面中的HTML代码最大化的压缩,这些可以使用系统压缩的HTML代码一般都是比较固定的代码片段,所以使用工具压缩也比较有保障,不会出现问题。而使用json结构,按照一个约定的接口,是可以最大化的压缩的。
    所以fackbook在这个的衡量上把握的比较好。
  4. 将页面进行模块分析,动态的模块,或者是个性化的模块(因每个用户所不同),使用js对模块的HTML,CSS、Javascript进行管理,各个模块只要负责自己的功能、样式、结构就行了。虽然看起来加载了很多的js、css文件,但是都是通过动态加载的方式,可以并行加载,只是在执行的时候会阻塞页面的渲染而已。最大化的利用浏览器的并发数来加载文件。并且将css、js都放置到一个独立的CDN子域名下,减少DNS Lookup查询的时间。
  5. 页面中所有隐藏的内容,都是通过异步加载,无处不在的异步加载,最小化在初始化中所呈现出来的页面的代码。
  6. 在源码中看到了这样的meta声明:
    <noscript><meta http-equiv=”X-Frame-Options” content=”deny” /></noscript>
    它的作用主要是防止ClickJacking漏洞的。它现在支持下面两个value:
    SAMEORIGIN – allows only sites from the same domain to frame the page
    DENY – prevents any site from framing the page
    http://blog.mozilla.com/security/2010/09/08/x-frame-options/