本文将介绍我在百度参与或负责的7次与搜索客户端架构优化有关的工作、所解决的问题以及过程中的思考,并从搜索客户端的架构变化来看搜索客户端的价值。时间回到2011年,我们团队启动了一款新产品的研发——在iOS平台上实现一个搜索App,名为“百度搜索”。很荣幸,我作为研发负责人参与了这个App从无到有的构建过程。这是我第一次站在实现者的角度来了解搜索业务。产品经理给“百度搜索”的定位为“有乐趣的、轻量级的搜索客户端”。听到产品经理给出的搜索客户端的定位时,还在想搜索服务用浏览器就可以满足,为什么还要再做一个搜索客户端?十几年过去了,这个问题的答案换过好多次,每隔一段时间我都有新的理解。在这个项目中,我学到的基本知识到现在都很受用,一些知识点还在影响着我的工作方法及标准。01 从零构建搜索客户端App
百度搜索初版为用户提供了文本和语音两种输入方式。用户输入完成后向搜索服务器请求搜索结果,当时的搜索服务器以网页格式返回搜索结果(结果页),点击结果页中的结果所进入的页面(落地页)也是网页格式。在技术实现上,我们使用的是iOS系统提供的浏览内核,支持网页的展现及交互。尽管通过浏览内核就可以满足用户的搜索浏览需求,但是我们在百度搜索视图的底部增加了工具条,以实现最基础的页面加载切换控制功能,如前进、后退、刷新等。整个App使用原生方式实现了主体框架(注:NativeApp,简写为NA,即原生应用程序),并通过内置的浏览内核加载网页,实现了搜索客户端的基本功能。初版的搜索客户端在表面上看和浏览器有些相似,如图1所示。此时的百度搜索主要使用系统原生应用程序接口(API)开发,可定制性不强。在这个阶段,研发团队和产品本身都处于成长期,架构设计的重点是构建产品的基础功能。02 Ding:优化移动端搜索的高频搜索需求
在2011年,移动设备中各种垂类App还没有像现在这么普及,搜索天气、股票等信息于部分用户而言属于高频需求。为了满足这些高频需求并将对应信息更好地呈现给用户,产品侧提出的方案为:在用户发起搜索时,为用户展现两类结果,一类为原搜索结果页的数据,使用浏览内核加载;一类为自定义的数据,在App内自行解析渲染。我们把实现这种自定义数据的“卡片”称为Ding。Ding可定制数据内容和搜索关键字,支持自动刷新及手动刷新,点击它还可以看到对应的详情页面。对于时效性较高且高频的搜索需求,通过Ding来获取,可明显降低成本。用户可以把Ding添加到首页,以便打开App时在首页就可以直接看到Ding的卡片。Ding在结果页中的展现如图2所示。这个阶段不再局限于满足用户的搜索需求,端与云的协同实现了以搜索或Ding的方式获取、展现信息以及与用户进行交互。这个阶段架构设计的重点在于搜索闭环能力的建设,而Ding仅是其中一种实现方式。03 搜索+浏览双框架:优化移动端搜索过程的体验
搜索业务有一个典型的特征,就是用户搜索一个信息后,会频繁地在结果页和落地页之间切换,直到找到想要的答案。这就意味着结果页需要多次加载,因为浏览内核的缓存能力有限,所以存在重新加载结果页的情况。而页面重新加载时用户需要等待,特别是在移动网络环境下,页面加载慢且出错的概率偏高。为了解决这个问题,我们将结果页和落地页拆分开,结果页使用原框架一一搜索框架进行加载,落地页使用新框架进行加载,这个新框架称为浏览框架。浏览框架没有搜索能力,但是可以快速关闭并回到搜索框架中,以使用户继续浏览结果页。这个过程上只需要进行两个框架的切换,因此实现了近零等待,提升了满足搜索需求的效率。搜索和浏览双框架共存的产品形态如图3所示。因为搜索和浏览两个框架是相互独立的,所以技术上可以实现对落地页的预渲染,如果预渲染的准确率比较高,就可以实现点击后立即展现落地页。04 搜索结果NA化:优化移动端搜索结果浏览体验
因为Web生态的开放性,所以在用户搜索和浏览过程中,会有很多站点参与其中,这就要求结果页的内容具有较高的适用性和扩展性。但结果页的内容格式是基于网页的,页面的浏览及交互受限于浏览内核,导致自有搜索客户端的优势不明显。基于实现成本、可控性及影响面的考虑,对于股票和外卖这类有明确需求方向的场景(对应特色搜索关键字),我们在百度搜索中进行创新尝试,使用NA自定义内容的扩展方式来增强部分搜索结果的展现,我们称这种扩展方式为搜索结果NA化。使用双层视图的方式扩展,底层是通过搜索框架加载的结果页,上层是通过股票NA的容器加载的股票内容页,两个视图之间可以切换。首次对结果页进行加载时,可以自动调用端能力(客户端扩展的能力,在网页中可调用)展现股票NA的视图,如图4所示。使用同层视图的方式定制。视图的上半部分为外卖NA视图,下半部分为浏览内核。NA视图内部可上下滑动,当滑动到底部后,框架根据用户的操作把当前活动的视图切换为浏览内核;反之,当前视图为结果页并向上滑动时,可以再切回外卖NA视图,如图5所示。相较于传统的网页格式结果页,NA化在性能和用户体验等方面均有明显优势。例如,更好的视觉效果和流畅度提升了用户整体的浏览体验,使得用户的使用时长提升。这一阶段的整体的技术方案是在原有结果页框架的基础上进行扩展,在客户端实现网页内容+自定义内容的混合渲染,并通过端与云的协同实现结果页的差异化定制。
05 搜索异步化:优化搜索核心指标
搜索业务的历史积累较多,从面向浏览器服务进化为面向NA化服务,不是做几个NA化的场景这么简单,还需要考虑浏览器的生态。NA化的工作告一段落后,要做的是优化用户在结果页上的体验,目标是优化页面的加载时长。仔细研究搜索结果页会发现,用户在搜索不同的关键字时,页面中总会有一些资源是相同的,不受具体的关键字影响。如果提前加载这些基础资源,那么在用户发起搜索时,仅需加载与关键字相关的资源,这样就可以减少页面加载时间。考虑到这一点,团队的前端人员开发了一套异步搜索框架。应用这套框架的前提是客户端需要提前创建一个浏览内核(单浏览内核),预先加载这个异步搜索框架。异步搜索流程如图6所示。但单浏览内核架构有一个局限,如图1-7所示,异步搜索框架或其他页面只能加载一个。如果用户再次发起搜索就只能采用同步的方式,即异步搜索的覆盖率没有达到预期。这个阶段的端与云的协同优化,不仅关注功能的构建,还开始兼顾核心指标的优化。06 多容器管理:突破单浏览内核的限制
解决异步搜索覆盖率问题的理想方案是在页面加载落地页时,创建一个新的浏览内核来加载异步框架。但是这种方案实现成本较高且不能保证搜索和浏览体验的统一,需要新的技术架构来支持,即多容器管理框架。多容器管理框架由框架层确定容器化的标准,统一管理容器的生命周期和事件,并根据业务、性能等目标进行合理调度,支持不同容器接入。我们还构建了容器内存/磁盘缓存管理机制,以及预创建、预加载、预渲染等优化策略,在效果体验及资源消耗方面实现了较好的平衡。将原网页浏览相关功能升级为网页容器,在多容器管理框架中,可创建多个网页容器。当一个网页容器被使用后,可再创建一个新网页容器来加载异步搜索框架以支持搜索。对比原单浏览内核管理框架,多容器管理框架在异步搜索方面的转换率有明显的提升。在这个阶段,多容器管理框架像一个简版的操作系统,支持搜索业务的全流程优化。07 变体发布:多App复用搜索能力
多容器管理框架上线之后,不同类型的内容可通过较低成本接入,团队的并行研发效率得到了改善。每个容器在各自的模块内独立达代,相互影响较小。时间到了2020年,各大厂均在构建自家的App矩阵,以超级App为中心孵化出一批矩阵App,如京东极速版、头条极速版、快手极速版等。这些矩阵App不仅具备主线App的核心能力,甚至还会有一些定制化功能。百度App也需要孵化矩阵App,但矩阵App复用百度App功能模块的成本较高。和传统的模块复用方式不同,App级的复用需要技术架构层提供支持。我们当时提出了变体发布的思路,即一个App可以通过工程化的配置实现功能快速裁剪和低影响面的差异化定制,主要实现方式包括技术分层、容器化、插件化、动态化、接口与实现分离等。通过这个思路,矩阵App单次同步主线App功能的耗时下降了70%以上。支持变体发布的App架构如图9所示。
总结:搜索客户端的价值
在20多年前的个人计算机时代,搜索引擎通常基于Web生态构建,用户不需要专门的搜索类客户端产品,使用浏览器即可免费享受搜索服务。而当搜索引擎的服务有了自建客户端的支持,搜索及浏览的体验就成了可控的,此时第三方的内容质量问题也可以被识别并干预,这时相当于搜索全流程是可控的,如图10中的灰色区域所示。图10 浏览器(左)和搜索客户端(右)中搜索体验的可控性示例同时,因为有搜索客户端产品的文持,从输入关键字到展现结果页,再到打开落地页,每一步都可以定向优化,这拉开了与其他搜索产品的差距。图11列出了搜索客户端对搜索业务研发的正向影响。不断地创新及优化端与云的协同,可以为用户提供更好的搜索体验。本文摘编自《搜索架构之道:App中的搜索系统设计与优化实践》,经出版方授权发布,转载请保留文章来源。
《搜索架构之道:App中的搜索系统设计与优化实践》是一本以搜索业务为主线,深度解读超级App构建与优化的策略、流程、方法、技巧和作者近20年心得精华的著作。本书覆盖了App从诞生到成为超级App的过程中技术架构层面所面临的所有核心挑战及其解决思路。
作者简介
刘俊启,百度前资深研发工程师、百度前App架构师、百度前OC&Swift编码委员会主席、腾讯研发工程师,国内App研发先行者。2005年入职盛大·数位红,参与了Game-V(中国第一个无线游戏娱乐运营平台)的研发工作(NOKIAS60平台)。之后作为初创团队成员,负责多款S60平台的App研发。2009年开始转战iOS平台,负责推进公司产品技术栈向iOS平台迁移。