如何优化iOS系统上的图文评论UI界面

简介: 在我们的社交 APP 上,⽤户的动态由精美的照⽚ 、视频和⽂字组成。对于每张照⽚和视频, 我 们都会展示出完整的标题和五个最新评论。由于⽤户喜欢使⽤标题来讲述照⽚背后的故事, 因此它们通常很⻓ 、很复杂, 并且可能包含超链 接和表情符号。渲染如此复杂的⽂本带来了⼀些问题, 它在滚动时造成性能下降。 即使在 iPhone 12 这样的新设备上, 复杂标题的初始⽂本绘制需要⻓达 50 毫秒, ⽽⽂本展示 需要⻓达 30 毫秒, 渲染速度很慢。⽂本问题还是简单问题, 有时我们需要加载更加复杂的图⽚甚⾄视频。所有这些步骤都发⽣在 UI 线程上, 导致app在⽤户滚动时丢帧。

在我的社交 APP 上,⽤户动态由精美的照视频成。于每视频, 我 展示出完整的标题和五最新评论由于⽤户使⽤标题来讲述照背后的故事,因此它们通常很、很复杂且可能包含超接和表情符渲染如此复杂带来问题滚动时造成性能下降。 

即使在iPhone12这样的新设备上,复杂标题的初始制需要⻓达50毫秒,⽽⽂本展示需要⻓达30毫秒,渲染速度很慢。问题还简单问题 需要加更加复杂图⽚⾄视频所有些步发⽣UI 线程上, app⽤户滚动时丢帧

基础知识:

始之前, 最好先了解本的基本念。

线程不应该⽤于繁重的操作,主要于:

1.接受⽤户输⼊/交互;

2.更新UI

线程必须处理太多操作最常的后果是出现丢帧现象,不能保60 fps(每16.67毫秒会发⽣这种现象。

精准地识别并调试丢帧问题

很容易发现帧问题最常的表形式是⽆响应/

可以使友盟+U-APMiPhone12这样的新款设备上是否会发⽣

1.jpg

显⽽iPhone12 上也发⽣了卡, 由此推的代存在化空⽽并⾮⽤户设备 配置问题。接下, 我需要更准确的跟踪卡顿问题。我们尝试了使CADisplayLink    TimeProfiler

使CADisplayLink

class DroppingFramesHelper: NSObject {

private var firstTime: TimeInterval =0.0

private var lastTime: TimeInterval = 0.0

func activate() {

let link = CADisplayLink(target: self, selector: #selector(updat

link.add(to: .main, forMode: .commonModes)

}

@objc private func update(link: CADisplayLink) {

if lastTime ==0{

firstTime = link.timestamp

lastTime = link.timestamp

}

let currentTime = link.timestamp

let elapsedTime = floor((currentTime - lastTime) * 10_000)/10

let totalElapsedTime = currentTime - firstTime

if elapsedTime > 16.7 {

print("[DFH] Frame was dropped with elpased time of \(elapse

}

lastTime = link.timestamp

}

}


然后, 在 AppDelegate 法中访问它⼀个实例:

didFinishLaunchingWithOptionsDroppingFramesHelper().activate()

在,如果测试程序出现丢帧的情可以在控制台上它们

2.jpg

采取的措施

在通控制台和友盟+U-APM知道了掉的情存在,能做些什呢?可以采取些下⾯这些措施:

1视图和透明视图

2连续调⽤中的负载

3JPEG

4渲染

 们将会⼀⼀进⾏讨论

1.减少试图和透明试图的数量

了提⾼应⽤程序的性能,先要做的事是:

 视图

 降低透明度

法很简单

label.layer.opacity = 1.0

label.backgroundColor = .white

了更加容易地察到重的透明度,可以使⼀个⾮便的具:  调试->视图调试->渲染->颜⾊混合

这个⼯可以松地发现视图, 如下所示:

3.jpg

在我不需要这⾥使⽤标签将背景颜⾊设晰。

2.最小化“连续调用函数”中的负载

显⽽cellForItemAtindexPathscrollViewDidScroll这样连续调⽤的函须运算得常快。

所以我们尽可能使单纯视图/元格,使⽤⾮巧快速的法。(例如, 不涉及布局束、象分配的配置)

3.解码JPEG图像

们处丢帧问题时化点像解

通常, 这个操作是在主线程上是由 imageViews 完成的, 但在会导致我应⽤程序慢。

这个问题⼀种决⽅案是码⼯作移后台列。这样操作不UIImageView的正常解样⾼效,mainThread是空的。

 在后台解码图像:

extension UIImage {

class func decodedImage(_ image: UIImage) -> UIImage? {

guard let newImage = image.cgImage else { return nil }


 // To optimize this, you cansomecachecontrol.

let colorspace = CGColorSpaceCreateDeviceRGB()

let context = CGContext(data: nil,

width: newImage.width,

height: newImage.height,

bitsPerComponent: 8,

bytesPerRow: newImage.width * 4,

space: colorspace,

bitmapInfo: CGImageAlphaInfo.noneSkipFir

context?.draw(newImage, in: CGRect(x: 0, y: 0, width: newImage.w

let drawnImage = context?.makeImage()

if let drawnImage = drawnImage {

return UIImage(cgImage: drawnImage)

}

return nil

}

}

可以添加进⼀步的存控制以提效率:


import UIKit

class AsyncImageView: UIView {

private var _image:UIImage?

var image: UIImage? {

get {

return _image

}

set {

_image = newValue

layer.contents = nil

guard let image = newValue else { return }

DispatchQueue.global(qos: .userInitiated).async {

DispatchQueue.main.sync { }

let decodedImage = UIImage.decodedImage(image)

DispatchQueue.main.async {

self.layer.contents = decodedImage?.cgImage

}

}

}

}

可以使“AsyncImageView”,在后台线不是主线程中解码图像。

为什么使用DispatchQueue.main.sync{}?

debug的前期我们尝试不使sync但是程序发⽣了崩溃⾏为了找出原因,使友盟+U-APM检测进⾏测试

4.jpg

可以从图中看出,码导致了OOM警,是由于存警告是在主线程上理的,   正在后台像,所以如果我使太多存, 就意外⾏为并带来极⼤⻛险(例发⽣的崩

4.离屏渲染

们处UI元素的特定可能遇到些离渲染问题需要在呈现它们前准渲染些元素。意味着量使CPUGPU

如何发现这种问题?

使具:  Debug->ViewDebugging->Rendering->ColorOscreen-RenderedYellow和前点的例相似, 使具, 我可以发现⻩⾊红⾊突出示的元素。

以下代码内容:

imageView.layer.cornerRadius = avatarImageHeight / 2.0

使  UIBezierPath代替,可以简单地解特定的离渲染问题

extension UIImage {

class func circularImage(from image:UIImage,size:CGSize)

let scale = UIScreen.main.scale

let circleRect = CGRect(x: 0, y: 0, width: size.width *

 

UIGraphicsBeginImageContextWithOptions(circleRect.size,

 

-> UIImage? {

 

scale, height:

 

false, scale)

let circlePath = UIBezierPath(roundedRect:circleRect,cornerRadius:c

circlePath.addClip()

 

image.draw(in: circleRect)

 

if let roundImage =UIGraphicsGetImageFromCurrentImageContext(){

return roundImage

}

 

return nil

}

}


简而言之,以下是通过调试得出的几点经验:

1.避免CornerRadius属性:

2.避免使ShouldRasterize

3.使  .rounded()更容易算。

4.Shadows会导致离渲染。

其他经验:

可以尝试⼀下以下的化建

1.boudingRectWithSize但是debug程可能常繁重。⾮⾮常需要,请尽量避免使⽤它们

2.检查结构布局, 尤其是使⽤⾃动布局且必须⽀旧设备时

3. 尝试将⼯作放后台列, 但注意存警告。



作者:郑文韬

相关文章
|
19天前
|
Linux 测试技术
Linux基础项目开发1:量产工具——UI系统(五)
Linux基础项目开发1:量产工具——UI系统(五)
19 0
Linux基础项目开发1:量产工具——UI系统(五)
|
3月前
|
监控 数据可视化 安全
Linux——怎样使用SSH服务实现远程UI界面本地显示
需求场景 最近几天需要实现软件的远程监控,但是实际场景又不能使用向日葵、VNC、AnyDesk、以及其他的监视软件,并且软件的整体设计也没有这块的数据上行设计。
108 0
|
4月前
|
Web App开发 数据安全/隐私保护 iOS开发
app优化ios,iOS app上架流程问题集锦,ASO新手小白必看(上)
app优化ios,iOS app上架流程问题集锦,ASO新手小白必看(上)
|
1天前
|
搜索推荐 安全 Android开发
探索安卓与iOS系统的差异与共通之道
【2月更文挑战第4天】安卓与iOS作为当前主流的移动操作系统,各自拥有独特的特性和功能。本文将深入探讨安卓和iOS系统的差异,并提出一些共通之道,帮助读者更好地了解和应用这两个系统。
|
1天前
|
人工智能 vr&ar Android开发
探索安卓与iOS系统的技术进展
【2月更文挑战第4天】本文将探讨安卓与iOS两大操作系统在最新技术进展方面的差异与相似之处。我们将分析它们在人工智能、增强现实、隐私保护等方面的创新和发展,并展望未来可能出现的趋势。通过对比这两个操作系统的技术特点,读者将能够更好地了解并选择适合自己需求的智能设备。
|
5天前
|
iOS开发
ipa文件安装到ios系统
ipa文件安装到ios系统
8 0
|
25天前
|
存储 传感器 监控
工业相机如何实现实时和本地Raw格式图像和Bitmap格式图像的保存和相互转换(C#代码,UI界面版)
工业相机如何实现实时和本地Raw格式图像和Bitmap格式图像的保存和相互转换(C#代码,UI界面版)
13 0
|
1月前
|
Web App开发 前端开发 JavaScript
ios 系统滑动问题
ios 系统滑动问题
|
1月前
|
存储 前端开发 开发工具
本地 SAP UI5 应用部署到远端 ABAP 系统,幕后英雄 ABAP_REPOSITORY_SRV
本地 SAP UI5 应用部署到远端 ABAP 系统,幕后英雄 ABAP_REPOSITORY_SRV
13 0
|
2月前
|
编解码 前端开发 人机交互
【Unity 3D】UI系统中UGUI各个组件的详细讲解(附源码 超详细)
【Unity 3D】UI系统中UGUI各个组件的详细讲解(附源码 超详细)
46 0

热门文章

最新文章

相关产品

  • 云迁移中心