分享组件改版小结

分享组件是全站通用组件,用于自定义分享信息、统计推荐关系,是营销团队打包输出 MGM 能力的重要工具。

分享组件支持集团内外部应用宿主(微信、金管家、银行、证券等app)中,分享链接/海报到不同渠道(微信、微博、行员app、快乐平安等)。

效果预览

改版前后的截图:

平安银行分享组件改版前后截图

需求背景

改版前分享组件面临的挑战主要有两个:

  1. UI层面——弹窗面板空间有限,最多仅能展示六个分享图标;
  2. 扩展性——原先组件打包为单一文件,含有所有宿主的逻辑和依赖文件,随着渠道和业务逻辑增加,文件尺寸越来越大,达到性能瓶颈。

这和之前微海报改版需求背景有共通之处。

方案

针对第一个挑战,我们将页面居中弹窗,改为底部弹层,单行四个,超出则可滚动。

针对第二个挑战,将单文件拆分为二,做了异步加载。并划分为同步模块、异步模块、渠道模块,实现按需加载。

盗用罗帅的结构图:

分享组件结构图

改版前后的文件构成图:

分享组件文件构成图

左边是单一文件,所有依赖和逻辑代码在一个文件中,随着业务逻辑日益复杂和接入的渠道增加,文件尺寸和维护难题渐渐显露。

右边是拆分后的,其中 loader 模块负责环境判断和UI、事件绑定等初始化操作。
可异步执行的逻辑如请求流水号,放到 AsyncMode 类。
渠道专有逻辑,继承 AsyncMode 类,和 jssdk 一起,各个渠道分别打包到 asyncMode**.js 文件中。

文件名中的**,为渠道名称首字母缩写,loader 根据宿主环境判断加载对应的渠道 AsyncMode 文件。比如页面投放到微信,loader 会加载 asyncModeWX.js 文件,投放到金管家app,则加载 asyncModeJGJ.js 文件。这样就实现了不同渠道的逻辑代码隔离,避免互相牵扯,缩减加载的冗余代码。

工程化方面,组件使用 typescript 编写,构建采用 rollup (TS 的类型系统和 ES6 特性支持,特别是 Class 用在新版组件里,真香!)

组件工具库 kits

改版过程中还产生个副产物 kits 工具库,其实就是 zepto 的精简版——由于原来的组件依赖 zepto ,这对于越来越多外部页面接入的通用组件而言显然不合时宜,所以需要剥离依赖。有想过改用原生写法,但这样一来基本就成了纯体力活,且后续维护不便。就想着不如把组件所使用到的 zepto 方法抽离出来,后续还可进一步优化,顺便可以归纳一下组件中常用的库工具方法是哪些。结果如下:

Core

  • $()
  • $.camelCase
  • $.contains
  • $.each
  • $.extend
  • $.fn
  • $.grep
  • $.inArray
  • $.isArray
  • $.isFunction
  • $.isNumeric
  • $.isPlainObject
  • $.isWindow
  • $.map
  • $.noop
  • $.parseJSON
  • $.trim
  • $.type
  • add
  • addClass
  • after
  • append
  • appendTo
  • attr
  • before
  • children
  • clone
  • closest
  • concat
  • contents
  • css
  • data
  • each
  • empty
  • eq
  • filter
  • find
  • first
  • forEach
  • get
  • has
  • hasClass
  • height
  • hide
  • html
  • index
  • indexOf
  • insertAfter
  • insertBefore
  • is
  • last
  • map
  • next
  • not
  • offset
  • offsetParent
  • parent
  • parents
  • pluck
  • position
  • prepend
  • prependTo
  • prev
  • prop
  • push
  • ready
  • reduce
  • remove
  • removeAttr
  • removeClass
  • removeProp
  • replaceWith
  • scrollLeft
  • scrollTop
  • show
  • siblings
  • size
  • slice
  • text
  • toggle
  • toggleClass
  • unwrap
  • val
  • width
  • wrap
  • wrapAll
  • wrapInner

Detect

  • Detect module

Event

  • $.Event
  • $.proxy
  • bind
  • delegate
  • die
  • event.isDefaultPrevented
  • event.isImmediatePropagationStopped
  • event.isPropagationStopped
  • live
  • off
  • on
  • one
  • trigger
  • triggerHandler
  • unbind
  • undelegate

Ajax

  • $.ajax
  • $.ajaxJSONP
  • $.ajaxSettings
  • $.get
  • $.getJSON
  • $.param
  • $.post
  • load

Form

  • serialize
  • serializeArray
  • submit

    Effects

  • $.fx
  • animate

    Touch

  • Touch events

精简后的代码连注释不到800行,如果不要 ajax 相关方法,挪出所在匿名函数即可,可再减少 300 行代码,算是抄了个轮子吧… 不过还蛮适合组件使用的。

想起七年前在17173参与的第一个组件——登录弹窗组件,直接 <iframe src="javascript: 后面 document.write style 和 script 标签,实现资源动态、异步加载,极大缩减启动脚本文件尺寸,并实现组件环境和宿主页环境的隔离,还支持到 ie6 版本。方案沿用至今想来是没什么大的问题。竟有些怀念当时满满的草莽气息。

17173扽股弹窗

分享到:

评论完整模式加载中...如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理