前端开发的演进
在过去的 10 到 15 年中,Javascript 无疑是发展最快的编程语言之一,它不再使用丑陋的、非结构化的代码和插件在网站上编写简单的逻辑,而是发展为具有构建功能完备的跨平台应用程序能力的强大生态。
随着对 web 平台的需求变得越来越复杂,前端开发者确实需要重新设计新的轮子。一些优秀的 JavaScript 框架和库陆续登上舞台:
随着 Angular、React、Vue 等框架和库的兴起,前端开发人员的焦点也从「如何编写代码」转移到了「选择哪种开发框架」。
San 的诞生
记得在 2016 年之前的时候,我所在部门的同学虽然对 React、Vue、Angular 等主流框架都有所尝试,但最终核心业务里面用的仍然是 jQuery。从我们业务的用户数据来看,IE8 - 仍占据着一定的市场份额:https://gs.statcounter.com/browser-market-share/all/china/2016。
如果把 Vue、React 这些 MVVM 框架比做洋枪大炮,那 jQuery 只能算是大刀长矛,面对洋枪大炮,低版本 IE 兼容性问题让做 2C 业务的同学只能摩拳擦掌、望洋兴叹。IE 兼容性相关的问题未来终将不再是问题,但是我们已经等不及要解决它了;出于对现状的不满意,我们开始了 San 的研发,并于 2016 正式推出。PC 端浏览器的 兼容性
是个绕不开的理由,San 为这类的业务需求提供了技术选型方案。
如果拿车来比喻,我们想造的是一台陆巡。相比轿车甚至多数 SUV,它没有那么好开,看不到很多 2.0T 的车尾灯;相比牧马人和 benz G,他越野能力和通过性也没那么强。但是它很可靠,能稳稳当当、舒适地带你到任何想去的地方。(@Erik)
San 的特性介绍
San 是一个做了无数减法后诞生的东西,它专注于一个轻快的,注重性能和兼容性的,数据为驱动形式的 UI 框架,配合相应的状态管理等库来形成生态。从功能上来看,San 并没有出奇的地方,其设计初衷是更好的性能、体积和兼容性,提高应用的天花板,减少应用开发者的后顾之忧。
San 通过声明式的类 HTML 视图模板,在支持所有原生 HTML 的语法特性外,还支持了数据到视图的绑定指令、业务开发中最常使用的分支、循环指令等,在保持良好的易用性基础上,由框架完成基于字符串的模板解析,并构建出视图层的 节点关系树,通过高性能的视图引擎快速生成 UI 视图。San 中定义的数据会被封装,使得当数据发生有效变更时通知 San 组件,San 组件依赖模板编译阶段生成的节点关系树,确定需要变更的最小视图,进而完成视图的异步更新,保证了视图更新的高效性。
组件是 San 的基本单位,是独立的数据、逻辑、视图的封装单元。从页面角度看,组件是 HTML 元素的扩展;从功能模式角度看,组件是一个 ViewModel。San 组件提供了完整的生命周期,与 WebComponent 的生命周期相符合,组件间是可嵌套的树形关系,完整的支持了组件层级、组件间的通信,方便组件间的数据流转。San 的组件机制,可以有效支撑业务开发上的组件化需求。
San 支持组件反解,以此提供服务端渲染能力,可以解决纯前端渲染导致的响应用户交互时延长、SEO 问题。除此之外,San 还提供了一些周边开源产品,与 San 配合使用,可以帮助开发者快速搭建可维护的大型 SPA 应用。
作为一个 MVVM 的组件框架。它体积小巧,兼容性好(IE6),性能卓越,是一个可靠、可依赖的实现响应式用户界面的解决方案。对于用过 Vue 或者 React 的开发者来说,San 框架非常容易上手,学习成本很低。
Size 对比
性能对比
数据来源:https://krausest.github.io/js-framework-benchmark/current.html
浅谈其他框架
San 尤其适合前端业务逻辑相对简单的业务。目前,在百度内部已有多个产品线把 San 定为业务首选前端开发框架,相关的业务已服务于亿级用户,这足以证明 San 是可靠、可依赖的前端框架。
而框架之间的对比似乎又是一个绕不过的话题,我们不能无视房间里面的大象。
对比 React
React 是经过实战检验的领导者,得到了企业和庞大的开源社区的支持。该库可以更好地扩展,让你创建复杂的企业级应用。从虚拟 DOM 到 JSX,从 Immutable 到 React Hooks,React 社区提出了很多伟大的革命性的想法。React 作为一个库而不是框架,许多依赖都源于由社区构建和支持的第三方库,无论是技术选型还是应用开发,都有着极大的灵活性,它的学习曲线相对也更加陡峭。
对比 Vue
Vue 使用一种更传统的方法,可以用简洁的模板语法来声明式地将数据渲染进 DOM 系统。还提供单文件组件的模块化方式,将 HTML 模板、样式和 JS 代码通过标签分隔。这种开发方式容易让前端开发人员更亲切,也使得框架易于学习。另外,Vue 的文档和生态方面,堪称业界典范。
San 汲取了 Vue 的一些优秀设计,同时也体现了一些新的思路。例如:在 Vue 中,数据直接置于组件下,methods 被规约。而在 San 中,method 直接置于组件下,数据被规约(其实已经被封装)。
相较于 Vue,San 在 API 的设计上更加节制。Vue 在组件通讯上,就提供了至少 6 种方案(参考 https://juejin.cn/post/6844903784963899405);而 San 则只提供 4 种方案(https://baidu.github.io/san/practice/),包含 store。San 不提倡使用 mixin,mixin 意味着组件有隐式依赖,组件在不同的 mixin 环境下,渲染结果和行为可能不同,同一个组件在不同环境下是不可预期的。目前 Vue3 也推荐使用 Composition api 来取代 mixin。
San 的生态建设
围绕着 San 生态的建设也在持续进行中,目前已经有了包括 San CLI、无极组件库、Santd、San DevTools、San SSR 等,周边生态已基本和 Vue 等业内主流框架对齐,足以满足当前的业务需求。当然,繁荣程度还有很大差距。需要广大开发者跟我们一起,共同建设繁荣的 San 技术生态。
目前 San 跟 Vue/React 的主流框架生态对比如下:
San、Vue 和 React 的生态对比
San CLI
CLI 工具致力于将打包构建等基础工具标准化,使开发人员专注于业务开发,不必花太多时间在 webpack、babel、postcss 等工具配置上。CLI 工具经历了 Hulk CLI1.0、Hulk CLI2.0、San CLI 三个版本的迭代(Hulk 是一开始做的偏业务的公司内部版本),现已对外开源。
目前 San-CLI 的主要功能:
提供交互式项目脚手架,开箱即用。支持
Smarty
和HTML
两种模板集成前端生态常用工具,初始化
Webpack
常用配置内置
Webpack
,提供插件化系统支持自定义扩展图形化的创建和管理 San 项目的 Web 界面,可集成常用辅助开发工具
UI 组件库
San 无极组件库是公司内部一套基于无极产品设计中台规范而开发的 San 版本的 UI 组件,主要用于百度各个产品线的 C 端业务。
Santd(官网 https://ecomfe.github.io/santd/)是一套基于 Ant Design 设计规范的 UI 组件库,目前主要用在多个内部的后台系统。
Santd 开源地址:https://github.com/ecomfe/santd
San DevTools
San DevTools 是前端开发工具中的利器,它能辅助开发者快速定位问题,发现性能瓶颈。
当你无法快速找到自定义事件 (Event) 在哪个组件上触发,消息(message)被哪个组件捕获,出了问题的界面对应哪个数据字段时,DevTools 都能助你一臂之力。
开源地址:https://github.com/baidu/san-devtools
San SSR
为 San 提供一个 SSR 代码框架和工具,将组件渲染为服务器端的 HTML 代码,实现同一组件同时运行在服务端和浏览器中,实现前后端同构。
San SSR 开源地址:https://github.com/baidu/san-ssr
San 在百度 APP 中的应用
这些年,随着移动开发技术的发展,我们的业务和团队都得到了长足的发展,但是技术栈却越来越乱,这是十分糟糕的。
对于一个大的研发团队来说,统一技术栈可以加深前端团队技术沉淀,防止重复造轮子,也有利于架构和解决方案的迁移,从而提升整体代码质量和开发效率,避免重复踩坑。
2018 年底开始,百度 APP 高工开始推动前端技术栈的统一,基于前端技术选型做项目脚手架、开发 CLI 工具、封装公共函数库、业务通用组件库。终极目标是实现一套代码,多端统一,先后用 San 做 H5、小程序、San-native 方案、San-SSR 服务端渲染等。
技术选型:为什么是 San
选择 San 作为统一技术栈的前端框架,主要基于以下几个原因:
首先是业务特点,百度 APP 的业务主要是以展现为主,核心业务的前端页面都是多 Webview 隔开的多页面的,交互相对比较简单,所以一个轻量和灵活的框架是首选;业务上我们不仅仅有移动端还有功能相同的 PC 页面,San 出色的兼容性,能轻松实现 PC 和移动端组件复用,我们可以做到一套组件在 PC 和移动上都可用。
其次,移动端采用开源方案(Vue/React)也是可以考虑的,外部库的好处在于发展的非常快,经常会有些新的 feature。但这也将会是个很大的风险,开源库的快速迭代意味着随时有新的最佳实践取代旧的模式而频繁的破坏性更改,让早期采用者承担重构成本。
最后,San 是一个普适性的前端框架,我们的小程序、San-native(类似 react-native)和 San SSR 都是基于 San,实现底层架构框架统一,真正做到从「Learn Once,Write Anywhere」到「 Write Once,Run AnyWhere」。
目前 San 作为主流的前端框架,被广泛应用到百度 APP 下包括百度 APP Feed 落地页(包括 PC)、移动端搜索结果页(百度搜索结果页,包括 PC)、个人动态落地页、用户个人主页(包括 PC 版)、话题、百度 APP 和搜索频道(san-native)等多个产品业务方向之中。
San 技术栈典型落地场景
Wise 搜索前端
面向用户:C 端
用户规模:亿级
技术选型
san
san-ssr
san-ssr-target-php
基于 San SSR 的改造,搜索业务实现了跨平台的同时,保证了老版架构迁移的平滑过渡:
组件化:把历史 Smarty 模板迁移 San 组件定义;
过渡期:通过跨平台的 SSR,一份代码分别编译到 PHP、 Node.js;
最终态:SSR 只编译到 Node.js,业务代码无需重写。
San 采取和 Vue/React 完全不同的方式进行 SSR,把解析和编译工作移到编译期,进一步减小运行时开销。
数据来源:https://github.com/searchfe/san-ssr-target-php/tree/master/test/perf
提升开发效率:通过架构升级,从旧的技术栈迁移到 San,实现业务的组件化,降低了后续的维护成本;
性能小幅提升:从测试数据来看 San SSR + PHP 和 Smarty+PHP 在一些场景下互有优劣,而在实际的业务场景(搜索结果页)有一定的是正向收益。
百度 APP Feed 图文落地页前端
面向用户:C 端
用户规模:亿级
技术选型
san + san-store + san-update
san-ssr
san-cli
老的 feed 图文落地页需要同时维护 smarty + react 两份模板代码,维护成本高。由于开发人员的变动,对于一些历史业务逻辑都很模糊。通过使用 san 技术栈的重构,取得了不错的收益:
代码开发从开发双语言代码迁移为统一语言,落地无极规范,减少样式问题的开发量,将开发效率提升 30% 以上;
首字节到达时间减少 26%,同步内容渲染结束时间减少 56%,各项性能耗时减少 20% 以上;
HTML 平均内容体积减小 16%。
Feed 频道 / 搜索六合频道
面向用户:C 端
用户规模:亿级
技术选型
san
san-native
san-native-cli
talos
Talos 是百度研发的一套动态 Native 视图框架,渲染引擎融合 Webview 和 NA,能同时支持 NA 和 Hybrid 的开发需求。它既能满足独立 App 的开发,也能满足平台型 App 内嵌。它专注性能优化,主要指标均优于同类框架。
San Native 作为 Talos 中的一种 DSL, 采用 San UI 框架作为底层驱动,通过重写 Document 以及 Element 类来驱动端渲染,使得 Web 前端工程师可以十分方便的编写原生移动应用,一套代码多端运行。目前主要应用在百度 APP 首页 Feed 频道和搜索结果页六合频道。
Talos 与 Hippy 性能对比 :
百度小程序
面向用户:小程序开发者 / C 端
用户规模:亿级
技术选型
san
talos
san-native
San 作为百度小程序底层渲染框架,提供了小程序所需的渲染机制,保证能够以组件化的方式进行小程序开发。同时提供了很多性能优化机制,很好的提升整体的运行性能。
San 底层提供简洁清晰的模板结构 ANode,能够被小程序框架所修饰,从而实现部分高频基础组件原生化,使得运行时渲染性能提升 50%。
San 提供压缩模板线下打包机制,将 template 编译成 ANode,可以避免在浏览器端进行 template 解析,提高初始装载性能。同时提供一种压缩方式将其转化成 APack,让其体积更小、网络传输成本更低,小程序接入后启动时间将缩短 20ms+。
附:San 生态相关
San 核心库
san : 一个快速、轻量、灵活的 JavaScript 组件框架
san-router: 支持 hash 和 html5 模式的 router,单页或同构的 Web 应用通常需要它。
san-factory: 组件工厂能帮助你在不同环境下更灵活的装配组件。
san-store: 应用状态管理套件,其理念是类似 flux 的单向流。
san-update: Immutable 的对象更新库,和 san-store 配合进行应用状态数据更新。
工具链
san-cli: 帮助你快速搭建 San 应用的命令行工具,让你专注于应用本身,避免在配置上花费太多时间。
san-loader: San 单文件组件的 Webpack loader。
san-hot-loader: 提供热更新功能,让开发调试更方便。
san-ssr: 服务端渲染框架与工具库。
san-devTools: 基于 Chrome 扩展的开发者工具。
drei: VSCode 插件。
san-test-utils: San 的单元测试实用工具库。
san-anode-utils: 一些工具方法能够帮助你处理 ANode.
docit: 基于 san 的 Markdown 文档建站工具
UI 库
无极产品设计中台: 服务于百度生态产品的产品设计中台,基于确定和自然的设计价值观上的模块化解决方案
santd: 基于 Ant-Design 设计规范的组件库
san-mui: 基于 Material Design 设计规范的组件库
跨端方案
基于 san-native 的动态视图框架 talos
延伸阅读
San - 一个传统的 MVVM 组件框架:https://efe.baidu.com/blog/san-a-traditional-mvvm-component-framework/
San 为什么会这么快:https://efe.baidu.com/blog/san-perf/
如何评价百度新造的 MVVM 轮子 San?https://www.zhihu.com/question/65498751/answer/294265707
头图:Unsplash
作者:金展
来源:百度 App 技术 - 微信公众号 [ID:gh_59f5931152fe]
转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
评论