朋友圈极限优化

1,622 阅读3分钟

前言

Feed流是大多数软件的标配,大多数都支持富文本、图片、视频,广告等。这个模块因为功能的增多变得越来越复杂,性能也变得越来越低,所以优化Feed流是必须的。 Feed的主要是图文显示、异步渲染。之前我们采用的是YYText的富文本支持,YYText在初期是能满足需求的,但YYText作者已经不维护了,还有YYText调用复杂和支持功能比较少,已经不能满足现在复杂的需求,为了解决之前留下的问题,参考网上开源库,就弄出了VVRichText.

之前的版本

做第一个版本的时候,既要快又要好的支持需求,选型YYKit和AsyncDisplayKit中纠结,因为AsyncDisplayKit侵入性和兼容性问题,最终采用了YYText框架支持富文本显示,还有YYWebImage框架很好支持Gif和Webp格式。但这个方式有几个问题:

  • 采用这个这种方式就不得不把Feed被拆分成5个Cell。头像和文字成一个Cell,图片显示成一个Cell,时间显示和更多按钮一个Cell,点赞一个Cell,评论一个Cell,拆分的Cell过多,也造成渲染多次,维护麻烦。
  • 引用YYWebImage的框架,不兼容之前的图片SDWebImage缓存库。又引入的YYCache和YYWebImage库。
  • 数据和显示耦合紧密。
  • 对点击、长按事件支持逻辑复杂。
  • 计算一个Feed的高度复杂

优化的版本

解决之前的问题,网上没有答案,只能自己解决问题,这个VVRichText具备以下特性,解决了我所有的问题。

  1. 支持富文本显示,支持异步文本渲染。
  2. 可以在文本中插入本地图片,网络图片或UIView对象。
  3. 支持WebP、GIF等格式。
  4. 支持添加单击和长按事件到文本、图片。
  5. 绘制文本框架,绘制空心字,设置文本垂直对齐属性等。
  6. 解析文本中的表达式,如http(s)链接、@user、#theme#、电话号码。
  7. 快速设置图像角半径属性和模糊处理等。
  8. 支持布局控制多个图文元素
  9. 支持SDWebImage缓存库

例子

VVRichText,将页面元素抽象成文字和图片两个对象,自动布局多个对象,最终将所有对象最终渲染到一个View上。性能也是达到最优,在iPhone5手机上也 能如丝滑般的体验。

文字对象例子 TextWidget
  • Feed正文内容模型
VVTextWidget *contentTextWidget = [VVTextWidget new];
contentTextWidget.maxNumberOfLines = 0;
contentTextWidget.text = statusModel.content;
contentTextWidget.font = [UIFont systemFontOfSize:15.0f];
contentTextWidget.textColor = VV_COLOR(40, 40, 40, 1);
contentTextWidget.frame = CGRectMake(nameTextWidget.left, nameTextWidget.bottom + 10.0f, VV_SCREEN_WIDTH - 80.0f, CGFLOAT_MAX);
// 添加长按复制
[contentTextWidget vv_addLongPressActionWithData:contentTextWidget.text
                                  highLightColor:VV_COLOR(0, 0, 0, 0.25f)];
// 解析表情、主题、网址
[VVTextParser parseGeneralEmojiWithTextWidget:contentTextWidget];
[VVTextParser parseTopicWithVVTextWidget:contentTextWidget
                               linkColor:VV_COLOR(113, 129, 161, 1)
                          highlightColor:VV_COLOR(0, 0, 0, 0.15)];
[VVTextParser parseHttpURLWithTextWidget:contentTextWidget
                               linkColor:VV_COLOR(113, 129, 161, 1)
                          highlightColor:VV_COLOR(0, 0, 0, 0.15f)];
图片对象例子 ImageWidget
  • Feed头像模型
VVImageWidget *avatarWidget = [[VVImageWidget alloc] initWithIdentifier:AVATAR_IDENTIFIER];
if (statusModel.avatar) {
    avatarWidget.contents = statusModel.avatar;
} else {
    avatarWidget.contents = [UIImage imageNamed:@"defaultavatar.png"];
}
avatarWidget.cornerRadius = 20.0f;
avatarWidget.cornerBackgroundColor = [UIColor whiteColor];
avatarWidget.backgroundColor = [UIColor whiteColor];
avatarWidget.frame = CGRectMake(10.0f, 20.0f, 40.0f, 40.0f);
avatarWidget.tag = 9;
avatarWidget.cornerBorderWidth = 1.0f;
avatarWidget.cornerBorderColor = [UIColor grayColor];
  • 将图片和文字的Widget对象添加到VVWidgetCollect中
[self addWidget:nameTextWidget];
[self addWidget:contentTextWidget];
  • Cell高度计算
self.height = [self suggestHeightWithBottomMargin:15.0f];
  • 单独更新一个Cell异步线程渲染会闪烁,切换为主线程渲染,比如点击展开Feed正文
//展开Cell
- (void)openTableViewCell:(FeedCell *)cell {
    NSInteger row = cell.indexPath.row;
    [self.feedVM expendData:row];
    [self reloadCell:row];
}

// 异步线程渲染会闪烁,切换为主线程渲染
- (void)reloadCell:(NSInteger)row {
    self.asynDisplay = NO;

    [self.tableView beginUpdates];
    [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:row inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
    [self.tableView endUpdates];

    self.asynDisplay = YES;
}

集成

  • 通过pod 'VVRichText'集成到项目中

感谢