You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UITableView滚动卡顿迟缓,如何优化Cell内图片缩放处理逻辑?

性能问题根源

你现有代码的卡顿来自三个严重的错误逻辑:

  • 用NSData(contentsOf: mediaUrl)在主线程同步发起网络请求,这个API会直接阻塞当前线程直到网络请求返回,滚动时频繁调用必然卡死
  • 已经调用SDWebImage的sd_setImage加载了一次媒体图片,后面又重复发起了一次同URL的网络请求,双倍浪费网络和CPU资源
  • 图片缩放计算完全放在主线程执行,大量并发计算直接抢占UI渲染资源

优化后的代码实现

直接复用SDWebImage的加载能力,不需要自己处理网络请求,两种实现方案可选:

方案1:用SDWebImage自带的缩放工具(推荐)

自带缩放能力会自动缓存处理后的图片,下次加载同尺寸的同URL图片不需要重复计算,性能最优:

func set(post:Posts) {
    self.post = post
    
    // 加载头像逻辑不变
    let url = post.url
    profileImageView.sd_setImage(with: url, completed: nil)
    
    // 加载并自动缩放媒体图片
    let mediaUrl = post.urlM
    let targetWidth = MediaPhoto.frame.width
    // 按宽度等比缩放,高度自适应
    let scaleTransformer = SDImageResizingTransformer(size: CGSize(width: targetWidth, height: CGFloat.greatestFiniteMagnitude), scaleMode: .aspectFit)
    MediaPhoto.sd_setImage(with: mediaUrl, placeholderImage: nil, context: [.imageTransformer: scaleTransformer])
}

方案2:自定义缩放逻辑

如果需要定制特殊缩放规则,把缩放逻辑扔到异步线程执行,不阻塞主线程:

func set(post:Posts) {
    self.post = post
    
    let url = post.url
    profileImageView.sd_setImage(with: url, completed: nil)
    
    let mediaUrl = post.urlM
    let targetWidth = MediaPhoto.frame.width
    MediaPhoto.sd_setImage(with: mediaUrl) { [weak self] image, _, _, _ in
        guard let self = self, let image = image else { return }
        // 异步执行缩放逻辑,不抢占UI线程资源
        DispatchQueue.global(qos: .userInitiated).async {
            let scale = targetWidth / image.size.width
            let newHeight = image.size.height * scale
            let renderSize = CGSize(width: targetWidth, height: newHeight)
            // 用更高效的UIGraphicsImageRenderer替代旧的上下文API
            let renderer = UIGraphicsImageRenderer(size: renderSize)
            let scaledImage = renderer.image { _ in
                image.draw(in: CGRect(origin: .zero, size: renderSize))
            }
            // 回到主线程赋值图片
            DispatchQueue.main.async {
                self.MediaPhoto.image = scaledImage
            }
        }
    }
}

额外优化建议

  • 提前计算好每个cell里媒体图片的高度,存入UITableView的高度缓存,不要等图片加载完再算高度,避免滚动时反复重算布局
  • 如果后台接口会返回图片的原始宽高比,可以直接用返回的比例提前算好控件高度,完全不需要等图片下载完成再做计算,滚动流畅度会更高

内容的提问来源于stack exchange,提问作者CodingForFun333

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 15:45:03