Mobile Development 12 min read

QDAS-APM: 360’s iOS Mobile Performance Monitoring Solution

This article introduces 360’s iOS mobile performance monitoring solution, QDAS‑APM, detailing its background, monitored metrics such as page rendering time, main‑thread stalls, network errors, FPS, CPU, memory, crash and startup duration, and explains implementation techniques using KVO, runtime class traversal, and code snippets.

360 Tech Engineering
360 Tech Engineering
360 Tech Engineering
QDAS-APM: 360’s iOS Mobile Performance Monitoring Solution

This article introduces 360’s iOS performance monitoring solution, QDAS‑APM, which aims to detect and locate performance problems such as crashes, network errors, UI lag, main‑thread blockage, high CPU/memory usage, and excessive power consumption.

Background : Performance issues greatly affect user experience. 360 has summarized five key performance concerns—resource control, version quality, online issue tracing, development‑stage degradation prevention, and realistic monitoring—and built a monitoring system based on these insights.

Monitored Features :

Page rendering duration

Main‑thread stalls

Network errors

FPS

Large file storage

CPU usage

Memory usage

Crash reports

App startup time

1. Page Rendering Duration

Page rendering time is measured from view controller initialization to the moment the user sees the rendered UI. Important sub‑metrics include lifecycle method execution time, page class name, launch type, execution cost, and plugin name. Directly hooking UIViewController methods is insufficient because most apps subclass UIViewController.

Two feasible approaches are proposed:

Using KVO: the system creates a dynamic subclass for any observed object, allowing interception of property changes.

Runtime traversal: enumerate all UIViewController subclasses and replace their implementations.

The preferred method is KVO due to better compatibility and performance. Implementation steps:

Create a UIViewController category and add KVO for the target instance.

In the KVO‑generated subclass, add swizzled methods to capture the original SEL and IMP.

Remove KVO observers in dealloc to avoid crashes.

Example code for measuring viewDidLoad execution time:

static void qh_viewDidLoad(UIViewController *kvo_self, SEL _sel)
{
    Class kvo_cls = object_getClass(kvo_self);
    Class origin_cls = class_getSuperclass(kvo_cls);

    // Get original implementation
    IMP origin_imp = method_getImplementation(class_getInstanceMethod(origin_cls, _sel));
    void(*func)(UIViewController *, SEL) = (void(*)(UIViewController *, SEL))origin_imp;

    CFAbsoluteTime startTime = CACurrentMediaTime();
    func(kvo_self, _sel);
    CFAbsoluteTime endTime = CACurrentMediaTime();
    NSTimeInterval duration = (endTime - startTime) * 1000;

    NSLog(@"Class %@ cost %g in viewDidLoad", [kvo_self class], duration);
}

Simply summing the durations of init , loadView , viewDidLoad , viewWillAppear , and viewDidAppear does not accurately represent rendering time, especially with asynchronous rendering. Instead, the layout completion callback viewDidLayoutSubviews can be used as an indirect indicator of rendering completion.

2. Main‑Thread Stall Analysis

Stalls affect UI smoothness and are measured by FPS (Frames Per Second). A healthy app maintains 50–60 FPS. Stalls occur when CPU/GPU processing exceeds the 16.67 ms window before the next V‑Sync signal, causing the display to show the previous frame. The article explains the iPhone’s double‑buffering, V‑Sync mechanism, and how missed V‑Sync leads to visible lag.

3. Network Monitoring

Two approaches are discussed:

NSURLProtocol : convenient for HTTP/HTTPS but limited to supported schemes and cannot handle custom protocols or certificate verification.

Hooking (NSProxy) : uses an abstract NSProxy subclass to forward messages, allowing interception of NSURLConnection , NSURLSession , and CFNetwork methods.

Excerpt from Apple’s documentation on NSProxy :

NSProxy is an abstract superclass defining an API for objects that act as stand‑ins for other objects or for objects that don’t exist yet. Typically, a message to a proxy is forwarded to the real object or causes the proxy to load (or transform itself into) the real object.

By hooking key methods in the three network classes, QDAS‑APM collects request/response metrics, formats them, and reports them to the backend for aggregation and reporting.

4. Integration and Usage

QDAS‑APM is a passive‑collection SDK that requires no additional system libraries. Integration consists of three simple steps:

Import the SDK library.

Include the SDK header files.

Initialize the SDK in application:didFinishLaunchingWithOptions: with the provided app key.

References :

Meituan Hertz: https://tech.meituan.com/2016/12/19/hertz.htmlg

iOS Performance Monitoring: http://www.cocoachina.com/articles/19680

mobile developmentiOSRuntimePerformance MonitoringNetwork MonitoringKVOQDAS-APM
360 Tech Engineering
Written by

360 Tech Engineering

Official tech channel of 360, building the most professional technology aggregation platform for the brand.

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.