据相关数据显示,截至2017年底,中国手机新闻客户端用户规模达到6.36亿人,移动App已经成为新闻和内容传播的最重要途径之一。而伴随着行业的竞争和发展,App中的内容页在提升App品质、提升使用时长及提升用户黏性等方面,扮演着更为重要的角色,同时也面临着更大的挑战。
- 内容页在呈现上越来越丰富。新闻资讯作为内容页的主体,逐渐增加了更多的文字样式、内容形式、富媒体、以及广告、投票等更为丰富的元素。
- 内容页需要更多扩展区域来提高使用时长及用户黏性。在资讯主体之外,各个App逐渐打造了例如关注模块、推荐阅读模块、评论模块、运营模块等越来越多的扩展阅读区域。
- 短视频、直播的争夺越来越激烈。越来越多的新闻App都将视频作为独立的模块和独立的内容页进行展示。
- 同质化产品竞争激烈。要求更快的迭代速度、更优质的用户体验、更小的实现成本。
所以,新闻类App内容页架构的设计和技术的优化,也要配合产品形态的发展,在越来越复杂的需求挑战下,拥有快速响应的能力和稳定优质的体验。
本文结合分析目前主流(DAU)新闻类App如今日头条、腾讯新闻、天天快报、一点资讯等内容页技术方案的选择,一起探索新闻类App内容页的技术实现和优化。
—— 几十行代码完成新闻类App多种形式内容页
HybridPageKit :一个针对新闻类App高性能、易扩展、组件化的通用内容页实现框架。
基于ReusableNestingScrollview、WKWebViewExtension、以及本文中关于内容页架构和性能的探索。
1. 概念定义
结合目前主流的内容页实现方式,我们把内容页分为上下两个部分,为了方便后续的阅读先简单定义下关键的名词。
- 上部分通常用WebView实现。常规包括标题 + 作者(关注)+ 资讯内容,我们称为WebView内容区。
- 下半部分主要是平行于WebView的各种扩展内容,常规包括点赞打赏、广告推广、相关推荐,热门评论等等,我们称为Native扩展区。
- WebView中每个复杂UI呈现、扩展区中每个独立模块,我们都称为一个模块或组件。
完整来看,整个内容页右侧(右滑)普遍为评论页。无论是之前流行的ScrollView右滑还是近期流行的Push新页面,这两种方式实现起来都比较简单且较为独立,故本文暂时忽略右侧(右滑)评论的部分。
2. 目录
技术方案选择 -
1.WebView类型选择
不同于微博,新闻类App的内容以段落性的文字为主,配合段落间的图片、富媒体等。同时为了满足跨平台的一致呈现、PC网页的文章转载、不同平台文章的抓取,以及注重阅读而非交互等原因,使用WebView加载渲染本地的HTML字符串数据已经成为了新闻类App通用的方案。
1. UIWebViewVSWKWebView
稳定性:
UIWebView较多的WebCore、JavaScriptCore Crash,以及系统性的内存泄露导致OOM,对整个App的稳定性都是极大的隐患。反观WKWebView,基于独立进程,不会占用App的内存计算,同时也不会导致主App Crash。所以在系统级的稳定性上,WKWebView有着极大的优势。
加载速度:
WKWebView通过JIT大幅优化了JS的执行速度,但是对于新闻类App内容页的使用场景来说,简单的进入、退出页面,且单纯的加载渲染HTML字符串,WKWebView比UIWebView慢了很多(Benchmark)。
兼容性:
NSURLProtocol的无法使用、长按MenuItems Bug(before iOS11)、iOS8不能删除Cache、设置Cookies及UA、POST参数、异步执行JS...这一系列的问题,成为了稳定项目替换WKWebView最大的挑战。
扩展性:
WKWebView具有更加丰富的接口、更多HTML和CSS的支持、以及更加友好的JS交互。同时Api的持续更新和社区的活跃,从长远使用的角度看有着极大的优势。
2. 修复、扩展WKWebView
通过以上的分析,WkWebView从系统级的稳定性、性能以及后续扩展性都有很大的优势。通过WKWebViewExtension扩展修复原生WKWebView,结合HybridPageKit中WKWebView的回收复用逻辑,极大程度上解决了原生WKWebView的问题,起到了很好的效果。
修复扩展的问题:
通过逐阶段分析耗时,在内容页的使用场景下,WKWebView从alloc到准备开始渲染这段时间,有着极大的优化空间。在浏览内容页这种场景下,HybridPageKit中通过WKWebView的复用回收以及资源缓存,极大降低了WKWebView加载渲染HTML的时间,使之低于原生UIWebView。
通过私有方法的扩展和代码优化,在WKWebViewExtension中支持了URLProtocol、修复了MenuItems的bug、支持iOS8清理缓存、扩展安全的JS执行方法、以及扩展NavigationDelegate以兼容JSBridge逻辑等。
无需解决的问题:
对于新闻类App内容页的使用场景,一些WKWebView的问题并没有必要形成通用的解决方案以兼容代码。比如POST请求不能带参数、Javascript异步执行等问题,都可以通过代码的重构来进行解决。尤其不推荐卡主Runloop从而同步JS的方式。
遗留问题:
目前,在使用WKWebView的过程中,唯一未解决的问题就是可靠、全面的白屏检测方案,从而支持WKWebView在任何情况下的Crash进行重载。诸如系统Crash回调、WebView Title监听、ContentSize监听、甚至屏幕随机取色值等方法都不能满足全部的白屏场景。
2. WebView内容区与Native扩展区的衔接
对于目前的主流App来说,单纯的WebView已经无法满足复杂的呈现和逻辑。如何在页面中合理的处理WebView与扩展区中的多种View协同滚动,灵活扩展,并且支持下拉刷新、上拉加载等操作,不同的新闻类App也有不同的技术方案。
1. 结合TableView

实现原理:
由于扩展区中列表类型的模块较多(例如相关文章、评论等),最简单的实现即Native扩展区的模块拆分到Cell的粒度,整体使用TableView实现。对于扩展区和WebView的衔接,如上图一般有两种实现方案:TableView根据WebView的Inset(或Div占位)插入到WebView中 & WebView作为TableView的Header。
优点:
这种方法相对简单,容易实现内容页各个模块的布局,同时基于TableView的刷新逻辑,也能动态的处理各个模块的更新、插入删除,并且支持家在更多等。和WebView的结合滚动也较为流畅。
不足:
这种方式将Native扩展区的模块粒度都区分到Cell的层级,列表类型模块只能通过Cell或者以Section的模式进行管理,同时也无法跨页面的整体复用UI及业务逻辑。UI的布局依赖TableView模式,灵活性较差。随着组件类型的增多,非同质性的View也没有充分利用TableView的复用。
同时无论使用哪种方式和WebView衔接,都影响了WebView、TableView的独立渲染展示,增加了维护的困难。并且Header与Inset对于头部区域的扩展,如下拉刷新等,实现都较为困难。
登录 | 立即注册