Mobile Development 15 min read

iOS Information Feed Performance Optimization: Reducing Stuttering in Mobile Apps

iOS feed performance optimization reduced stuttering by moving layout and rendering off the main thread, using async text/image rendering, pre‑layout calculations, view hierarchy simplification, lightweight CALayers, and off‑screen rendering avoidance, boosting FPS from 35‑45 to 55‑60 on low‑end devices.

NetEase Media Technology Team
NetEase Media Technology Team
NetEase Media Technology Team
iOS Information Feed Performance Optimization: Reducing Stuttering in Mobile Apps

Background

In the Open Course APP, the information feed is a core interface for users to access and browse course-related content. However, on low-performance devices, users experience stuttering during feed browsing—unsmooth page scrolling and slow loading, with frame rates typically between 35-45 FPS, far below the ideal 60 FPS. This significantly impacts user experience, prompting the team to optimize the feed's performance.

Theoretical Foundation

Image Rendering Principle

Computer screen display typically involves collaborative work between CPU and GPU. The rendering process: 1) CPU processes graphics through frame calculation and image decoding, then submits texture data to GPU via bus; 2) GPU performs texture blending, vertex transformation, and pixel filling to generate frame data submitted to frame buffer; 3) iOS uses double buffering where GPU pre-renders a frame into a buffer for video controller reading; 4) Video controller reads frame buffer data via VSync signal and displays on screen.

Causes of Stuttering

When VSync signal arrives, system graphics services notify the app, and the main thread begins CPU calculations (view creation, layout computation, image decoding, text rendering). CPU submits content to GPU for transformation, synthesis, and rendering. GPU submits results to frame buffer, waiting for next VSync to display. Due to vertical synchronization, if CPU or GPU fails to complete within one VSync period, that frame is discarded, causing the display to retain previous content—resulting in interface stuttering.

Optimization Solution Selection

Two mainstream solutions were evaluated: Graver and Texture (AsyncDisplayKit).

Graver - Meituan's open-source iOS async rendering framework (later discontinued). Approach: "drawing controls" instead of "assembling controls." Each rendering element expressed via WMMutableAttributedItem, producing a Bitmap as final output.

Pros: Improves idle CPU utilization, reduces peak CPU usage; full async pipeline (text calculation, style layout, image decoding, rendering); low marginal cost; fast rendering with low memory.

Cons: Flattens view layers, losing tree structure flexibility; requires bitmap-based event handling system; maintenance challenges after being discontinued.

Texture (AsyncDisplayKit) - Facebook's high-performance display library (2014). Approach: Async display using Node concept to overcome UIView/CALayer main-thread limitations.

Pros: Async display off main thread with caching; open-source for easier debugging.

Cons: Steep learning curve; high migration cost; requires Flexbox layout.

Due to maintenance concerns and migration complexity, the team decided to adopt async rendering concepts from both solutions for their own optimization.

Optimization Practice

Pre-layout

View layout computation is the most CPU-intensive operation. Combined with MVVM architecture, a Layout layer was inserted to store layout information. The flow: 1) Main thread builds request parameters and initiates network request; 2) Network thread fetches data; 3) Parallel queue performs pre-layout including layout and rendering info; 4) Main thread triggers reload with layout models.

Async Rendering

Text Async Rendering

All text controls use CoreText for layout and Bitmap rendering. Common controls like UILabel perform layout/drawing on main thread, causing high CPU pressure. The team adopted YYLabel's async rendering mechanism:

- (void)display { dispatch_async(YYAsyncLayerGetDisplayQueue(), ^{ UIGraphicsBeginImageContextWithOptions(size, opaque, scale); CGContextRef context = UIGraphicsGetCurrentContext(); ...... UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); ...... dispatch_async(dispatch_get_main_queue(), ^{ self.contents = (__bridge id)(image.CGImage); if (task.didDisplay) task.didDisplay(self, YES); }); }); }

Image Async Rendering

Image decoding is complex and CPU-intensive. Images aren't decoded until set to UIImageView or CALayer.contents, requiring main thread execution. Async decoding implementation:

- (void)display { ...... dispatch_async(backgroudQueu, ^{ CGContextRef context = CGBitmapContextCreate(...); //draw in context .... CGImageRef img = CGBitmapContextCreateImage(context); CFRelease(context); dispatch_async(mainQueue, ^{ layer.contents = img; }); }); }

View Hierarchy Optimization

All bitmaps must be submitted from memory to GPU as textures. Complex overlapping views consume significant GPU resources. Optimization strategies: remove redundant views; merge icons and text using NSAttributedString; pre-calculate and cache TextLayout; use lightweight CALayer instead of UIView.

Off-screen Rendering Optimization

Off-screen rendering creates additional buffers and requires multiple context switches, incurring high costs. CALayer properties like border, corner radius, shadow, and mask typically trigger off-screen rendering. Optimizations: use CAShapeLayer+UIBezierPath for corners; use shadowPath for shadows; pre-process network images with rounded corners.

Results

After optimization, frame rate improved from 35-45 FPS to 55-60 FPS on low-performance devices like iPhone7 and iPad Air.

Experience Summary

Pre-layout: Calculate layout in parallel queue before display

Async rendering: Process text/images in parallel queue before submitting to layer.contents

View hierarchy reduction: Reduce/merge views

Use lightweight views: Prefer CALayer over UIView

Avoid off-screen rendering: Optimize cornerRadius, shadow, and corner processing

Mobile DevelopmentiOS performance optimizationAsync Renderingoff-screen renderingstuttering optimizationview hierarchyYYLabel
NetEase Media Technology Team
Written by

NetEase Media Technology Team

NetEase Media Technology Team

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.