本文做者:HelloDeveloperhtml
10 月 27 日,82 期百度技术沙龙,邀请了数位百度前端技术部 Web 前端资深研发工程师,从 Web 前端技术出发,经过五个主题,立足如今面向将来,由内到外地分享百度在搜索组件化的探索、搜索体验加强、开放 Web 速度优化及开放 Web 将来发展发面的技术沉淀和积累。前端
1ios
搜索组件化探索与实践shell
首先进行分享的是百度前端技术部资深研发工程师陈骁带来的《搜索组件化的探索与实践》。json
为何搜索要作组件化?axios
据陈骁介绍,最开始的百度搜索移动端的前端架构是从 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 字符串。
与此同时,百度搜索对整个渲染的过程进行了简化。在框架层,经过建立虚拟 DOM,减小了一次递归,也减小了在线上运行时的逻辑。在基础组件层,百度对横向团队可以彻底控制的一些简单组件进行了优化。利用 HTML 编译器编译成语法树,语法树对它每个 AST 节点进行优化,经过将 Tag 直接定义为普通的 DOM 节点的方法,生成最后想要的函数代码。
框架层:渲染流程简化
简单组件编译优化
目前进展
目前,百度提供搜索组件化的工具。好比搜索 Web 无障碍规划、搜索性能准入规范、搜索设计规范;服务方面包括性能监控、先后端异常监控等;运行方面提供 VSL 语音交互框架帮助开发者开发一些语音交互逻辑;工程方面提供搜索敏捷平台,帮助开发者直接完成联调、提测、上线;在应用方面,有卡片、图片搜索、咨询搜索、移动端的首页,还有一些独立的站,包括百度体育和百度招聘。
搜索组件化技术全景图
2
移动体验标准化建设
第二个 Session 是由百度前端技术部资深前端工程师刘浪宇带来的《移动体验标准化建设》。
极致的用户体验是 Web 产品所追求的,那么什么是好的用户体验,如何去量化用户体验作到好的体验呢?首先须要有一套清晰的体验指导标准,而后再去落地。
移动体验指南
移动体验指南是基于移动 Web 生态提出一套通用的体验指导规范,目的是更好地服务于用户及产品的系统,为广大用户提供优质的体验。从用户的体验层次、交互和移动 Web 现状,百度概括出六个纬度:
第一,快速的信息呈现。速度快慢直接影响用户对站点的体验评级,因此让主体内容快速呈现给用户才是优质的体验必需的。
第二,设计交互层面强调一致性。一致的设计交互能够利用用户的学习经验,下降学习和使用的成本。
第三,好产品须要作到让用户低成本、高效地完成全部交互操做,总体操做要清晰无阻,带给用户最流畅的体验。
第四,内容强调优质阅读观感。站点的内容可读性、内容自己质量是否可以达到,都是优质的体验所必需的。
第五,情感层面有两点,首先是愉悦的情感认知,其次是让用户对站点信任,页面是否安全、是否及时告知流量信息等等。
第六,关于强健的场景适配,优秀的站点应当适合于不一样的人群和宿主环境。
移动体验检测平台
有了体验指南,如何快速知道站点存在哪些问题?这就须要体验检测平台 Radar。
Radar 的最底层是 Headless Chrome,百度经过协议接口能够很是快捷地操做这个浏览器。中间的运行是基于谷歌开源的一个网页工具 Lighthouse 。它主要有两个内容,第一是网页数据收集,经过数据分析得到数据,按照规则的须要,对于这些数据进行分析后输出想要的结果。第二,Radar 的核心是很是多的规则,主要分两类,一类是普通的,一类是交互的。
刘浪宇以交互的规则为例,详细阐述了一个规则是如何实现的。以下图,交互的规则主要分为两部分,第一是场景识别,第二是交互分析。举一个比较简单的例子,当用户在页面看到一个输入框时,以为点击能够直接输入是一个良好的体验。那么如何量化这个规则呢?首先是场景识别,找到在这个页面中看起来像评论输入框的元素。而后找一些特征,从海量数据里面标注、提取一些通用特征以后为这个场景创建特征库。以后再基于场景所须要的特征,进行网页结构化数据提取。
Radar 规则架构(交互类规则为例)
接下来这些场景元素就要进行交互分析,首先进行深度筛选而后进行交互操做。以模拟屏幕的点击举例,点击以前用户会看页面的变更,好比说 DOM 的变更、跳转的变更,而后对变更进行分析,看是否符合预期。
3
基于 Custom Elements 标准组件化构建 Web 应用
第三个主讲人是百度前端技术部资深前端工程师邹淼江,他现场分享了如何高效快速的构建一个体验良好的 Web 应用、基于 Custom Elements 标准的组件化设计、如何提高用户端体验和开发效率。
首先看自定义标签,自定义标签在功能上逻辑上与 JavaBean 相似,都封装 Java 代码,是可重用的组件代码,而且容许开发人员为复杂的操做提供逻辑名称。另外,自定义标签具备⽀持⽆障碍、提升开发效率、评估性能、对 SEO 良好的特色。
其中,如何使用自定义标签进行性能评估呢?百度提供了一套搜索引擎的验证工具。好比,符合某一种规则的 Custom Elements,给它标高分,为符合高性能标签。但若是使用 DIV 的方式,搜索引擎没办法知道布局是否是高性能,也没办法知道所对应的 JS 如何实现,若是有了 Custom Elements 的标准,就能清晰地知道这个页面想干什么。
基于此,咱们能够设想:若是彻底使用这些 Custom Elements 语义化标签构建 Web 站点可行吗?
这就须要引入组件化设计。其实目前存在的组件化设计都千篇一概,把一个页面的功能模块以组件树状的形式自由组合,堆积成一个功能的页面或者是模块,这就是组件的结构。具体要求:
每⼀个 Custom Element 是⼀个组件
组件内部实现相应的交互、功能和数据处理逻辑
组件之间逻辑和样式是独⽴隔离的
组件是能够通讯的
组件是可复⽤的
Web Components 标准
Web Components 是指经过一种标准化的非侵入的方式封装的一个组件。主要标准包括 Custom Elements,Shadow DOM,HTML Templates,HTML Imports 等多个维度的规范与实现。
Custom Elements 是提供一种方式让开发者能够自定义 HTML 元素,包括特定的组成,样式和行为。支持 Web Components 标准的浏览器会提供一系列 API 给开发者用于建立自定义的元素,或者扩展示有元素。
Shadow DOM 旨在提供一种更好地组织页面元素的方式,来为日趋复杂的页面应用提供强大支持,避免代码间的相互影响。开发者可利用 Shadow DOM 封装本身的 HTML 标签、CSS 样式和 JavaScript 代码。
HTML Imports 是一种在 HTML 中引用以及复用其余的 HTML 文档的方式,能够简单理解为常见的模板中的 include 之类的做用。咱们能够经过 HTML Import 的形式,直接将作的 Custom Elements 的标签放进 HTML 中进行渲染渲染。
Web Components 兼容性
4
搜索落地页体验技术及应用
第四个主题由百度前端技术部前端工程师李兆明讲述。如何更快、更好的将各种搜索结果页面传递到用户端一直以来是百度搜索前端的核心关注点。基于此,李兆明分别从如何让落地页加载更快,如何让搜索结果页和落地页之间切换更加顺滑以及将来的新标准,介绍百度搜索落地页体验技术的探索。
如何让落地页加载更快
思路一:提早加载。经过 Resource Hint 提示浏览器预解析域名、创建预链接,甚至进行预渲染。如果不支持的浏览器,则能够经过 JavaScript 模拟一部分。
思路二:抓取数据。经过开放平台提交数据,由百度来渲染。
思路三:MIP / AMP。MIP 提供多重措施,让使用 MIP 技术的页面加载速度更上一层楼。例如,CDN 加速服务;使用 MIP 设计的网站没有任何能够阻塞渲染的脚本,全部脚本都在页面主体加载完成后才执行。此外,MIP 要求全部页面都是静态的,若是有须要实时更新的数据须要异步获取,这样设计节省了后端的渲染时间。
如何把两个页面融合在一块儿?
其实,不管有多少优化加载速度的手段,归根结底离不开页面跳转。可是,浏览器跳转相对来讲不够平滑,用户体验不够好,能不能把先后两个页面融合到一块儿呢?
答案固然是确定的。李兆明在保证体验、保障安全及保持开放的基础上,讲解了百度前端搜索的解决方案:
保证体验:经过 Iframe 加载页面;经过 PostMessage 等方法实现交互动效。
保障安全:不容许使用外部脚本,须要封装组件审核;经过校验确保 HTML 符合规范。
保持开放:经过 GitHub 追踪开发。
展望新技术
在将来,百度搜素将基于域名、Iframe 渲染问题,为开发者带来 Navigation Transition、Promotable Iframe、Portals 及 Web Packaging 新标准,带来最流畅的体验。
Navigation Transition:页面切换的交互方式。解决了跨域问题,没有 Iframe 渲染的历史包袱。不过前一个页面依然不能控制后一个页面的加载、渲染。iframe 能够提早加载,可是 Navigation Transitions 必定要在用户切换的时候加载。
Promotable Iframe:与 Iframe 相关,核心代码是 Promotable 的 API,只要调用 Promotable,就会调动页面的一小块,然后调动整个页面及内容。可是这种方法涉及一些生命周期的管理和 JS 的回收问题,是不够安全的实现,并且这样没有解决 CDN 的问题,依然须要改域名。
Portals:传送门,将一个页面传送另外一个页面。这个标准是 Promotable Iframe 的加强,引入了一个新的 HTML 标签 portal,这个标签用来替代 Iframe 显示一块网页,写法和 Iframe 相似。可是它比 Iframe 多一个功能,就是能够经过 “active” 方法激活它。与此同时, portal 的子文档会收到一个 portal zactive 事件,事件中能够拿到它的上级元素,这样又能够把上级元素当成一个 portal 插入回本身的文档流,使得页面切换回去成为可能。
Web Packaging:解决了 CDN 跨越问题。这个标准包括三方面:签名、打包、加载。以下图,左边内容提供者是站长,缓存的 CDN 类比 MIP 的 CDN ,右边是访问用户,用户浏览咱们百度搜索结果页的时候,经过 MIP 的 Cache CDN 提早把数据取过来,用户真正点击的时候,直接从刚才取回来的页面去加载它。因为内容自己是内容提供者提供的,因此他能够对于本身 URL 进行签名。有了这个签名且签名有效的时候,浏览器能够本身显示原始的网址,同时原始的网址能够和原来的服务器进行交互,像经过原网址打开的同样,解决了 CDN 跨域问题。
5
如何经过 Lavas 快速构建 PWA 站点
最后一个主题的讲师是百度前端技术部资深研发工程师王轶盛为你们介绍如何经过 Lavas 快速构建 PWA 站点。
PWA
PWA(Progress Web App)是 WEB 将来的发展方向。从体验上来讲,PWA 接近原生 APP,经过 Manifest 技术容许用户快速打开站点并得到沉浸式的体验,经过 Service Worker 可以作到资源预加载和离线可用等从而提高性能和可用性;同时 PWA 又拥有 Web 站点的共同优点:免安装和自动更新。
但与 Web 站点不一样的是,PWA 又具备可靠、快速、黏性等特色:
第一是可靠。在断网的状况下,PWA 可作到比较友好的离线提示,这个是 PWA 断网的最高级,叫断网可用。
第二是快速。53% 的用户会放弃加载时间超过 3 秒的网站,越快的加载速度就有越少的用户流失。PWA 提供 Service Worker,肯定哪些访问缓存、哪些访问网页,缩短加载时间。
第三是黏性。黏性是指用户访问过一次,下一次访问是否麻烦。PWA 会用一个半秒的启动动画来保证浏览器首页启动的顺滑。另外,启动以后没有的地址栏、菜单栏,保证用户的沉浸式体验。
从技术层面讲,PWA 有分为四部分:
第一是 Service Worker 。定义预缓存、网络拦截和缓存策略。它自己是一个 Worker,有专门的语法,须要 CACHES API,须要注册及更新。
第二是 Manifest 。这是一个 Json 文件,定义快速入口,启动动画。
第三是 Web Push and Notification 。是服务器推送给客户端的主动通知。
第四是 APP Shell 。这并非新技术,但它是经常使用的 PWA 架构。简单来讲,就是把一个 APP 分红了外壳和内容,用 Service Worker 把外壳缓存起来,将里面的页面进行跳转。
经过 Lavas 搭建 PWA 站点
Lavas 包括工具、文档以及对应的解决方案和建站模板,是一个开源的解决方案。Lavas 自己有两部分,Lavas cli 和 Lavas core,内部用 Vue + Vue Router + Vuex 搭建站点,内置两套模板 (basic & app-shell),支持传统模式 SPA 和 SSR 快速渲染,能够快速拥有 PWA 特性,灵活性强,配置简单,并且文档及时更新,内容完整。经过 Lavas 搭建 PWA 站点主要有八个步骤:
准备环境 & 初始化项目。安装 Lavas cli,初始化项目,选择模板,安装依赖。
建立新页面。
添加连接。使用 <router-link>,注意和 Vue 保持一致,to 属性指明目标页面,支持字符串格式的地址,支持对象。而后启动调试服务器。
和服务端通信。安装 axios,引入 axios,向后端发送请求。
使用 Vues 管理数据。
建立 STORE,须要定义一些内容。把请求数据移动到 action 里面,获取成功后调用 commit 触发 mutation 去更改 state。
在组件中,经过 store.dispatch 触发 action 获取数据,而后经过 mapState 把 state 和计算属性关联,最后经过计算属性在页面上使用。
配置 Manifest 。Manifestt.json 定义了启动 URL,定义各类尺寸的 icon,定义动画配色和启动模式。
配置 Service Worker。配置,指定模板位置、构建位置
构建和上线。执行构建命令 > lavas build;启动生产环境 > cd dist,> lavas start。
Lavas 技术原理
Lavas 的技术原理主要有自动生成路由规则、Skeleton、App Shell。
Vue Router 须要四个步骤作整件事情:第一步定义和引用组件,第二步把组件和路由联系起来,第三步是把刚刚联系起来的数据放到 Router 函数建立实例,第四是把 Router 放到 VUE 建立实例,结束 Vue 实例挂载就。
通过改进, Router 不用本身定义页面级组件,能够认定只要在 Pages 目录中,那组件都是页面级的,从而能够实现自动化 Import,不须要每次写一大堆的代码。另外,绝大多数状况路由规则和组件名称是有对应关系的。自动生成路由规则映射,省去了列出映射关系的麻烦,也避免后期组件更名带来的维护成本。
Skeleton 叫骨架屏,就是实际内容展示以前,有个大概内容给用户看,这样用户提早看到一些东西。这是 Loading 升级版,由于每一个组件能够自定义样式、切换时机、列表等。
Lavas 的 Skeleton 均可以用,实现思路是 Vue 的挂载点通常是个空的 DIV,在构建时将 Skeleton 的内容添加到挂载点中,Vue 挂载前清空 DIV 内的占位内容,挂载后渲染为实际内容,使用 SW 预缓存 HTML,访问时直接从缓存中获取 HTML,这样可让用户看到占位的东西。
App Shell,就是把一个 APP 分两部分,有外壳和内容,把外壳缓存起来,每打开页面先把外壳拿出来,而后再是内容渲染。App Shell 实现有两个步骤,第一是划分,告诉程序哪部分是外壳、哪部分是内容;第二是程序把外壳缓存起来。这须要实现两方面,第一是 SPA,首次请求服务器返回 Index.HTML,全部页面的渲染均由 JS 完成,只在挂载点内从新渲染,单页 Index.html 就是 Shell,使用 SW 预缓存 Index.html 便可。第二是 SSR,首次请求服务器返回给所有内容,后续页面的渲染由 JS 完成。
Web 生态的发展就是互联网的发展,新技术的不断涌现和新场景的不断实现也让这个开放的生态得以持续繁荣。王轶盛表示,百度但愿国内的开发者与站长可以多多参与到 PWA 项目中,共同建设和改善国内的 Web App 生态。