浅谈Web容器设计的边界和目标

开发 架构 新闻
本文是笔者参与UC浏览器新一代Web容器架构方案的设计、建设、业务落地过程的一些总结和思考。

在移动端项目的落地过程中,有很多技术方案可供选择,如Native、Flutter、H5……但在业务中选择哪一种技术方案,当然是需要结合业务和技术的现状和历史沉淀来看。

就历史沉淀而言,UC是做浏览器的,在对Webview优化上的积累自然也是最多。由于UC有对浏览器内核有定制优化的能力,很多时候对Web的优化和问题从前端侧可能是很难找原因,但从内核的“上帝视角”却很容易找到思路和解法。在浏览器里面做业务,只要没有超过Web容器的能力范围,我们一般会优先考虑用Web技术来满足业务的诉求。

当然,要想准确把握Webview的能力范围并不是件容易的事,而不同人或团队对于Webview能力边界的理解也是不太一样的。当我们在讨论一项技术的边界时,关键的不是了解该技术能做好什么,而是知道它做不好什么。

注意,说的是做不好,不是做不了。很多时候,我们所说的“做不好”指的是,达不到最优秀的用户体验,通常与使用Native并经过优化后的效果进行对比。在用户体验竞争越来越激烈的情况下,每个产品都期望能用最好的天花板最高的技术来落地。

但在现实的技术方案设计中,除了考虑技术所能达到的最优效果外,还需要综合考虑开发成本、开发周期、维护效率、线上风险等因素,以及根据业务发展、人力资源配置情况,综合考虑后最终选择一个ROI最高的方案。

好了,方案选择的路径不是这里讨论的重点,还是来聊聊动态容器吧。下面笔者将列举一些典型的用Webview技术的Cover起来有难度的场景。

Web 容器的边界场景

一、复杂的媒体播控

1. 视频播控

并不是说Webview(H5)、小程序处理不了视频,而是对于视频的细节处理不够好。我们都知道web原生的video播放控件功能单一,没有快进/退、倍速、音量调节、亮度调节、对缓冲无感知等问题。此外,动态容器处理视频还有以下常见问题:

  • 自动播放控制:主要是iOS的限制,在webview内的video标签需要用户的许可,因此双端自动播放逻辑是不一致的。在iOS上为了解决自动播放的问题,通常在body上绑一个video的play事件,用户触碰一下页面就代表授权了,但这解法其实挺鸡贼的,并不能代表用户的真实意愿。
  • 播放时长统计:video播放时长统计是业务和算法的需要,如果前端业务开发者来做video播放时间统计会存在,在点击播放时视频资源才开始下载,什么时候视频开始起播基本完全靠估算,播放过程中网络缓冲时间也可能被统计到播放时长内,因此时长统计由前端业务来完成非常容易带来统计误差,业务往往是不可接受的。
  • 封面无缝切视频:由于video真正的播放视频时间(起播时间)不精确,也带来视频的封面图片替换为视频播放画面的过渡体感会比较生硬,如果点击播放后立刻将封面图片替换掉,而这时视频还在加载就会出现黑屏效果,体感不ok。
  • 播控面板UI定制:在webview内对video的UI调整也是有难度的事情,常见的实现是先隐藏原生video的控制条,然后在video上覆盖一层自定义UI,接着在自定UI上通过事件的方式来控制底下的video。这样的封装有很多开源的方案,但整体体验与Native定制的播放器有很大落差,在自有App内几乎不会用,站外分享才会考虑这类方案,实际也是一个不得已的选择。
  • 多视频播控:如果在一个页面中存在多个视频,在播放其中视频时,需要对其他视频进行暂停或销毁处理;如果这是一个视频长列表,产品期望根据用户滚动的位置实现视频的自动播控,那么多视频问题会更复杂,因此很少看到有业务使用动态技术构建包含视频自动播控的长列表业务。在这个场景,技术要么native,要么flutter。

包含多视频的长列表滚动到可视范围内自动播放,技术以native/flutter为主

当然,webview处理video带来的细节体验问题还有不少,有一些问题通过native托管可以有效解决。在各大App自有业务内,对Webview的video播放器的优化基本都走native托管的模式,在技术实现上叫混合渲染或同层渲染。

2. 音频播控

音频媒体资源的播控问题与video是类似的,webview内的audio标签也存在功能单一,没有快进/退、倍速、音量调节、对缓冲无感知等问题。


在我们的业务中涉及的音频播控场景比较少,目前为止包含音频播控的场景主要是图文的语音播报功能,由于需要对音频播控在App保活期间全局生效,音频播控的落地页面自然不能使用h5的audio标签来处理TTS音频,而是对接Native自定义的语音控制事件体系,页面则绘制一个播控音频的UI面板。

目前,针对音频播控的诉求行业主要方案是Native base,Flutter实现应该也没问题,Web的实现相对较少。目前,我们已完成了此场景Web化,这里需要解决的边界问题是在后台模式下的页面保活和生命周期拓展。

3. 动图播控

动图包括gif、apng、webp等,在动态容器只有img标签一种图片处理方式,在一些动图很多的场景,就很难实现对动图的播放有效控制。例如:

  • 多宫格图片的顺序播放:由于不知道动图什么时候播放完成,在多宫格的动图列表中需要等待上一个动图播完再接着播下一个的需求是无法用现有img标签来实现的。在业界碰到类似的问题,如果非要用web的方式解决,往往将动图转化为video来处理,或者就直接标记为“动图”让用户自己点击播放。

实际上,业务需要动图播放可控的功能,要解决的实际问题是动图可以逐帧暂停/播放、播放开始和结束都有对应的事件,也就是需要一个功能完备的动图播放器,而不只是用封面替换动图来模拟实现暂停而又不知道最后一帧啥时候完成的半成品。

目前针对动图进行有序播控的诉求,我们采用的是Flutter方案,本质是Native的实现,而在Webview容器内可以通过类似视频播放器一样,通过同层渲染技术实现对动图的逐帧播控。

二、高性能的长列表

1. 长列表的性能问题

在Web容器下,性能是长列表面临的最棘手问题。问题会表现为:

  • 在不停下拉滚动的过程中,当列表插入的页面节点越来越多,则会导致滑动越来越卡顿(掉帧);
  • 如果列表内容过多而不做 DOM 节点回收或分页处理,页面的内存可能占用过大,进而导致页面或 App 崩溃;
  • 在做了页面节点回收后会导致在快速滑动的过程中,页面节点回收而Dom渲染速度跟不上滚动的速度,而导致用户有明显的白屏体感。

2. 行业方案分析

对于这些问题,前端业界有很多解决方案,解决思路大致两个方向:

  • 针对图片过多

图片过多,这是引起性能问题的最常见因素,因此在有大量图片的页面中,我们都会使用 lazyload 的方式按需加载图片,长列表的场景也是一样的。

  • 针对节点过多

业界普遍的解决方案是虚拟长列表,根据列表容器的可视范围,动态计算出在可视范围内的列表节点 item,然后只渲染视野边界内容的 item,通过控制页面节点数避免内存线性增加。

在具体的实现方案中,目前行业方案有:

  • 给列表容器设置 height 或 padding 值撑开容器: react-virtualized& vue-virtual-scroll-list
  • 通过 transform 对列表 item 进行位置偏移,同时用一个影子容器来实现滚动条的模拟:ngx-virtual-scroller
  • 小程序方案:微信小程序recycle-view、taro虚拟列表

当然,还有很多,这里就不再一一列举。

以上的几种方案有所差异,但设计理念基本类似。在实际的业务场景中,当容器内的每个 item 高度是动态的(等高的计算逻辑相对没那么复杂,这里不讨论),在虚拟列表页面节点数量增多的过程,背后存在大量的js逻辑计算:

  • 在计算可视范围内的 item 内容时,必须需要循环遍历每个 item,获得其相对于可视窗口的偏移量,进而计算出需要展示的 item,以完成虚拟列表布局的需要。
  • 容器的外部高度是需要在滚动过程中,不停的进行动态计算并进行重新渲染,也就是整个列表中内部每个元素,在滚动过程中是时时刻刻都产生超过可视范围的区块重绘。

由于获取Dom元素的真实高度需渲染完成后才能获得(相对Native或Flutter可以在元素layout的过程,通过layoutBuilder的回调就可以获取其高度,无需等待元素渲染上屏),导致js计算列表元素高度需要等待Dom渲染,进而到带来不可避免的时间差。

因此,在页面快速滚动的过程中,虚拟长列表在回收节点计算的过程,由于高度计算的处理逻辑需要等到Dom上屏之后,如果页面滚动速度越快,计算量也就越大,等待Dom上屏的时间间隔就越大,一旦页面的滚动速度超过一定阈值,必然出现可视区域内UI的变化速度 > 渲染速度的问题,就会表现为快速滚动的页面闪白。

3. 闪白无法量化

实际上,滚动的白屏问题是虚拟列表的节点被回收后引入的新问题,是一个用户的体感问题。在这里笔者用可视区域内的UI变化速度 > 渲染速度只是技术用语上的表述,尴尬的是从纯技术的角度这是 一个很难用数据进行量化的问题 。why?

首先,这是一个新问题。

如果我们没有对页面节点进行回收,那么就不存在滚动路径上页面没内容的情况,也就没有所谓的闪白问题。但不做节点回收就意味着在一个超长或无限下拉的列表中,DOM 节点会线性增大,必然导致页面占用越来越多的内存,增加更多的排版耗时,进而影响页面性能和用户操控体感。

其次,为何无法数据量化?

因为在 Webview 内,前端并不知道当前页面滚动速度是多少(或者在前端不能准确地用数据的方式表达),滚动曲线和滚动加速度在不同的手机和平台上也是不尽相同的,因此在不同手机上发生白屏的滚动速度阈值是不一样的。

4. 规避快滑闪白

那么,为了平衡快速滚动的闪白问题,可以让容器可以对页面在滚动速度的上限进行限制,这个需要客户端容器侧来处理。

很多前端开发者应该都知道,在老旧 iOS 系统上,如果 WebView 采用的 UIView 架构,由于 UIView 和 js 运行在同一个线程,导致在 UIView 滚动时会阻塞 js 执行,因此在 UIView 的容器内虚拟长列表快速滚动带来的白屏问题是不可避免的,好在现在的 iOS 系统基本上已升级为异步线程模式的 WKWebView 了。

目前,WKWebView 容器滚动的惯性速度和加速度的上限默认是比安卓的要低一些的(这也只是笔者对双平台的滚动对比的体感,没有量化的数据),而且iPhone手机性能通常比较好,因此虚拟长列表页面在快速滚动中,iOS闪白体感不那么明显。

由于安卓的 WebView 容器在快速滚动情况下,页面会拥有很高的惯性速度和加速度。在极端滚动操控下,比如直接触控拖拽滚动条(参考以上的视频)或通过window.scrollTo 快速定位到某个位置,JS 逻辑还来不及计算当前滚动到的可视区域所需展示的 item 内容时,页面就已滚过了该区域,闪白问题几乎是不可避免的。

而针对极端操控的闪白问题,可以在安卓的Web容器侧禁用滚动条的拖拽功能来规避,这并没有在根本上解决问题,但是webview这种机制不一定全是缺点,在大多数场景下,普通速度滑动h5的列表滑动也是很顺畅的,基本也感觉不到白屏,而技术角度看webview内存占用会比flutter低,这其实也是一种优势。

5. 长列表的优化思路

如果业务上,不得不使用长列表,在前端的优化技巧层也是有一些方式方法的。

比如,让列表渲染的 item 不只是可视范围内的 item,而是会在上下边界部分预留足够的buffer,这样可以缓解问题。在双端的具体优化策略上,双端冗余buffer也可以做差异处理。在上下边界的冗余 item 数量,iOS 可以冗余少一些(性能好,但内存少),而安卓则多一些(设备内存大,就多占内存)。

或者,在需要动态计算列表高度的时候将过程简化,比如原来需要每一个参与布局的列表item都需要计算一次,是否可以采用“分组计算”的策略,例如10个item分为1组,回收节点也是按组进行,这样回收算法的复杂度就可能只有原来的1/10。

6. 边界的选择

不管对长列表采用怎样的dom节点回收技术,都必定会面临在用户极端操控下 UI 的变化速度 > 渲染速度问题,在现有的浏览器JS执行必然阻塞Dom渲染的模型下,而且Webview内核层面定义没有透露更多的动态渲染处理API之前,此问题暂时没有彻底的解法。在对用户体验较高的长列表场景,我们倾向于选择Flutter,如果是一级核心场景,主流方案还是Native。

当然,问题虽如此,这并不意味在h5长列表中对非可视区域的节点进行回收是个不必要的设计,毕竟极速滚动的闪白还是一个比较极端场景,很多时候产品对于用户的体验并不没有那么特别苛刻。或许也不应该那么苛刻,特别是人力有限的情况下,毕竟也要综合考虑ROI,但开发者最好要知道技术边界在哪里,避免掉坑里。

三、复杂的视差互动

视差互动(Parallax Effect)或滚动(Parallax Scrolling)指操控网页滚动过程中,同时实现多个元素以不同的速度移动,形成立体的运动效果以提供出色的视觉体验。

1. 视差互动的案例分析

先来看看两个真实业务场景的栗子(视频):

以上视频的栗子是Flutter实现的视差效果,含有两种视差:

  • 往上推,logo需要根据上推手势同步缩小;
  • 切换tab,当前高亮的tab背景和top横线需要同步跟随手势变换。

如果用H5的方式来做这个需求,这两个效果是做不到滑动操控和UI变换的那种顺滑体感。这个本质原因是js是单线程的,当js在执行时DOM渲染会被阻塞,一帧内要做多件事情就可能会出现掉帧,所以做不到丝滑体感。

以上的栗子是基于Flutter实现的视差,是目前比较常见的视频播控落地页的交互模式。在这个业务场景中是一个可以横向切换的多页容器,同时每个播放页面又是一个可上下滚动的嵌套容器:

  • 页面整体可以上下滚动,而下方的评论区块则在视频缩放到最小后可以继续局部滚动;
  • 视差效果则是上推视频容器区块同步缩小,播放器也随着可播区块的缩小而跟随缩小;下拉,则反之。

这个栗子里面包含的边界问题是复杂嵌套滚动的顺滑切换,目前业界实现类似效果的技术方案主要是Nativa或Flutter,没有见过H5实现的效果。

再看一个相同业务的Flutter与H5差异对比栗子。

以上是相同页面的两种技术实现对比,头部的视差互动在滑动操控时,H5有明显的UI抖动,Flutter则不会。可以看到,在我们的业务中,Flutter实现了title随着容器上推渐显和下拉而渐隐,H5做不到顺滑的渐隐渐显过渡,降级的分享页只能取消效果。

2. 为什么Web实现视差有边界

当我们用Webview来实现复杂的视差交互时,为何会触及Web的边界?

究其原因是复杂的视差互动大多需要通过js计算受控目标的Dom实时位置,不断循环“读取dom位置→计算dom位置→改变dom位置”,如果受控目标过多(视差效果通常是2个或以上受控目标,且每个目标采用不同的运动曲线),必然会带来js计算耗时>16.67ms进而导致UI的抖动,就会给人一种互动动画不顺畅的体感。

在前端的业务场景中,复杂一些的动画可以采用css动画来实现,顺畅度会比js实现好很多。这是因为css动画本质是由渲染内核提供的动画组件能力,它和js是异步的,不会因为js运行而阻塞。但有一个问题,css动画的运行状态在js侧没有感知的机制,如果用js和css混合来处理视差、动画会存在两者衔接不顺的问题,这就违背了采用视差效果的初衷。

四、复杂的多tab页面

在现在App业务场景中,多tab的页面是非常常见的UI交互设计,多tab页面设计将相同类型的信息聚合到相同的tab内,不同的分类则按tab横向拓展,这样可以在有限的屏幕范围内尽可能多的容纳更多信息。

1. 多Tab页面的技术难点

图片转自https://developer.aliyun.com/article/791254

可以看到很多大型App的首页都是类似的设计,实现的技术栈是客户端,用Web实现案例会比较少见。当然,在某些App极速版中确实有基于H5实现的,但也会在用户安装App后通过动态加载等方式将Native版本下载回来。为什么Web实现类似的多tab长列表存在困难呢?

其实在上述的边界问题中也谈到了其中的原因,在这个场景中用web实现的话,有以下的难点:

  • 嵌套滚动:上下可以滑动,部分局部内容滚动,外层滚动容器与tab容器滚动是一体化,滚动过渡要自然;
  • 长列表:不同tab容器可以承载着无限列表内容,长列表的信息比较多,需要对于非可视内容做好节点回收;
  • tab吸顶:列表在滚动至顶时,tab栏目菜单需自动吸顶,吸顶过渡自然(通常是某种视差特效);
  • 左右滑动:手势的左右横滑,避免页面边缘退出,相邻tab的内容要保留可切换预览,tab切换可预加载;
  • 浏览记录:不同tab容器的内容是不相同的,在一次浏览周期内要保留已浏览的位置记录;

2. 多Tab的容器拓展

从技术方案上有很多实现的方法和思路,在UC的业务场景中也有很多类似的业务,在这个场景是包含了长列表、视差滚动等边界问题的综合,由于Web容器对于这边边界问题缺少原生组件能力支持,业务落地的技术成本往往比较高,而且对比效果native或flutter的效果差别也比较明显。

因此,针对多Tab列表的场景,在业界的技术选型中往往以native或flutter技术为主。在部分业务场景则通过native拓展多Tab容器的方式,每个tab则是内嵌Webview,而native处理tab与tab之间的页面切换效果和事件派发,这样通过容器封装也可以实现Web的场景拓展,这就是Web容器的多page模式(也叫swiper容器)。

五、App的局部弹窗

在同一个套业务代码里面提供一个局部弹窗,在技术上应该是比较简单的。那么,弹窗在什么情况下会存在边界问题呢?让我们先来看看几个业务场景的诉求。

1. 局部弹窗的场景

  • 场景1:

上面是相机万物识别的结果呈现的页面流程。当拍照完成后,在拍照结果的等待页面中再从弹出一个局部弹窗,用于展示云端的搜索结果内容,承载内容是一个第三方页面(不是当前相机业务负责,而是另外的业务团队)。页面的容器顶部bar拖拽放大结果内容页面,支持分段式触控,也就是弹窗容器高度是可变的,内部支持局部滚动。

  • 场景2:

以上两个视频是分别在两个不同的内容消费场景打开用评论或评论详情,其中一个是图文H5打开一个子弹窗,另一个是沉浸式视频播放流中打开一个半屏弹窗。

因为都是评论是通用的功能,会在很多业务场景中被调用,在技术上我们采用的是H5实现,同行大多采用Native,例如今日头条、腾讯新闻、网易新闻等均如此,它在代码上不属于当前的业务,是一个独立演进的业务模块。

  • 场景3:

这是UC带货直播的业务。在我们的直播容器中,上层可见的UI是由Webview实现的互动层来承载,它包含很多功能实现,例如点赞、礼物互动、弹幕列表、商品卡片、福利活动、作者关注等,所有动态运营能力基本都基于互动层来实现,行业的主要方案是native为主,而采用Webview来实现在技术上是一种新的尝试。

在底部的购物车按钮打开的是当前直播中的商品列表,在原有的产品设计中不属于当前互动业务团队,而是由直播电商团队负责,所以是一个二方页面的局部页面。后来改成了我们通过接口获取,但考虑到互动层的复杂度,我们沿用了独立页面的技术实现。

2. 局部弹窗的边界问题

以上,所有的弹窗功能有一个共同特点,就是不属于当前业务,也就是由A业务调用B业务,实现一个局部的功能界面效果。在业务划分上,可能是不同的业务团队负责,都是H5技术栈的话,业务实现所采用的的前端框架大概率是不一样的。

那么,这里的边界问题是——在两个相互隔离的js代码仓库中,如何实现一个局部的弹窗,而且该弹窗是一个二方提供的具体实现?

技术上,被调用的局部弹窗可以采用js-sdk的方式提供对外服务,业务调用方通过动态注入JS到当前页面的页面中来实现。但这就会带来以下的问题:

  • 业务耦合:需要两个业务是相互解耦的,两个的代码不能产生相互干扰;
  • 版本迭代:被注入到业务中的二方js-sdk需要考虑版本更新问题,是加载具体的js-sdk前调用一个api来决定最新版本,还是提供一个覆盖式发布的js-sdk(不管什么版本都是同一个url,想想就知道有很大的坑)呢?
  • 加载性能:将一个第三方js注入到业务中,本质是一个异步js模块注入的问题,业务方需要解决好性能的问题。

以上这些问题其实纯前端的方式都是不好解决的,因此,这样的局部弹窗更合理的设计是一个独立Web页面,独立页面的好处是避免了业务耦合和版本迭代两个问题,只需要解决加载性能问题就可以了。但在具体的技术实现上,难道用iframe的方式设计这个弹窗吗?

很显然,大多数前端开发者都不太愿意采用这样的设计,因为iframe不好用。因此,这样的局部弹窗页面需要从客户端角度提供定制化的扩展,这就是Web容器的半屏模式,也叫局部容器模式。

六、Web 容器边界的本质

以上举例了5个典型的Web边界问题,哪些是可以在容器范围内进行突破的呢?当然这里所说的边界突破,指的是原来做不了或做得不够好的,通过对容器的封装而获得解决的。

实际上,容器边界能力的突破还是需要Native同学通过容器进行组件/API定制,给前端提供私有组件的方式来解决标准Web容器的能力局限。从Web浏览器的渲染流程上,只要不涉及需要挑战浏览器渲染线程模型的,从原理上可以通过容器封装来解决。

例如媒体播控、局部弹窗,通过Web容器扩展私有组件或API能力是可以比较好的实现边界拓展的,但长列表、视差和复杂多tab等场景所面临的本质问题都是一致的,都需要在足够小的时间片段内完成“读取Dom位置(大小)→计算Dom位置(大小)→改变Dom位置(大小)”,如果这个时间片段超过16.67ms(一帧)都会面临体验不够好的问题。

如果想将时间耗时压缩在足够小的范围内,而 JS作为动态解析型语言的执行效率在计算下一帧Dom位置的耗时就可能会成为瓶颈,而Web标准没有在layou阶段提供获取Dom位置大小信息的能力,则进一步加剧了需要动态计算目标Dom位置的等待时长 。

因此,此类问题在现有的Web范围内是不太好解决的,而解决它可能需要调整浏览器的渲染流程和架构,这样的技术成本还不如用其他技术来得更加实在,技术方案又不是只有Web一种选择,不是吗?

七、Web 容器设计的目标

以上笔者列举了许多Web的边界问题,好像都是说动态方案做不好的或做不了的,对前端而言是不是太过悲观了呢?显然,这并不是笔者的初衷,而是期望通过了解技术实现的边界,才能更好的推动Web容器进行完善和向前发展。

笔者认为,对于Web容器的封装目标是—— 在容器范围内解决原有Web标准容器解决不了的边界问题,并通过容器的标准化封装提升对复杂问题的解决效率,让Web容器能够覆盖更多的业务场景,进而能够拓展前端的业务空间 。这里的关键点有:

1. 解决Web的边界问题

这是一个很重要的出发点,但凡标准能够解决的问题,其实就不需要一个自定义的容器(轮子)来加持。边界的问题其实跟业务类型和场景有很大关系,不同的业务触及的边界是不一样的,在不同的发展阶段业务对于边界的体感或认知也不尽相同。

不过,是不是所有的边界问题都能通过容器来解决呢?显然不是,有些边界可能是在现有Web容器范围内就是无法突破的,该Native的就Native,因此需要开发者对于边界问题的有更精准和更深刻的认识。

2. 解决Web不够标准的问题

很多时候一个App应用需要在不同的平台上提供服务,不同平台的实现或UI展现本来就存在差异,而这种差异对产品而言可能是不可接受的,那么可以将这种不一致的问题在容器层面进行封装或拓展。

这样的能力差异挺多的,例如输入面板、分享面板、日夜间适配、web容器样式(如前进、后退、关闭、收藏等)、跨页通讯、容器push/pop的动画、worker调度和通讯,等等……这些应该是容器封装要解决的基本内容,有一部分是web标准的延伸或拓展(渐进增强),也有部分是针对私域业务的定制优化。

3. 提升复杂问题的解决效率

复杂问题有很多,举个通俗易懂的栗子。例如性能优化,这对于每个业务都是一个复杂的问题。

做过移动H5性能优化的同学都应该知道,纯前端视角是很难将性能优化到极致的,最多就是通过服务端实现SSR、ER边缘渲染,但这并不是最极致的性能优化手段。在App里面做性能优化,极致的优化手段还包括离线包、数据预取、图片预取、NSR预渲染、页面预执行、端智能调度等优化手段。

当然,复杂问题的解决往往也是一个技术成本高的事情,如何将复杂的、成本高的事情简单化、标准化、动态化,这也是容器设计的重要目的。

4. 拓展前端的业务空间

这应该是Web容器封装的最终目标。当然,一个新的Web容器方案,除了性能、交互体验能够满足业务需求外,前端的开发体验也需要得到保障,配套的工程效率工具方案也应该是一个Web容器建设的重要内容,而这往往容易被容器封装的Owner所忽略的。

因此,Web容器框架应该以业务为起点,前端开发者需要深度参与其中,这样才能提出和推动更符合前端视角的诉求落地,而不只是被动接受客户端的封装实现。

责任编辑:张燕妮 来源: Alibaba F2E
相关推荐

2009-06-29 15:51:48

Spring容器

2016-09-01 13:39:33

Linux镜像XML 解析器

2012-07-31 10:07:07

架构系统架构架构设计

2012-01-18 10:20:31

2023-05-29 13:03:54

GPUWebWebGPU

2009-12-21 15:43:05

路由基础算法

2017-06-06 10:30:12

前端Web宽度自适应

2011-05-16 14:54:12

测试用例

2017-03-07 14:23:28

ITILDevOps交付

2009-07-28 10:43:23

Web服务器ASP.NET

2015-01-15 17:41:54

soa云计算BPEL

2022-10-09 14:15:42

短链设计

2016-02-18 10:09:23

12306核心思路架构

2009-07-09 10:25:05

Servlet的Web

2022-06-20 06:24:13

5GWeb前端开发

2010-01-11 17:34:37

C++语言

2011-05-18 16:02:08

XML

2009-07-06 10:25:14

Java Web Se

2011-09-08 17:48:33

Web Widget

2023-12-07 19:19:11

点赞
收藏

51CTO技术栈公众号