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

UICollectionView滚动卡顿问题:加载本地40张图片时滚动掉帧如何优化?

UICollectionView本地图片滚动卡顿优化方案

核心问题定位

  • 重复生成图片数组:你在numberOfItemsInSection和cellForItemAt中每次都创建新的ThemeManager实例,调用themeBackgroundImages()时都会重新生成包含40个UIImage的数组,大量重复开销完全没必要
  • 图片未做降采样:本地原图尺寸远大于cell中imageView的显示尺寸,系统渲染时需要实时对大图做解码、缩放操作,CPU/GPU占用极高,这是滚动卡顿的核心原因
  • 重复设置视图属性:每次cell复用都重新设置cornerRadius,同时未做离屏渲染优化,进一步增加渲染开销
  • 之前的异步队列方案无效的原因:卡顿核心不是图片IO耗时,而是图片渲染阶段的主线程开销,就算把加载逻辑放到异步队列,最后渲染依然要在主线程处理,反而会增加线程调度开销。

具体优化代码

1. 页面层缓存降采样后的图片

在ThemesVC中提前加载并处理所有图片,避免滚动时重复计算:

class ThemesVC: UIViewController {
    // 缓存降采样后的适配尺寸图片,仅初始化一次
    private var allThemeImages: [UIImage] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 提前计算目标图片尺寸,和cell大小保持一致
        let targetImageSize = CGSize(width: view.frame.width / 2.34, height: view.frame.height * 0.3)
        let screenScale = UIScreen.main.scale
        // 一次性加载并降采样所有图片
        let rawImages = ThemeManager().themeBackgroundImages()
        allThemeImages = rawImages.map { image in
            downsample(image: image, targetSize: targetImageSize, scale: screenScale)
        }
        // 其他初始化逻辑...
    }
    
    // 图片降采样方法,将大图缩放到刚好适配控件的尺寸,大幅降低渲染开销
    private func downsample(image: UIImage, targetSize: CGSize, scale: CGFloat) -> UIImage {
        let format = UIGraphicsImageRendererFormat.default()
        format.scale = scale
        return UIGraphicsImageRenderer(size: targetSize, format: format).image { _ in
            image.draw(in: CGRect(origin: .zero, size: targetSize))
        }
    }
}

// 优化后的数据源方法,直接使用缓存好的图片
extension ThemesVC: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout{
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return allThemeImages.count
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ThemesCollectionViewCell", for: indexPath) as! ThemesCollectionViewCell
        cell.themeCellImageView.image = allThemeImages[indexPath.row]
        return cell
    }
    
    // 其他布局方法保持不变即可...
}

2. 优化Cell性能,避免重复配置

将固定属性放到Cell初始化方法中只设置一次,同时开启栅格化缓存渲染结果:

import UIKit

class ThemesCollectionViewCell: UICollectionViewCell {
    @IBOutlet weak var themeCellImageView: UIImageView!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // 圆角等固定属性仅设置一次
        contentView.layer.cornerRadius = 20
        contentView.layer.masksToBounds = true
        // 开启栅格化,缓存cell渲染结果,滚动时无需重复渲染
        layer.shouldRasterize = true
        layer.rasterizationScale = UIScreen.main.scale
    }
}

3. 优化ThemeManager,缓存原始图片数组

避免每次调用方法都重新生成40张图片的数组:

func themeBackgroundImages() -> [UIImage]{
    // 静态缓存,全局仅生成一次图片数组
    struct StaticCache {
        static var cachedImages: [UIImage]?
    }
    if let cached = StaticCache.cachedImages {
        return cached
    }
    var images = [UIImage]()
    images.reserveCapacity(40)
    // 原有图片赋值逻辑保持不变
    images = [UIImage(named: "original-theme")!, UIImage(named: "blue-theme")!, UIImage(named: "purple-theme")!, UIImage(named: "pink-theme")!, UIImage(named: "red-theme")!, FlyTheme().backgroundImage, DreamTheme().backgroundImage, LoverTheme().backgroundImage, NatureTheme().backgroundImage, InspireTheme().backgroundImage, TimeMachineTheme().backgroundImage, NowhereTheme().backgroundImage, DarkThoughtsTheme().backgroundImage, FutureCityTheme().backgroundImage, LostTheme().backgroundImage, FireTheme().backgroundImage, PatternTheme().backgroundImage, HorizonTheme().backgroundImage, SpelTheme().backgroundImage, WonderlandTheme().backgroundImage, BreatheTheme().backgroundImage, PassionTheme().backgroundImage, TimelapseTheme().backgroundImage, FugitiveTheme().backgroundImage, InfiniteWayTheme().backgroundImage, LonelyTheme().backgroundImage, RelationshipTheme().backgroundImage, MoonlightTheme().backgroundImage, DreamlandTheme().backgroundImage, WayOutTheme().backgroundImage, MistyTheme().backgroundImage, UnpredictableTheme().backgroundImage, VolcanoTheme().backgroundImage, DiscoverTheme().backgroundImage, PurpleInspirationTheme().backgroundImage, ForestTheme().backgroundImage, RainbowTheme().backgroundImage, FlowersTheme().backgroundImage, TheMoonTheme().backgroundImage, LuridTheme().backgroundImage]
    StaticCache.cachedImages = images
    return images
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:54:04