浏览器的加载与页面性能优化
发布日期:2011年2月15日本文将探讨浏览器渲染的loading过程,主要有2个目的:
- 了解浏览器在loading过程中的实现细节,具体都做了什么
- 研究如何根据浏览器的实现原理进行优化,提升页面响应速度
由于loading和parsing是相互交织、错综复杂的,这里面有大量的知识点,为了避免过于发散本文将不会对每个细节都深入研究,而是将重点放在开发中容易控制的部分(Web前端和Web Server),同时由于浏览器种类繁多且不同版本间差距很大,本文将侧重一些较新的浏览器特性
现有知识
提升页面性能方面已经有很多前人的优秀经验了,如Best Practices for Speeding Up Your Web Site和Web Performance Best Practices
本文主要专注其中加载部分的优化,总结起来主要有以下几点:
-
带宽
- 使用CDN
- 压缩js、css,图片优化
-
HTTP优化
- 减少转向
- 减少请求数
- 缓存
- 尽早Flush
- 使用gzip
- 减少cookie
- 使用GET
-
DNS优化
- 减少域名解析时间
- 增多域名提高并发
-
JavaScript
- 放页面底部
- defer/async
-
CSS
- 放页面头部
- 避免@import
-
其它
- 预加载
接下来就从浏览器各个部分的实现来梳理性能优化方法
Tangram base的设计思路
发布日期:2010年12月30日上周,Tangram开源了,有不少人阅读代码后提出了自己的意见、对Tangram的期望,很感谢这些热心的朋友的支持。与此同时,也看到了一些对Tangram设计的疑问,因此有了这篇文章,主要是想介绍在设计Tangram base时的一些考虑,以及它适合做什么事情。
细粒度拆分
只要看过Tangram文档或源码的人,一定会发现它拆分粒度够细。将每一个方法独立写成一个文件,用户可以通过codeSearch功能,获得定制好的Tangram,然后基于其开发业务组件和逻辑。
在百度来说,前端工程师一直都很关注流量和加载性能,按需定制可以最大程度的节省带宽、加快页面的加载和渲染速度。
同时,Tangram面向的产品跨度广,从搜索产品到社区产品到商业产品,而工程师动手能力都很强,他们能很轻松的基于Tangram提供的方法集,封装一套适合自身的产品底层库。不同的产品间,封装差异会比较大,但是由于底层库相同,交流沟通并不会产生多少障碍。
静态方法,无污染
除了拆分粒度细之外,Tangram库名字空间整洁,所有的方法都是静态的,对环境的污染很小。
一些老产品中总会有一些匪夷所思的代码,而且很多产品中会有第三方代码,为了最大程度的避免冲突,Tangram仅仅暴露一个变量到window中,而且用户完全可以把Tangram放在闭包中使用,这样即使页面上出现两套Tangram,他们之间也不会有任何冲突。
复杂的RIA产品需要一个开发框架时,采用Tangram做为底层库也很有优势,因为Tangram是静态的,封装和覆写都特别方便,如果发现在自身环境下对某些函数有特别的要求(如性能要求极高),可以自己编写新函数覆盖。函数是独立而且简单的,开发人员也可以很方便的对其进行研究,了解原理进而更好的使用。
上面的内容大多是Tangram针对产品团队的设计考虑。而对于一些通用组件开发者,基于Tangram开发时,他可以把Tangram当成一个函数库,仅仅选取他需要的部分,保证组件的体积精简。同时不必遵从Tangram的封装方式,可以按照需求,封装出自己想要的风格然后release。事实上,百度内已经有数个以这种形式存在的通用组件。
改进
Tangram一直都在不断升级,简单说说我们接下来要做的几件事情:
- 修改库中方法调用的baidu前缀,这件事情会在下一个版本发布前完成,做为一个开源项目,它应该保持自己的独立性。
- Codesearch整理后,也会被随项目放出,这样大家就能很方便的在本地选取任何一个版本的Tangram代码了。
- 我们会不断整理Tangram的设计细节,开发规范,工具,并且在社区和blog中发布,即使你不使用Tangram,也完全可以参考和借鉴我们的思路。
- 不断完善文档,良好的中文文档也是Tangram相对其他库的一个优势。
开发团队
在百度FE,我所在的小组叫通用组,负责包括Tangram的所有前端通用技术的研发与维护,所有百度工程师都会贡献代码到Tangram。开源后,Tangram将接受更多来自百度外部的意见,保持Tangram的不断成长和进步。欢迎前往github的network(base,component)围观我们每天的代码提交,更欢迎各位fork,为Tangram提供想法和代码。
小结
这篇文章介绍了Tangram base的设计特点、面向场景等,做为一个基础函数库,Tangram base很容易被封装和扩展,你也可以很放心的使用它来进行二次开发。
Tangram的文档地址是:http://tangram.baidu.com,你也可以前往github查看最新的源码(dev分支)
我们基于Tangram base,开发了Tangram component,这是一个组件库,它的设计考虑和实现方式就更复杂了,这部分留到下次再谈,如果你关注Tangram,欢迎订阅baidu UX blog获得更新。
Tangram 前端库通过 Github 开源了
发布日期:2010年12月24日Tangram 是百度内部一直在开发和使用的前端库之一,功能与 jQuery 、 Prototype 等库类似,主要功能是简化 DOM 操作,并且扩展 JavaScript 语言。这部分功能准确来说属于 Tangram Core ,另外一个叫做 Tangram Component 的库提供一些类似 YUI 、 Sencha 这个级别的组件。
之前 Tangram 说要开源很久了,一直卡在流程上,并且也有人觉得必须把库做得足够好了才好意思拿出来开源。我个人的看法是,跟 John Resig 的一样,前端库应该从第一天开始就开源,因为就算你不开源别人也一样能看到,所以还不如开放出来接受别人的贡献。如果你写得不好,就算你不开源,别人要看也还是能看得到的,所以还是直接把代码晒出来好了,看得不顺眼的可以直接说,实在看不下去了可以动手改,改完了再把代码贡献回来。
说完了我对开源的看法,接下来我们看看 Tangram 和 Git 分别有什么好,先从 Tangram 说起。
Tangram 能做什么
熟悉我的人都知道,我从来不讨论哪个工具更好的,我只讨论在特定的情况下哪个工具更适用。因此,我们来看一下什么情况下 Tangram 是适用的。
Tangram 的总体设计很大程度上是参考了 Mootools 的做法,就是将框架拆散到函数的级别,你可以引用单个函数,而不一定要加载整个库。这样做的好处是节省带宽流量,尤其适用于那些流量很大但 AJAX 功能不多的网站。百度的很多服务流量都不小,而且常用页面上需要的 AJAX 功能也不多,因此 Tangram 成为了一个很好的解决方案。
那么什么情况下 Tangram 不适用呢?如果你要写一个 AJAX Web App , Tangram 就没有什么特别的优势了,除非你尤其熟练使用 Tangram 。一个 AJAX Web App 本身就依赖于库中大量分散的功能,把一个库拆分到函数级别并没有什么意义。当然,在 AJAX Web App 中, Tangram 也没有什么明显的劣势,跟 jQuery 、 Prototype 都差不多,这时候就由团队成员对不同库的使用熟练程度来决定选用哪个库了。
现在 Tangram 的最大弱势在于,它缺乏一种机制让你对页面逻辑的描述变得流畅( fluent ),而这正是我们使用 DSL 时所追求的。过去我也说过 jQuery 是一种 DSL ,它允许你用一种很流畅的语言来描述页面的交互行为,这使得页面交互行为变得很容易管理──读懂别人写的 jQuery 页面并不难,在上面做调整也很简单。这是 Tangram 为了减少下载体积做作出的牺牲,不过我希望它将来可以通过编译工具等方法来弥补这个缺陷──例如说,我还是用某一种 DSL 来描述页面交互,然后这种 DSL 能够被编译为 Tangram 代码。
Git 有什么好
为什么选择开源到 Github ? Git 到底有什么好处?我觉得一个简单的例子就能很好地说明问题。
例如说,你想看看 Tangram 的源代码,那么你可以直接打开 Tangram Github 的首页,然后以只读的方式把代码都复制到本地。
读着读着,你觉得 Tangram 写得也不是那么好,想改改看。于是你回到刚才那个页面上,点 Fork 按钮,然后就相当于把 BaiduFE 下面的 Tangram 项目整个复制到你个人帐号下了。你当然拥有你个人帐号下 Tangram 项目的完全读写权限啦,这时候你就可以把它复制到本地了。
可以看到,这是我的帐号( CatChen )下的 Tangram ,不再是 BaiduFE 下面的。这时候你就可以随意改动啦,改动完提交就是了。
如果你习惯使用 SVN 或者 CVS ,那么你需要注意啦, Git 的提交都是本地的,不会提交到服务器上去。你 Github 帐号下的 Tangram 是一个仓库,你本地编辑的则是另外一个仓库。别忘记了,你刚刚是用克隆命令把 Github 上的仓库复制下来的。所以在提交后,你还必须用推送命令把本地仓库复制回 Github 去。
在这里, origin 是一个远程仓库的别名。因为你本地的仓库是从 Github 上克隆下来的,所以 Github 上的仓库叫做 origin 。默认情况下,仓库只有一个分支,叫做 master ,所以你要把本地仓库推送到这个分支上去。
这时候,你自己的 Tangram 是更新了。如果你希望 Tangram 的官方版本也接受这个更新的话,你可以点击页面上的 Pull Request 按钮,这时候 Tangram 的管理员就可以考虑从你这里把更新拉取到官方版本上去。
如果你在开发自己版本的 Tangram 时,看到别人的 Fork 有更新了,并且也想要那个更新,怎么办呢?你可以主动地从别人那里拉取,然后 Git 就会帮你完成合并。例如说,我发现 Leeight 那里在做的一个 Tangram 升级不错,尽管他还没完成这个升级,也没提交到官方版本中去,但我就可以先把这部分升级拉取到我本地的仓库中来。
这样子,我就能看到 Leeight 所做的升级,跟我正在做的改动是否能够良好地兼容了。或者,我可以先做一些依赖于他的升级的事情,等他把升级做完了并且被官方版本采纳了,我再向官方版本提出 Pull Request 。
可以看到, Git 对开源项目来说是非常友善的,尤其是跟 SVN 和 CVS 做对比的话。 SVN 和 CVS 尽管允许分支,但分支之后通常要到项目完成时才会进行合并,这时候主干已经发生了很多变更,合并起来就相当痛苦。 Git 允许你分支后随时从别人的分支拉取变更,同时你还可以在自己的仓库内做很多子分支,这就使得开源项目管理变得十分方便了。
小结
说了那么多道理,建议大家还是动手实验一下比较好。试用 Tangram 无需下载,直接创建一个页面然后引用我们放在 CDN 上的脚本即可,然后可以尝试按照入门指南做些简单的东西试试。
使用 Git 管理开源项目的话,推荐阅读 Git 开发管理之道 ,能够让你更好地了解 Git 项目一般是如何进行分支的,以及如何利用这些分支获得更好的灵活性。如果你想看完整的 Git 手册,可以看看 Pro Git 这本书,作者把这本书放到网上并且免费公开了。
最后插播一下小广告,我的 jsHelpers 库也跟随着 Tangram 开源了,大家可以来 Fork ,我很欢迎大家提交 Pull Request 。
John Resig 见面会视频
发布日期:2010年11月22日上个星期 John Resig 来到了中国,谋智网络跟 CSDN 组织了一场 John Resig 见面会。 John Resig 在大会上介绍了 jQuery 的两个新特性(暂时还是插件): Data Link 以及 Templates 。引入这两个插件后,前端的数据呈现及交互将变得更简单,开发数据驱动型 Web 应用的成本也会随之而降低,估计将来我们能够见到更多基于 jQuery 的数据交互型 Web 应用。
此外, John Resig 还花了半个小时讲解 jQuery Mobile 。其中一项核心概念就是,基于 jQuery Mobile 开发的 Web 应用能够优雅地降级,自动适应功能比较弱的浏览器,同时又保证了在一流浏览器上的最佳体验。具体的做法与 YUI 的浏览器分级方法一样,将浏览器分为 A 级、 C 级和 X 级。确保 A 级的到最好支持,同时保证 C 级得到最低支持,此外假设 X 级能够获得一定支持。最后, jQuery 不会专门为了 jQuery Mobile 而多增加一个分支。无论你针对什么浏览器进行开发,都只会有一个版本的 jQuery 。如果有必要,你可以自己到 jQuery 的 github 获取具体子模块的代码并自行组合。
中国移动开发者大会 2010 及视频资源
发布日期:2010年11月08日这个星期去参加了 CSDN 和创新工场举办的中国移动开发者大会( CMDC ),感觉最大的收益是认识了一些做移动开发的人,同时了解了各家公司在做移动开发时积累的经验。
《植物大战僵尸》成功的秘密
最有趣的一个 session 是「《植物大战僵尸》成功的秘密」,演讲者是 PopCap Games 亚太区总裁 James Gwertzman 。这个如此成功的游戏经过了4年的开发,进行了多次迭代,才做出了我们看到的版本──易于上手同时充满乐趣。最初的 PvZ 设置为先要培养植物,等植物成熟了再来打僵尸,游戏的前期显得十分无聊所以这个迭代被否决的(这估计是正式版中 Zen 的来源)。第二个迭代设计为随机生成植物卡片,你要收集够太阳了,并且你想买的植物卡片随机出现了,你才能种植该植物,而且卡片的使用是一次性的,这个版本由于随机性太高而导致可操作性太低,也被否决的(这估计是正式版中某些随机卡片关卡的原型)。在第三个迭代中,太阳花和豆子炮的价格都是 100 太阳,尽管战略游戏玩家都知道要先积累资源再打仗,但悠闲游戏玩家在面对压力时,积累到 100 太阳后总是购买豆子炮,这样玩最终总会输掉。为了解决这个问题,设计团队尝试了若干修改,最后发现只要简单地把太阳花价格从 100 调整为 50 就可以了,悠闲游戏玩家自然会先购买太阳花。
从 Tap Tap Revenge 看 iPhone 应用成功之道
另一个英语 session 是「从 Tap Tap Revenge 看 iPhone 应用成功之道」。 Tapulous 从 iOS 1.0 开始做 App ,当时还不开放 SDK ,他们就做出了一款很成功的跳舞机游戏叫做 Tap Tap Revolution 。随后随着 iOS 升级, Tap Tap Revenge 不停发布新版本,并且在 Apple 的 iOS 4 发布会上进行了展示。如果做一个 App ,能够让 Steve Jobs 愿意在发布会上使用它来做演示?经验是:
- 做正确的 App
- 尽早进入市场
- 不停地添加新东西
- 专注于社区
- 具备社交性
- 专注于公关
- 跟 Apple 保持良好关系
- 保持在榜单上
- 免费应用加增值服务模式
天才团队和统一过程
「天才团队和统一过程」是一个有趣的 session 。我说不出这个 session 讲的是什么,但是郑飞科讲了很多有趣的故事。
美国硅谷移动创业经验分享
这是另一个我认为有点意思的 session 。赚美元花人民币开起来总是很幸福的事情,但如何才能赚美元呢?如何设计美国人愿意买的应用呢?柯博文介绍了他在硅谷创业的经验。
Panels
有两个论坛是比较有趣的,一个「 UI/UX 经验分享」,另一个是「海外市场面面谈」。
如果您对各种技术会议感兴趣,欢迎订阅我们的博客,也欢迎您加入百度。接下来我们将会提供 UPA 、 SD2C 、 TechEd 等会议的信息与视频。
UCD 2010百度工作坊
发布日期:2010年11月04日2010年10月30日,UCD2010年会,很精彩、很成功、很感动。
2010年10月30日,13:30-18:10 UCD百度工作坊,32个同学奋战到底,很充实、很紧张、意犹未尽。
2010年 11月1日,工作依旧繁忙,有点累,也想说点什么。
首先要说的是,本人比较低调,不善言辞,虽然有幸在互联网用户体验的圈子里闯荡了四、五年,小有一点成绩,仍不敢以专家自居,更不敢和圈子里的列位大师相提并论,非要按个名头的话,就是个现实主义的传教士而已,只求把自己经历过的、看到的、做过的真实产品设计方法、流程、经验分享给大家。记住,这里没有大理论,所有理论必须落地。
在百度的时间里,接触了很多的搜索类产品,为很多千万级用户量的产品进行体验的把关、研究的支持,经历着产品一波又一波迭代的过程。最初很想以搜索来命题本次的工作坊,带大家感受一些搜索背后的用户研究或是框计算与社区类产品的结合之类。但是当深入进来的时候才发现,搜索除去体验外更多的还是算法,而算法既意味着数据。固然用户研究离不开数据,但人长时间泡在数据里,就会不自然的迷失,甚至有时候怀疑自己是不是还属于UCD这个圈子的人。
恰巧最近在做几个核心产品的无线化工作,便借着几年来的经验和心得,拉拢了百度两个很牛X的交互设计师一起,密谋了此次的工作坊。工作坊最终命题:“跨平台产品的用户研究和交互设计”
百度前端技术交流会PPT
发布日期:2010年11月01日10月30日下午,在百度大厦成功举办了百度前端技术交流会。
从 if else 到 switch case 再到抽象
发布日期:2010年11月01日大家觉得在接手遗留代码时,见到什么东东是最让人感到不耐烦的?复杂无比的 UML ?我觉得不是。我的答案是,超过两个 else 的 if ,或者是超过两个 case 的 switch 。可是在代码中大量使用 if else 和 switch case 是很正常的事情吧?错!绝大多数分支超过两个的 if else 和 switch case 都不应该以硬编码( hard-coded )的形式出现。
复杂分支从何而来
首先我们要讨论的第一个问题是,为什么遗留代码里面往往有那么多复杂分支。这些复杂分支在代码的首个版本中往往是不存在的,假设做设计的人还是有点经验的话,他应该预见将来可能需要进行扩展的地方,并且预留抽象接口。
浏览器渲染与web前端开发 – 在电子科技大学的技术交流
发布日期:2010年10月27日10月23日下午,借着校园招聘的机会,我们来到了电子科技大学与同学们进行技术交流。
