如何优化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. 尝试将⼯作放后台列, 但注意存警告。



作者:郑文韬

相关文章
|
2月前
|
计算机视觉 Python
基于Dlib的人脸识别客户端(UI界面)
基于Dlib的人脸识别客户端(UI界面)
73 2
|
2天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
2天前
|
人工智能 搜索推荐 算法
婚恋交友系统UI/UX设计优化 婚恋交友系统用户界面友好性提升 婚恋交友系统用户行为分析与优化 婚恋交友系统用户反馈收集与处理
针对婚恋交友系统的UI/UX设计优化,本文提出多项策略:简化用户界面、提升交互体验、个性化推荐算法;增强用户界面友好性,包括适应性、无障碍及情感化设计;通过数据收集与分析优化用户行为路径;建立多渠道反馈机制,分类处理并及时告知结果。这些措施旨在提高用户体验和满意度,促进平台健康发展。[点击查看完整演示和免费源码](https://gitee.com/duoke-official-open-source/hunlianjiaoyou)
15 4
|
22天前
|
前端开发 数据安全/隐私保护
全新紫色新UI数码盲盒系统源码/全开源无加密/附教程
全新紫色新UI数码盲盒系统源码/全开源无加密/附教程 前端uniapp+H5 后端FastAdmin框架 可打包成APP多端运行 亲测可用
45 13
|
1月前
|
安全 Swift iOS开发
Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法
本文深入探讨了 Swift 与 UIKit 在 iOS 应用界面开发中的关键技术和实践方法。Swift 以其简洁、高效和类型安全的特点,结合 UIKit 丰富的组件和功能,为开发者提供了强大的工具。文章从 Swift 的语法优势、类型安全、编程模型以及与 UIKit 的集成,到 UIKit 的主要组件和功能,再到构建界面的实践技巧和实际案例分析,全面介绍了如何利用这些技术创建高质量的用户界面。
33 2
|
1月前
|
开发框架 JavaScript 前端开发
HarmonyOS UI开发:掌握ArkUI(包括Java UI和JS UI)进行界面开发
【10月更文挑战第22天】随着科技发展,操作系统呈现多元化趋势。华为推出的HarmonyOS以其全场景、多设备特性备受关注。本文介绍HarmonyOS的UI开发框架ArkUI,探讨Java UI和JS UI两种开发方式。Java UI适合复杂界面开发,性能较高;JS UI适合快速开发简单界面,跨平台性好。掌握ArkUI可高效打造符合用户需求的界面。
114 8
|
2月前
|
机器学习/深度学习 数据可视化 计算机视觉
基于opencv的车牌识别系统(UI界面采用tkinter设计)
基于opencv的车牌识别系统(UI界面采用tkinter设计)
56 0
|
1月前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
2月前
|
开发框架 JavaScript 前端开发
鸿蒙NEXT开发声明式UI是咋回事?
【10月更文挑战第15天】鸿蒙NEXT的声明式UI基于ArkTS,提供高效简洁的开发体验。ArkTS扩展了TypeScript,支持声明式UI描述、自定义组件及状态管理。ArkUI框架则提供了丰富的组件、布局计算和动画能力。开发者仅需关注数据变化,UI将自动更新,简化了开发流程。此外,其前后端分层设计与编译时优化确保了高性能运行,利于生态发展。通过组件创建、状态管理和渲染控制等方式,开发者能快速构建高质量的鸿蒙应用。
140 3
|
21天前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。