从 Web 诞生到如今,Web 前端技术已经逐步成长为一个丰富且有活力的技术世界。随着互联网行业发展格局的频繁演进以及产品策略的不断调整,不同阶段的业务在技术选型、前端性能优化、用户交互体验上不断产生新的需求,不断地对 Web 前端技术提出新的要求。
10 月 27 日,82 期百度技术沙龙,邀请了数位百度前端技术部 Web 前端资深研发工程师,从 Web 前端技术出发,通过五个主题,立足现在面向未来,由内到外地分享百度在搜索组件化的探索、搜索体验增强、开放 Web 速度优化及开放 Web 未来发展发面的技术沉淀和积累。
搜索组件化探索与实践
首先进行分享的是百度前端技术部资深研发工程师陈骁带来的《搜索组件化的探索与实践》。
为什么搜索要做组件化?
据陈骁介绍,最开始的百度搜索移动端的前端架构是从 PC 时代迁移过来,服务器端使用 Smarty 来渲染模版,实现前后端分离。前端使用 Zepto 来完成交互逻辑,但是它的扩展性比较有限,难以实现对 HTML、CSS 代码的组件化管理,随着移动端的交互形式越来越复杂,原本的方案出现了局限性。
于是,组件化应运而生。组件化是把一些可复用的单元提取出来,通过对几个组件的管理,实现对整个搜索结果页样式的控制,提高开发的效率和横向团队整体升级的效率。
目前百度已经有了非常多的组件化解决方案,包括 Lavas 和 Reac t。可以具体到组件语法、基础框架以及同构区块。
如下图所示,组件语法包括四部分:
- Template:组件代理结构
- 浏览器端:组件前端逻辑
- Style:前端样式
- Config:同构逻辑
前三部分基本能够覆盖组件的常用语法,而同构在服务器端和浏览器端都能执行,主要有 props、data、components、computed 等。
那么这个组件代码怎么在线上跑起来呢?
首先会在线下通过编译器,把它编译成 PHP、JavaScript 两份原码。PHP 的编译产物完全使用 PHP 的语法,可以在后端形成一个 Server Runtime,在这个过程中,也能够把 PHP 的编译产物渲染成字符串,通过网络传输到浏览器端。而在浏览器端运行时可以用编码产物 Javascript 的组件,渲染成可操作的 HTML 代理结构,包括它的事件和交互。
其中的难点在于怎么把一个组件代码编译成在 PHP、在 JS 都能跑的组件代码。百度会做对于模板和一些表达设计的处理。例如,模板代码有一个文本节点,有一个自定义组件,在编译的过程中,会利用编译器把它转化成抽象语法树,形成树的结构,每个节点都有一些属性和信息,利用语法树的结构和属性信息,就可以通过代码生成器分别生成 PHP 和 JS 的代码。
这里还有一个问题,为什么需要一个同构区块呢?这是因为同构区块可以很好控制服务器端能执行的代码,方便语法解析。另外,百度对同构代码块进行语法限制,以保证服务器端的稳定性,也可以更加方便解析成想要的 PHP 代码。
通过改造,组件化渲染框架不仅可以使得效率提升,保证了体验一致性,而且进行了横向升级降低成本。
性能优化
针对服务器端的渲染性能,百度做了非常细致的优化:
- 在框架层,对渲染流程进行了简化,添加了缓存;
- 在基础组件层,对控制的简单组件进行编译优化;
- 在业务层,提供先验工具、准入规范,线上监控和报警,并提供 a-nossr 指令。
那么组件是如何在服务器端渲染成想要的 HTML 字符串呢?
如下图所示,会经过以下步骤:首先,加载组件的配置,创建组件的实例。在实例的创建过程中,对这个组件所有的数据进行初始化,包括一些特征和计算属性,得到初始化状态以后,再渲染出虚拟 DOM 树,把整个组件节点数渲染成一个实例的形式,用虚拟 DOM 树渲染成 HTML 字符串。