李子拓:今天很高兴能有机会跟大家一起探讨,怎么在客户端上我们的软件做的更快。因为我是头一次来谈到这个CSDN这个活动,我做个调查。咱们在座的各位朋友里面,有多少人亲自在Windows或者其他平台做客户端开发的。
看一个图,大家看到这个图,能想到什么?浏览器是肯定的。这两个浏览器,应该是比较高端的用户才会用。但是,其实所谓的高端用户,看到他有什么特点,或者有什么反映,那么其实我们也做过一些调查。其实大家看到这个东西以后,很简单,一个快,一个慢。就是这种结果,我们比如搞专业的人听起来可能鄙视一番,但是他确实代表着一些问题。所以我们今天搜狗浏览器也是从这儿开始。
其实我们很多用户在看浏览器,或者其他客户端产品快慢的时候,包括用户调查,大家都只得到一个很模糊的概念?具体什么是快?什么是慢刚才也讲了。我随便列几条,比如启动时候,初次之后,我建一个标签多长时间。IE8大家体会到,我新建一个标签非常慢。比如说网站下载资源用多长时间,甚至还有一些比较厉害的用户,说你这个浏览器退出用多长时间,也是一个问题。所以也是客户端软件快慢所探讨的范畴。我讲之前,简单的从我个人的角度定义一下客户端产品什么叫快和慢?
我们用户每次电击鼠标或者按键盘有一个预期的行为。如果双击图表以后,3分钟一点动静都没有,大家需要干什么?看有没有起来。对于普通用户,他会再去放一些,我是不是刚才鼠标点错了,没点上。这种情况下,一般来说,我们需要给他一个中间的结果。那么,但是用VC的应该知道,点他以后,VC会出现一个条,就是在软件里面比较重要的一个地方。
我今天可能也是做广告,就是介绍一下我们搜狗浏览器团队,然后在做搜狗浏览器里面的一些经验。搜狐浏览器,相比国内老牌的浏览器来说,是太年轻的一个角色。像遨游做了好几年,搜狗是3年前才开始做,其实到今年年底是他的3周岁的生日。但是,大家可以关注搜狐浏览器,在短短三年时间内,能上升到国内浏览器排名的第三名,他一定是有用户认可的一方面。
在浏览器2.2版本,我们有一个图,这个图片有点老,我们有一个五级加速。我们先简单看一下浏览器用户怎么操作。比如我去敲一个网址,访问网址以后,这个页加载完了以后,得到我所要的信息。在这个过程里面有很多步骤,要做很的复杂的工作。所以我们简单的归纳为一个网络请求。还有一个就是你抓完东西回来以后,你要把服务器的HTML源码展示,看看中间有多少相交的区域。他不用等到你所有的资源下来以后才展示,我们把用户第一次看见页面顶上的那些定义一下。
我们先讲网速,因为网速是根本。大家在上网的时候,肯定我先访问一个网址,然后这个网址去搜狐新浪发东西,然后这个页面加载完成了。我不知道在座的有多少在教育网上过,他里面非常快,教育网的干线也很牛,但是他到公网不通,各种原因,可能是政治上,一些利益上的问题。总之,你的教育网去访问一些公网速度非常慢。当时搜狗在1.0的时候也是试图解决这些事情。我们当时很简单,就是架一个代理。其实这个东西,大家一拍脑袋都能想到,就是钱的问题,有钱把服务器都架起来了。
其实外面的一些业界或者用户可能都看不到,但是里面很复杂。不是说我们用户教育网的百分之百都是公网,就需要有一个名单滤一下,我们就有本地的一个策略,这个策略用来把这个教育网的这个类似于名单的东西过滤一下。只有在你访问的网站,跟你不熟,紊乱的时候找这个服务器。具体的技术细节,我就简单说了,基本上就是去客户端连接不同网端的服务器,这时候,你数量哪一个网端,服务器知道的一清二楚。等到用户真正想访问一个真正的站点的时候,决定你是不是要加速。这套思路,我觉得用在客户端的时候针对不同的网端在本地做一些策略,这也是我个人的一些猜测,具体还要看大家真正做软件时候的需求。
网速这一块,还有一种情景,就是说,大家经常用迅雷下载,在下东西的时候,大家会不会觉得上网比较慢?应该有一些用户会遇到,比如我开迅雷下东西,确实挺快,这时候我上网,一点都打不开,迅雷不想停怎么办?为了解决这个问题,我们可以说,我们去连目标网站的时候,我们先去借网速,相当于你暂时把他停掉,这个时候对用户是透明的,他看不到。然后等到访问页面完成以后,再把这个网速还回来,这个其实就是一个叫网速保护的概念。这个概念,现在像迅雷,360他们都有,原来也是比较简单。就是通过一个驱动来控制系统底层的网速,等到有请求的时候,去通知其他的软件让一下,大家觉得浏览器削弱了,比较可怕,但是这个其实对用户还是有很大作用。
然后就是下载,下载是上网比较重要的一个操作,这里不多讲了,就是我们用P2P的下载,这个东西到不是搜狗的专利,因为迅雷在这方面确实做的更好。但是,迅雷刚才讲了,就是启动慢,所以有些用户不太愿意用。觉得我开的时间还不够下,所以搜狗提出一个搜狗高速下载。我们接下来探讨一下客户端共有的这么一个问题,就是我们也谈这个渲染跟绘图。他其实目的就是把这个从网上下载的描述语言,包括各种脚本把他转变成排版,这里面其实严格意义上讲分好多阶段。我们这里面把他当成一个来看。
对于传统的浏览器,大家用IE可能是最多的,数据也摆在这儿,IE有什么问题?其实用的也很好。但是,在他IE自己,只有他自己,大家觉得也就这样用了,但是当一些竞争对手出来以后,大家觉得IE很慢,不是网速的问题,就是我们都下来了,然后你也慢,这就是他内核实现的问题。那么,我们浏览器又加了一个核,加了一个VIP的核,他是业界公认的更快的浏览器的核。这里面提一句,大家在写客户端软件的时候,会不会在里面嵌一些内容。最近新浪微博的客户端也是用了一个IE核,应该是大家可能会用到这些。当你发现IE核在你做需求的时候比较痛苦,你可以换一个别的。痛苦具体是哪些方面,慢是一方面,还有一个就是准不统一。如果5、6个不同的标准写这个Java脚本,你也是一个很痛苦的地方,核不在自己手里的问题。在这种情况下,你可以考虑带一个UIK的核。你不用去给IE擦这种屁股,是一个比较值得推荐的做法。大家在做客户端开发的时候,可以有限考虑一下这个。这也是在消灭IE6的道路上做一些贡献。
另外一个就是说,为什么搜狗没有抛弃IE核,就是解决兼容性问题。然后我提一下搜狗的防假死,这个概念我很奇怪,自从我上高中的时候用遨游就发现一个问题,一个页面运行的非常慢,或者他已经死了,点什么都没有用了,他虽然会很人性化的列出来,但是还是很不爽。我就想,为什么没有一个机制说,一个网站挂了,别的可以看。后来,当我们团队做的时候也发现了,这确实是一个很难的技术问题。因为在座的都是Windows开发,很多人知道这个Windows的结构。可以做一个实验,我们比如说建一个框,我们里面可以通一个子窗口。你如果尝试停掉另外一个进程,把进程给死循环,外面的窗口也跟着一块挂了。这个确实也表明了微软他这个窗口系统里面的一个问题,就是他的窗口表面上看起来,你可以理解为他是相互独立的,但是其实不是,他里面有很多内部消息,有一个叫活动的方式,我也不是很明白,他为什么设计。但是,确实引入一个问题,对于多标签多页面的这种会带来这种问题。
就是我在访问一个网址的时候,其实他是通过一个相互关联的一个循环,我再来一个网址,发现他还是卡在这个地方,这也是用户抱的一个问题。所以大家可以看到,现在大家对老牌浏览器意见比较大。比如说我这个网址死掉了,我再访问一个网址不知道访问什么,最惨的可能我连访问一个网址的机会都没有。后来我们找到一个算是不是很完美的解决方法,就是用一个独立的消息循环。这个是怎么做呢?就是比如说,举个例子,这是一个大窗口,里面的子窗口,你看起来是一个字窗口,但是其实不是一个字窗口,是两个顶窗口叠在一起,就脱离了父子窗口的关系。这样的话,大家也可以想,开发起来确实难度比较大,这个也是一个优势。现在应该是国内只有360合搜狗有这个防假死,目前其他的还没有,从体验效果和反馈来说,这个东西用户还是比较满意的。当然估计用不上这个东西,但是你如果发现有些东西不可控,你的程序里面有一个第三方的窗口,或者引用别人的库和逻辑。
对于防假死来说,可能还有别的一些要点,就是IO操作也是一个比较重要的东西,这个和启动关系比较紧。其实和你平常的运行关系非常紧密,比如你的界面跑在一个固定的地方。还有一个就是说,腾出CPU优先处理当前标签,用户可能一受抖,开了几十个标签,但是当前可能最多只能看到一个,这种情况下,如果他不能优先的处理,他也会抱怨,会说你这个东西不顺畅。我们的优化就是说,在用户开了很多标签,但是只展现一个的情况下,后面的都停掉,让他优先关注前面的这个表现。
最后再谈一下启动,尤其是冷启动,是大家关注的比较多的问题。一个是delayload,刚才也谈到了,我们启动的时候,把不需要的模块都往后放,至于放到什么时候,有不同的做法。比如说有些程序,可能我这个模块,我是用时加载,我启动很快,比如我有一些功能,有一些业务是不用的,或者有一部分是用户用的。这些东西,在用户调用的时候,把他加载起来。还有一种做法,就是延时,不管你用没用,都把他加载起来。在搜狗浏览器里面,这方面处理的是比较极端的,搜狗浏览器在启动的时候保证只有唯一的一个线程去做必须要显示的东西,比如说界面,界面上用的图片资源。把这个资源弄进来以后,当所有的事情都做完以后,再去开第二个线程。比如搜狗浏览器加载,包括大家看到浏览器的收藏夹。你无论如何一定要给用户第一视野,让他一下看到你是一个什么东西,至于他可有可不用的东西,一定在后面再给。
还有一个就是首次加载的文件的合并。在1.0的时候,我们配制文件差不多有十几个,每个人配制的文件,都想存东西。每个人自己有一套配制文件,一下浏览器启动的时候要读十几个问题,每一个文件,取的时候很慢。所以这个时候,可以打击以后个包,就是把他们聚合起来,让浏览器,让程序再一次IO的时候,把他们全都读进来,这个也可以回答刚才金山那位朋友的问题。你的包大小压缩不压缩跟大小有关系,但是策略是一样的。就是数量级的差距,而不是说简简单单的差距,这个也是一个可优化的地方。
然后浏览器起始页合并,比如像传统的IE他也是硬盘上去读。所以他这块没有办法去拆分。如果想把这些文件聚合起来,工作量稍微复杂一点。如果你用到IE,可能到时候你会先注册一个协议。这样的话,你可以让启动的时候的次数限制在一次,剩下的都走内存,这个可以加快首次起动速度。最后一条,不管在任何情况下,一定要优先给用户提示,不管你觉得这个过程是长还是短,你都要告诉他。你如果可能,如果开发时间充裕,最好的做法应该是在做一个操作之前,程序能够知道自己要花多长时间,并把这个时间告诉用户。像Windows的拷贝文件一样,会告诉你还剩多长时间。就是不论长短时间,能给用户提示都是最好的。