背景

闲鱼会玩社区是一个以分享个人趣味生活为主的内容社区,在社区的运营过程中,经常有一些文章形式的内容在会玩广场上投放。此前文章创作是在一个主要承载营销搭建的平台上完成的,这种方式首先不是专门为文章场景服务的,导致搭建出来的页面是一个静态页面,数据无法被理解,也无法进入审核和分发链路。而且搭建工具无法对外使用,从而无法让外部的创作者参与文章创作。因此,我们想从零开始开发一个能快速发布且高可扩展文章结构形式的发布工具。

调研

业界也有许多同类型的产品,如常见的知乎、掘金、微信公众号等。微信公众号的文章无论从发布体验、消费体验以及内容结构扩展上都做得很好。我们总结微信公众号文章有以下几个特点:

1.文章内容形式丰富度高;

2.浏览体验极好;

3.支持第三方内容模版;

闲鱼会玩文章希望能在内容形式,浏览体验上尽可能对齐微信公众号文章的标准。但闲鱼会玩文章与微信公众号也有一定的区别,微信公众号面向不同的自媒体,不同垂类的自媒体对文章的展示调性是不同的,因此对文章的内容样式不会做太多限制,而闲鱼的社区有着自己的调性以及自己的品牌主题色,内容形式会更加收敛。

目标

文章内容结构自由度高,内容排列可以是标题、文字段落、图片以及交互组件(如投票器、链接卡片等)的排列组合,因此高可扩展性非常重要。此外,发布器作为文章创作入口,需要存储创作者全部内容信息,包括字体、字号、颜色、段落、图片等。还有展示页在端上的性能体验也是非常重要的指标。因此我们定了以下几个系统的关键目标:

1.信息还原度百分之百

2.内容结构可扩展

3.展示页秒开体验

文章发布链路大致流程如下所示:

方案

围绕既定的设计目标,如何实现呢?我们的方案是根据一套约定的schema协议来表达文章内容的所有信息,协议记录和表达所有需要在客户端还原展示的信息,最后通过这套协议把发布器和展示页连接起来。可以看出,设计一套通用、简洁的文章内容协议是方案的关键。文章发布器负责产生schema,结构化存储后,文章展示页获取到该schema然后在端上解析协议并展示出对应的内容信息。方案大图如下所示,标橘黄色表示协议相关的部分,它出现在了几乎整个链路中。

协议设计

梳理出协议设计目标如下:

1.规则简洁易懂。规则越简单,则根据协议创建schema数据以及解析schema数据就越容易。

2.可扩展。未来的文章形式可以是非常丰富的,要求用这套协议表达任意的内容形式。

3.结构化存储。将图文内容可以进行结构化抽取和存储,文章内容的schema可能非常大,而数据库存储字段一般会有字符上限,需要压缩schema。此外文章的实体内容需要进入安全审核链路,这也要求我们必须进行内容结构化抽取。

围绕着以上三个诉求,我们我们基于钉钉的富文本协议,定制了一套符合要求的协议规则。

协议逻辑

现有元素标签

•root - 根元素

•p - 正文标签

•span - 文字标签

•img - 图片标签

•h2 - 二级段落标签

•card - 卡片标签

•idleVideoCard - 视频卡片

现有属性

1.常规属性

2.图片属性

3.视频属性

如何扩展

我们规定未来所有新增的插件,都作为一种子类的卡片,可以自定义卡片类型,卡片数据统一放到metadata字段中,然后端上根据卡片类型做对应的组件,并将metadata中的卡片数据信息作为参数导入组件中去,从而做到未来任意插件,都能映射到协议里。

结构化存储

协议是一种json schema,这种在关系型数据库中存储是一个比较头疼的问题。图文内容存储会将内容分成三个字段,分别是文本、图片数组和自定义扩展字段。文本和图片的结构化信息会用于安全审核以及算法推荐识别,自定义字段用来存储业务上的其他信息。我们的第一版方案是将文本和图片内容提取出来单独存储,并将整个json字符串全部放到自定义字段中,这样只需要一存一读就可以了。然而,真实场景中,自定义字段有字符数限制。因此需要对json字符串进行一定的转译和压缩,只保留必要的样式和排版信息即可。

发布器

发布器的核心是一个富文本编辑器,市场上主流的react编辑器有开源的slate.js、facebook的draft.js,阿里内部比较成熟的富文本工具有语雀富文本编辑器和钉钉文档团队的we-editor。从协议的复杂度和可扩展性上考虑,我们选型了钉钉的we-editor。

富文本编辑器的使用上,除了要处理在编辑器上手写文章场景外,从外部粘贴内容进编辑器的场景复杂度会更高。因为内容本身就带有富文本样式,从而导致文章样式不可控,生成的富文本协议内容混乱,不利于结构化审核和端上展示页渲染。

粘贴场景处理

粘贴进来的内容是带上内联样式属性的标签,如div、span、a、h1、h2、img、video等。我们的做法是,在粘贴的时候,将所有的内联样式清除,并只处理格式范围内的标签。对于img、video标签,则需要更多的处理,因为img和video的src是一个地址链接,这些链接如果是站外连接,就会存在访问跨域,同时对平台来说也存在安全风险。做法是对站外资源做转存处理,即将站外链接下载后通过内部服务将资源转存到可靠的资源服务器上。

插件扩展

插件扩展通过定制编辑器插件来完成。我们只保留了基础的redo/undo、字体加粗、字体对齐、添加图片等编辑器自带能力,其他如视频、连接能力通过自定义插件完成。通过对we-editor插件体系封装,开发者可以像开发react组件一样开发插件。封装过程是将扩展插件都当作一种卡片,在schema里指定工具栏内容,对应点击事件,以及插入富文本的卡片样式等,即可插入任意插件。以一个插入视频的插件为例:

点击该插件工具栏按钮的时候,选择插入idleVideoCard类型的卡片即可。

函数服务层

在发布器的发布链路中,我们设计了一层faas函数服务层。主要考虑以下几个原因。

1.安全问题。结构化信息抽取算法应该放到服务端计算,否则会存在刷接口绕过安审链路的漏洞。

2.抽取和还原都通过js实现。从而保证一套规则技术栈统一。

下图为大致的数据流转示意图:

文章展示

文章展示的原理是通过协议规则将经过处理的schema还原成真正的schema信息,并解析信息转化成对应的可视化组件。我将重点讲协议解析和性能优化。

协议解析

理论上只要能正确解析出富文本schema协议表达的富文本信息,在端上可以还原成任意对应的设计规范,这也是未来我们可以做集团统一文章发布工具的基础。即只要保证协议一致,端上的展示可以大不相同。还原函数伪代码如下所示:

体验优化

前端的性能性能优化话题是一个老生常谈的话题,限于篇幅有限,这里只讲这次在文章详情页的几个主要优化方案。性能数据结果上,跨端首屏渲染时间从1700ms优化到1000ms左右,做到了秒开。先上优化前后效果对比:

在讲具体方案前,我们先来看一下一个h5页面在webview里是加载流程:

在这个链路中,最消耗时间的是各种资源的IO,包括页面文档的IO,样式文件、js文件和图片的IO以及数据接口请求的IO。其次耗时的是webview的启动耗时。因此我们的优化主要围绕减少IO以及提前IO的思路去进行。

  1. 资源combo

    页面加载中除了包含业务的js文件之外,还包含jstracker的资源,rax的框架资源,安全相关的js等,将这些资源合并成一个资源请求,则可以减少很多次请求IO,从而降低首屏渲染时间。

  2. 图片懒加载

    文章中一般会有很多图片,这些图片大部分不会在第一屏中就出现,因此可以将未出现在屏幕中的图片先不加载,等用户下滑至该图片出现在屏幕中时,才请求该图片资源。

  3. 本地资源缓存

    文档资源下载以及js资源一般来说是一个长时间不变的东西,如果这些资源提前在客户端空闲的时候就已经下载好,等到请求这些资源的时候,客户端发现本地已经有了同名的资源,就拦截这次资源请求,返回本地缓存好的资源,则可以大大降低首屏渲染时间。

  4. 数据预取

    首屏渲染的时间长短有一部分取决于第一次调用的接口的返回速度,而接口请求一般要等到js逻辑触发接口请求时才发出。如果首屏需要获取的请求是一个确定的参数,那么是否可以将请求接口这个时机提前呢?我们数据预取的方案就是在用户点开页面的请求URL中就带上首屏需要请求的接口参数,然后客户端获取到这个参数后异步地请求这个数据,将结果缓存到客户端上。等到js逻辑需要发出请求的时候,判断当前请求是否已经被请求过,若请求过,则直接返回缓存在客户端上的接口数据。

  5. 去掉客户端loading

    客户端loading本来是webview自带的能力,表示当前页面还有资源在加载,但其实虽然有资源在加载,但首屏的页面信息其实已经加载出来的。去掉客户端的loading,可以给用户带来更快的体感,虽然实际上并没有加快这个流过程。优化后的加载流程如下图所示:

性能优化无止尽,因此文章展示页的优化也会一直做下去,可以考虑提前启动webview容器,ESR、NSR等方式优化。

展望

到目前为止已经完成了文章发布工具从0到1的建设,未来需要做的事情还有很多。基于这套高可扩展的协议,可以扩展出更多更丰富的文章内容形式以及交互玩法,如投票器、弹幕、文章模版等,最终可以沉淀出一套可开放的基于当前协议的模版插件开发体系,以适应不同的文章内容体系。此外,性能体验优化会继续以高标准的要求不断进行优化。

再往上层看,文章内容只是会玩社区内容的其中一种承载形式,我们希望有一个包含更多创作能力的创作者站点工具。pc侧的创作者中心和手机端上的创作者发布中心呈一个互补的态势。普通的创作者更倾向于即来即发,随手发,随时发,而对内容质量有更高追求的一些pgc创作者则更关注内容质量,发布效率,内容消费数据等比较专业的指标。

因此在完成了基本的发布能力后,我们会逐渐完善整个创作者发布链路,集普通图文创作、视频内容创作、文章创作、内容管理、数据中心、热点内容发现于一体的完整专业创作者发布工具。

闲鱼易用高可扩的文章发布工具建设相关推荐

  1. 闲鱼如何0到1搭建一套发布引导链路

    背景 随着闲鱼持续不断的需求迭代和业务迅速的发展,如何进一步提升用户的使用.留存和活跃的转化,进而带动整体二手交易市场的增长是核心命题.经闲鱼内部数据分析我们发现,用户的商品发布数与成交量呈现明显正相 ...

  2. 从0到千万DAU,这5年闲鱼架构如何演进?

    阿里妹导读:闲鱼品牌创立于14年阿里的某个茶水间,从0开始到现在千万DAU,5年时间里闲鱼见证了闲置物品从线下到线上交易的转移.而线上交易的繁荣,则需要业务架构做相应的调整.演进才能支撑业务的快速发展 ...

  3. QCon演讲|闲鱼从零到千万DAU的应用架构演进

    导读:业务架构要随着业务发展做相应的演进,继而支撑业务的快速发展.本文主要通过介绍闲鱼从零发展到千万级DAU应用的不同阶段的业务特点.核心问题以及针对性的架构演进,来阐述业务架构的演进思路与心得. 闲 ...

  4. 系列文章|闲鱼商品理解之精品库建设

    现状 闲鱼是一个基于C2C场景的闲置交易平台,每个用户既是买家也是卖家,并随着这些年的高速发展,一方面闲鱼的商品越来越丰富,在自由享受交易乐趣的同时也存在商品良莠不齐的问题,另一方面这些年闲鱼一直在深 ...

  5. 抓球球的机器人应该怎么玩_闲鱼2019年应该怎么玩?闲鱼上面的几大规则

    闲鱼2019年应该怎么玩?闲鱼上面的几大规则 如今已经是2019年了,还是有好一些的伙伴们在求闲鱼流量,闲鱼新的一年是不是有什么大的改动,还可以照着往年的玩法继续做闲鱼吗,对于这样的问题,我实在有些看 ...

  6. 走近科学,探究阿里闲鱼团队通过数据提升Flutter体验的真相

    背景 闲鱼客户端的flutter页面已经服务上亿级用户,这个时候Flutter页面的用户体验尤其重要,完善Flutter性能稳定性监控体系,可以及早发现线上性能问题,也可以作为用户体验提升的衡量标准. ...

  7. 闲鱼如何建设技术舆情治理体系 (多图多代码)

    简介: 从日志.监控.性能检测几个方面建设了有日志可查.有数据可依的排查体系 现状和问题 闲鱼的舆情治理,依托阿里集团的设施建设,有以下能力: 崩溃异常.性能在线聚合查询: 本地日志:TLog: 在线 ...

  8. 拆解闲鱼无货源盈利模式,需要注意的细节太多?

    一.为什么要做闲鱼项目? (更多精彩干货请关注共众号:萤火宠) 闲鱼目前是阿里旗下的.全国最大的二手交易平台.用户以80后.90后为主,女性多于男性,学生.宝妈及上班族居多,不仅用户数量庞大,且互动率 ...

  9. 兴趣标签体系告诉我,闲鱼的95后是这样的...

    背景与挑战 - - "水果糖小椿 M39 暂挂" - - "列表科幻?" 不知大家能否读懂上面的对话,但在闲鱼,这样的对话每天都在发生.数据显示,闲鱼约30%的 ...

最新文章

  1. 数据准备技巧及其对机器学习的重要性
  2. 前端学习(2501):动态绑定样式
  3. Oracle:数据类型速记
  4. python全栈开发工程师_老男孩Python高级全栈开发工程师三期完整无加密带课件(共104天)...
  5. 汇编语言和本地代码及通过编译器输出汇编语言的源代码
  6. 信息安全工程师考试心得体会
  7. java filter 跳过_如何在java中的过滤器链中跳过一个过滤器
  8. Codeforces 833D Red-Black Cobweb [点分治]
  9. “武汉城市之根”发声: 又见宝藏系列数字藏品独家发行
  10. jquery dataTable 参数详解
  11. 使用matplotlib时报错:RuntimeWarning: Glyph 20998 missing from current font.
  12. 计算机组成原理的重难点,《计算机组成原理》重点难点习题
  13. #创新应用#善听听书:进入听书的时代!
  14. Python遥感可视化 — Basemap作Albers投影
  15. wap视频广告遇到的问题
  16. CCF CSP认证考试在线评测系统
  17. 云课堂计算机测试答案,2020智慧职教云课堂计算机应用基础答案最新最全章节测试答案...
  18. windows防火墙设置_成都企业级网络防火墙
  19. 计算机文件共享xp,两台XP怎么共享文件
  20. AcWing 4411. 三仙归洞 (简单模拟)

热门文章

  1. Android中铃声总结【安卓源码解析一】
  2. mysql 服务没有报告任何错误_mysql无法启动服务没有报告任何错误
  3. Notepad++下载安装介绍教程
  4. Mysql的主键和索引
  5. git 怎么回退已经push的版本_git push 操作代码回退
  6. RN 实现阴影,解决Android阴影问题 react-native-shadow
  7. proe5.0启动失败,光标转了几圈后没有任何反应
  8. h5打开麦克风权限录音_微信H5录音实现
  9. HTML5+CSS期末大作业:运动体育网站设计主题——体育铅球(5页)带注册 期末作业HTML代码
  10. j2me游戏开发之LWJGL(Lightweight Java Game Library)