@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/LICENSE +0 -10
- package/docs/facts.json +1 -1
- package/manifest.json +266 -267
- package/package.json +2 -2
- package/pipeline/scripts/_notices.mjs +1 -1
- package/pipeline/skills/.skill-manifest.json +68 -68
- package/pipeline/skills/shared/README.md +70 -70
- package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
- package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
- package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
- package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
- package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
- package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
- package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
- package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
- package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
- package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
- package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
- package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
- package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
- package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
- package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
- package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
- package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
- package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
- package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
- package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
- package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
- package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
- package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
- package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
- package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
- package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
- package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
- package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
- package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
- package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
- package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
- package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
- package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
- package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
- package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
- package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
- package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
- package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
- package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
- package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
- package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
- package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
- package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
- package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
- package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
- package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
- package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
- package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
- package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
- package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
- package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
- package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
- package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
- package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
- package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
- package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
- package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
- package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
- package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
- package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
- package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
- package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
- package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
- package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
- package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
- package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
- package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
- package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
- package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
- package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
- package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
- package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
- package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
- package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
- package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
- package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
- package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
- package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
- package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
- package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
- package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
- package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
- package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
- package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
- package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
- package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
- package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
- package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
- package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
- package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
- package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
- package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
- package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
- package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
- package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
- package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
- package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
- package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
- package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
- package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
- package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
- package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
- package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
- package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
- package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
- package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
- package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
- package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
- package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
- package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
- package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
- package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
- package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
- package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
- package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
- package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
- package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
- package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
- package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
- package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
- package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
- package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
- package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
- package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
- package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
- package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
- package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
- package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
- package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
- package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
- package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
- package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
- package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
- package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
- package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
- package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
- package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
- package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
- package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
- package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
- package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
- package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
- package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
- package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
- package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
- package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
- package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
- package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
- package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
- package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
- package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
- package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
- package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
- package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
- package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
- package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
- package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
- package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
- package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
- package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
- package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
- package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
- package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
- package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
- package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
- package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
- package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
- package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
- package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
- package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
- package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
- package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
- package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
- package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
- package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
- package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
- package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
- package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
- package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
- package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
- package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
- package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
- package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
- package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
- package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
- package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
- package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
- package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
- package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
- package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
- package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
- package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
- package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
- package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
- package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
- package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
- package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
- package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
- package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
- package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
- package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
- package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
- package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
- package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
- package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
- package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
- package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
- package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
- package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
- package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
- package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
- package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
- package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
- package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
- package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
- package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
|
@@ -1,233 +1,146 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Hangs and the Main Run Loop
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Based on Apple's article "Understanding hangs in your app" and the WWDC23
|
|
4
|
+
session "Analyze hangs with Instruments".
|
|
5
5
|
|
|
6
|
-
##
|
|
7
|
-
- What a hang is
|
|
8
|
-
- Main-thread work stages
|
|
9
|
-
- Triage workflow
|
|
10
|
-
- Common root causes
|
|
11
|
-
- Fix patterns
|
|
12
|
-
- Verification checklist
|
|
13
|
-
- Related SwiftUI implications
|
|
6
|
+
## What Counts as a Hang
|
|
14
7
|
|
|
15
|
-
|
|
8
|
+
A hang is a delay the user notices in a discrete interaction, such as a tap
|
|
9
|
+
that does not respond. Almost always the main thread is busy for long enough
|
|
10
|
+
to be felt.
|
|
16
11
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
| Main thread busy for | Feels |
|
|
13
|
+
|----------------------|-------|
|
|
14
|
+
| Under about 100 ms | Immediate |
|
|
15
|
+
| About 100 to 250 ms | Sticky |
|
|
16
|
+
| Over about 250 ms | Probably a hang |
|
|
17
|
+
| Several seconds | An obvious bug |
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
The exact number matters less than whether the user felt the interaction was
|
|
20
|
+
blocked. Suspect the main thread first.
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
- Around 100-250 ms starts to feel sticky.
|
|
25
|
-
- Above ~250 ms is a likely hang candidate.
|
|
26
|
-
- Multi-second stalls are usually obvious product bugs, not subtle perf issues.
|
|
22
|
+
## How the Main Thread Spends a Frame
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
interaction, and the main thread is usually where the problem lives.
|
|
24
|
+
Three stages happen on the main thread:
|
|
30
25
|
|
|
31
|
-
|
|
26
|
+
1. The event is delivered to the view or responder that handles it.
|
|
27
|
+
2. App code runs, changes state and schedules UI work.
|
|
28
|
+
3. Core Animation commits the layer tree to the render server.
|
|
32
29
|
|
|
33
|
-
|
|
30
|
+
If any stage runs long, the run loop cannot go back to sleep and pick up the
|
|
31
|
+
next event. A healthy app is idle most of the time; a busy one lets taps,
|
|
32
|
+
gestures, timers and redraws pile up.
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
Work isolated to the main actor still runs on the main thread. `@MainActor`
|
|
35
|
+
makes code correct; it does not make it faster. Assume the main thread is
|
|
36
|
+
overloaded until a profile shows otherwise.
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
sleep and cannot service the next event in time.
|
|
38
|
+
## Triage
|
|
41
39
|
|
|
42
|
-
|
|
40
|
+
1. **Pick one concrete interaction.** "The Save button ignores taps for half a
|
|
41
|
+
second", "the push animation pauses before starting", "dismissing the sheet
|
|
42
|
+
freezes scrolling". Not "the app feels slow".
|
|
43
|
+
2. **Record it** with the Hangs instrument, adding Time Profiler when needed.
|
|
44
|
+
Release build, real device, a path you can repeat, several repetitions.
|
|
45
|
+
3. **Read the busy windows on the main thread** before looking at total CPU.
|
|
46
|
+
Is the time spent in app code, in synchronous I/O, in recomputing layout or
|
|
47
|
+
state, or waiting on a lock or an actor hop?
|
|
48
|
+
4. **Remove or relocate the work.** Hiding it behind a spinner is a weak fix.
|
|
43
49
|
|
|
44
|
-
|
|
50
|
+
## Common Causes
|
|
45
51
|
|
|
46
|
-
|
|
47
|
-
- A busy run loop means new taps, gestures, timers, and redraw work queue up.
|
|
48
|
-
- Main-actor tasks still execute on the main thread. Moving code to `@MainActor`
|
|
49
|
-
is a correctness tool, not a performance optimization.
|
|
52
|
+
### Synchronous I/O
|
|
50
53
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
## Triage workflow
|
|
55
|
-
|
|
56
|
-
### 1. Reproduce a single concrete interaction
|
|
57
|
-
|
|
58
|
-
Start with one specific symptom:
|
|
59
|
-
|
|
60
|
-
- tapping a button does nothing for half a second
|
|
61
|
-
- pushing a detail screen pauses before animating
|
|
62
|
-
- dismissing a sheet freezes scrolling underneath
|
|
63
|
-
|
|
64
|
-
Avoid broad goals like "the app feels slow" until you isolate a single path.
|
|
65
|
-
|
|
66
|
-
### 2. Record with Instruments
|
|
67
|
-
|
|
68
|
-
Use the Hangs instrument, and pair it with Time Profiler when needed.
|
|
69
|
-
|
|
70
|
-
Good capture setup:
|
|
71
|
-
|
|
72
|
-
- Release build
|
|
73
|
-
- real device
|
|
74
|
-
- repeatable interaction path
|
|
75
|
-
- enough repetitions to confirm the same stall pattern
|
|
76
|
-
|
|
77
|
-
### 3. Inspect busy windows on the main thread
|
|
78
|
-
|
|
79
|
-
Look for long busy periods instead of staring at total CPU first.
|
|
80
|
-
|
|
81
|
-
Questions to answer:
|
|
82
|
-
|
|
83
|
-
- Is the main thread blocked in app code?
|
|
84
|
-
- Is it blocked in synchronous I/O?
|
|
85
|
-
- Is it repeatedly recalculating layout or view state?
|
|
86
|
-
- Is there a lock or actor hop forcing serialization?
|
|
87
|
-
|
|
88
|
-
### 4. Reduce the work, not just the symptom
|
|
89
|
-
|
|
90
|
-
A useful fix removes or re-locates expensive work. A weak fix only hides the
|
|
91
|
-
stall behind a spinner while the main thread still does too much.
|
|
92
|
-
|
|
93
|
-
## Common root causes
|
|
94
|
-
|
|
95
|
-
### Synchronous I/O on the main thread
|
|
96
|
-
|
|
97
|
-
Typical offenders:
|
|
98
|
-
|
|
99
|
-
- file reads
|
|
100
|
-
- JSON decoding for large payloads
|
|
101
|
-
- image decoding
|
|
102
|
-
- database fetches
|
|
103
|
-
- Keychain work done inline with UI gestures
|
|
54
|
+
Reading files, decoding large JSON, decoding images, database fetches and
|
|
55
|
+
Keychain calls made inline in a gesture handler.
|
|
104
56
|
|
|
105
57
|
```swift
|
|
106
|
-
//
|
|
107
|
-
Button("
|
|
108
|
-
let data = try? Data(contentsOf:
|
|
109
|
-
|
|
58
|
+
// Blocks the main thread while the file is read and parsed.
|
|
59
|
+
Button("Import") {
|
|
60
|
+
let data = try? Data(contentsOf: archiveURL)
|
|
61
|
+
entries = parseArchive(data)
|
|
110
62
|
}
|
|
111
63
|
|
|
112
|
-
//
|
|
113
|
-
Button("
|
|
64
|
+
// Starts the work, lets it run elsewhere, then publishes the result.
|
|
65
|
+
Button("Import") {
|
|
114
66
|
Task {
|
|
115
|
-
let
|
|
116
|
-
|
|
117
|
-
await MainActor.run { model = parsed }
|
|
67
|
+
let parsed = await ArchiveReader.load(from: archiveURL)
|
|
68
|
+
await MainActor.run { entries = parsed }
|
|
118
69
|
}
|
|
119
70
|
}
|
|
120
71
|
```
|
|
121
72
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
A tap handler should kick off work, not do all the work inline.
|
|
73
|
+
Event handlers should kick work off, not perform it:
|
|
125
74
|
|
|
126
75
|
```swift
|
|
127
|
-
|
|
128
|
-
func didTapRefresh() {
|
|
129
|
-
items = expensiveRebuildOfEntireList()
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// DO
|
|
133
|
-
func didTapRefresh() {
|
|
76
|
+
func reloadTapped() {
|
|
134
77
|
Task {
|
|
135
|
-
let rebuilt = await
|
|
136
|
-
await MainActor.run {
|
|
78
|
+
let rebuilt = await index.rebuild()
|
|
79
|
+
await MainActor.run { results = rebuilt }
|
|
137
80
|
}
|
|
138
81
|
}
|
|
139
82
|
```
|
|
140
83
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
SwiftUI and UIKit/AppKit can both stall if the view tree triggers too much work
|
|
144
|
-
per interaction.
|
|
84
|
+
When the caller is already on the main actor, a plain assignment after the
|
|
85
|
+
`await` does the same as `MainActor.run`.
|
|
145
86
|
|
|
146
|
-
|
|
87
|
+
### Layout and rendering pressure
|
|
147
88
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
- layout invalidations triggered by frequent geometry changes
|
|
89
|
+
Signs: formatters created again and again, images resized in `body`, attributed
|
|
90
|
+
strings built while scrolling, and invalidations driven by frequent geometry
|
|
91
|
+
changes.
|
|
152
92
|
|
|
153
|
-
###
|
|
93
|
+
### Waiting instead of working
|
|
154
94
|
|
|
155
|
-
A hang
|
|
95
|
+
A hang does not have to be computation:
|
|
156
96
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
- a
|
|
160
|
-
- synchronous dispatch back to main
|
|
161
|
-
- a main-actor method waiting on another main-actor path
|
|
97
|
+
- the main thread waits for a lock a background job holds,
|
|
98
|
+
- code dispatches synchronously to the main queue,
|
|
99
|
+
- a main-actor method waits on another path that also needs the main actor.
|
|
162
100
|
|
|
163
101
|
### Priority inversion
|
|
164
102
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
## Fix patterns
|
|
169
|
-
|
|
170
|
-
### Keep main-thread work small and deterministic
|
|
171
|
-
|
|
172
|
-
Prefer this split:
|
|
173
|
-
|
|
174
|
-
- main thread: input, state wiring, view invalidation
|
|
175
|
-
- background work: parsing, formatting batches, image prep, persistence
|
|
176
|
-
- main thread again: commit the final result
|
|
177
|
-
|
|
178
|
-
### Precompute instead of recompute
|
|
179
|
-
|
|
180
|
-
```swift
|
|
181
|
-
// DON'T
|
|
182
|
-
Text(distanceFormatter.string(from: trip.distance))
|
|
183
|
-
|
|
184
|
-
// DO
|
|
185
|
-
Text(trip.formattedDistance)
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
If the value changes rarely, compute it at the model boundary.
|
|
189
|
-
|
|
190
|
-
### Stream results instead of blocking for all results
|
|
103
|
+
When the UI waits for lower-priority work that holds a shared resource, the app
|
|
104
|
+
feels hung even though the main thread's stack looks shallow.
|
|
191
105
|
|
|
192
|
-
|
|
193
|
-
finishes.
|
|
106
|
+
## Fix Patterns
|
|
194
107
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
108
|
+
- Divide the work: the main thread handles input, state wiring and
|
|
109
|
+
invalidation; background work does parsing, batch formatting, image
|
|
110
|
+
preparation and persistence; the main thread then commits the result.
|
|
111
|
+
- Precompute values that rarely change where data enters the model, for
|
|
112
|
+
example `trip.formattedDistance` rather than formatting inside `Text`.
|
|
113
|
+
- Deliver partial results as they arrive instead of waiting for everything.
|
|
114
|
+
- Cancel work that is no longer wanted:
|
|
199
115
|
|
|
200
116
|
```swift
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
117
|
+
List(matches) { MatchRow(match: $0) }
|
|
118
|
+
.task(id: searchText) {
|
|
119
|
+
matches = (try? await catalog.search(searchText)) ?? []
|
|
120
|
+
}
|
|
205
121
|
```
|
|
206
122
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
After a fix, confirm all of the following:
|
|
123
|
+
`.task(id:)` cancels the previous task and starts a new one when `searchText`
|
|
124
|
+
changes. Inside `search`, check `Task.isCancelled` or call
|
|
125
|
+
`try Task.checkCancellation()` so abandoned searches stop early.
|
|
212
126
|
|
|
213
|
-
|
|
214
|
-
- main-thread busy windows are shorter
|
|
215
|
-
- the fix works in Release on device
|
|
216
|
-
- repeated interaction does not regress frame pacing
|
|
217
|
-
- cancellation works when navigating away mid-task
|
|
127
|
+
## Verification
|
|
218
128
|
|
|
219
|
-
|
|
220
|
-
|
|
129
|
+
- The same interaction no longer produces a Hangs event.
|
|
130
|
+
- Main-thread busy windows are shorter.
|
|
131
|
+
- It holds up in Release on a device.
|
|
132
|
+
- Repeating the interaction does not degrade frame pacing.
|
|
133
|
+
- Navigating away cancels the work.
|
|
221
134
|
|
|
222
|
-
|
|
135
|
+
If the hang is gone but scrolling or animation got worse, the work only moved.
|
|
223
136
|
|
|
224
|
-
|
|
137
|
+
## What This Means for SwiftUI
|
|
225
138
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
- hidden work in formatting or filtering
|
|
139
|
+
SwiftUI hangs usually come from long `body` updates, broad observable
|
|
140
|
+
dependencies, identity churn in lists, or formatting and filtering hidden in
|
|
141
|
+
views.
|
|
230
142
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
first need
|
|
143
|
+
- The interaction is clearly tied to view updates or layout: start with the
|
|
144
|
+
SwiftUI Instrument.
|
|
145
|
+
- The whole app is unresponsive and you first need proof the main thread is
|
|
146
|
+
blocked: start with the Hangs instrument.
|
|
@@ -1,177 +1,99 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Long Updates and Frequent Updates
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
applying design patterns to reduce long or frequent updates.
|
|
3
|
+
Based on Apple's article "Understanding and improving SwiftUI performance".
|
|
5
4
|
|
|
6
|
-
##
|
|
7
|
-
- Core concepts
|
|
8
|
-
- Instruments workflow
|
|
9
|
-
- Reading SwiftUI timeline lanes
|
|
10
|
-
- Diagnosing long updates
|
|
11
|
-
- Diagnosing frequent updates
|
|
12
|
-
- Common remediation patterns
|
|
13
|
-
- Verification loop
|
|
14
|
-
- Practical guardrails
|
|
5
|
+
## Two Different Problems
|
|
15
6
|
|
|
16
|
-
|
|
7
|
+
| Kind | What happens | Usual sources |
|
|
8
|
+
|------|--------------|---------------|
|
|
9
|
+
| Long updates | One update takes too long | An expensive `body`, layout, or hosted platform views |
|
|
10
|
+
| Frequent updates | Many small updates add up | Dependency fan-out, noisy observable state, geometry or timer signals invalidating too much |
|
|
17
11
|
|
|
18
|
-
|
|
12
|
+
Both hurt, and they need different fixes. Treat them as separate bugs.
|
|
19
13
|
|
|
20
|
-
|
|
21
|
-
- **Frequent updates**: many small updates happen too often
|
|
14
|
+
## Instruments Workflow
|
|
22
15
|
|
|
23
|
-
|
|
16
|
+
1. Build Release and run on a real device.
|
|
17
|
+
2. Profile with the SwiftUI template.
|
|
18
|
+
3. Repeat one interaction several times.
|
|
19
|
+
4. Read the SwiftUI track first, then line it up with Time Profiler.
|
|
20
|
+
5. Change one thing, record again.
|
|
24
21
|
|
|
25
|
-
|
|
22
|
+
A trace from an interaction you cannot reproduce on demand is much harder to
|
|
23
|
+
interpret.
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
platform-view work.
|
|
25
|
+
## The Lanes
|
|
29
26
|
|
|
30
|
-
|
|
27
|
+
- **Update Groups**: batches of SwiftUI work.
|
|
28
|
+
- **Long View Body Updates**: slow `body` evaluations.
|
|
29
|
+
- **Long Platform View Updates**: slow hosted views. Check representables,
|
|
30
|
+
`List` rows that embed platform views, and media, map or web components.
|
|
31
|
+
- **Other Long Updates**: layout, geometry and update coordination.
|
|
32
|
+
- **Hitches**: missed frames. A hitch is a symptom; its cause may be elsewhere.
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
and timer signals invalidating more of the tree than intended.
|
|
34
|
+
## Diagnosing Long Updates
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
Begin with the red or orange update, not with total runtime. Set the
|
|
37
|
+
inspection range to it and look at the hottest frames in Time Profiler.
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
4. Inspect the SwiftUI track first, then correlate with Time Profiler.
|
|
43
|
-
5. Change one thing at a time and re-record.
|
|
44
|
-
|
|
45
|
-
If you cannot reproduce the exact interaction on demand, your trace will be much
|
|
46
|
-
harder to interpret.
|
|
47
|
-
|
|
48
|
-
## Reading SwiftUI timeline lanes
|
|
49
|
-
|
|
50
|
-
### Update Groups
|
|
51
|
-
|
|
52
|
-
Shows clusters of update activity over time. Good for spotting periods where the
|
|
53
|
-
screen keeps re-evaluating even when no single event stands out.
|
|
54
|
-
|
|
55
|
-
### Long View Body Updates
|
|
56
|
-
|
|
57
|
-
Highlights expensive `body` work. These often point straight to code you can
|
|
58
|
-
simplify or move out of render paths.
|
|
59
|
-
|
|
60
|
-
### Long Platform View Updates
|
|
61
|
-
|
|
62
|
-
Useful when SwiftUI hosts UIKit/AppKit content. If this lane is hot, inspect:
|
|
63
|
-
|
|
64
|
-
- `UIViewRepresentable` / `UIViewControllerRepresentable`
|
|
65
|
-
- `List` row content with embedded platform views
|
|
66
|
-
- media, map, or web components
|
|
67
|
-
|
|
68
|
-
### Other Long Updates
|
|
69
|
-
|
|
70
|
-
Captures non-body SwiftUI work like layout, geometry, and update coordination.
|
|
71
|
-
|
|
72
|
-
### Hitches
|
|
73
|
-
|
|
74
|
-
Frame misses. These are the symptom users feel, not always the root cause.
|
|
75
|
-
|
|
76
|
-
## Diagnosing long updates
|
|
77
|
-
|
|
78
|
-
### Start with the red/orange update window
|
|
79
|
-
|
|
80
|
-
Do not begin from total runtime. Begin from the expensive update itself.
|
|
81
|
-
|
|
82
|
-
### Correlate with Time Profiler
|
|
83
|
-
|
|
84
|
-
Set inspection range on the slow update and inspect hot frames.
|
|
85
|
-
|
|
86
|
-
Common findings:
|
|
87
|
-
|
|
88
|
-
- formatting in `body`
|
|
89
|
-
- array transformations in `body`
|
|
90
|
-
- image decoding during scroll
|
|
91
|
-
- representable updates doing too much work every pass
|
|
92
|
-
|
|
93
|
-
### Typical fix shape
|
|
39
|
+
Typical findings:
|
|
40
|
+
- formatting in `body`,
|
|
41
|
+
- array transforms in `body`,
|
|
42
|
+
- image decoding while scrolling,
|
|
43
|
+
- representables doing too much on every update pass.
|
|
94
44
|
|
|
95
45
|
```swift
|
|
96
|
-
//
|
|
97
|
-
Text(
|
|
46
|
+
// Formats on every evaluation.
|
|
47
|
+
Text(order.total, format: .currency(code: order.currency))
|
|
98
48
|
|
|
99
|
-
//
|
|
100
|
-
Text(
|
|
49
|
+
// Reads a value the model prepared when the total changed.
|
|
50
|
+
Text(checkout.totalText)
|
|
101
51
|
```
|
|
102
52
|
|
|
103
|
-
The
|
|
104
|
-
|
|
105
|
-
## Diagnosing frequent updates
|
|
106
|
-
|
|
107
|
-
### Watch Update Groups and Cause Graph together
|
|
108
|
-
|
|
109
|
-
Frequent updates often look like "the screen keeps waking up" rather than "one
|
|
110
|
-
frame is red."
|
|
111
|
-
|
|
112
|
-
### Look for noisy dependencies
|
|
113
|
-
|
|
114
|
-
Typical offenders:
|
|
115
|
-
|
|
116
|
-
- a timer injected high in the tree
|
|
117
|
-
- geometry state stored in a shared model
|
|
118
|
-
- a broad `@Observable` root model
|
|
119
|
-
- environment values changing more often than needed
|
|
120
|
-
|
|
121
|
-
### Reduce fan-out
|
|
122
|
-
|
|
123
|
-
Good strategies:
|
|
124
|
-
|
|
125
|
-
- split shared models by domain
|
|
126
|
-
- move fast-changing state lower in the tree
|
|
127
|
-
- derive narrow child state instead of passing whole parents
|
|
128
|
-
- gate updates by thresholds when continuous values are noisy
|
|
129
|
-
|
|
130
|
-
## Common remediation patterns
|
|
131
|
-
|
|
132
|
-
### Precompute presentation values
|
|
133
|
-
|
|
134
|
-
Cache strings, sorted arrays, and other display-ready values before render.
|
|
135
|
-
|
|
136
|
-
### Make dependencies narrower
|
|
137
|
-
|
|
138
|
-
A row should depend on row state, not screen state.
|
|
139
|
-
|
|
140
|
-
### Keep representables idempotent
|
|
141
|
-
|
|
142
|
-
Only touch hosted UIKit/AppKit views when actual inputs changed.
|
|
143
|
-
|
|
144
|
-
### Avoid layout feedback loops
|
|
53
|
+
The lasting fix is usually architectural: decide where derived values live.
|
|
145
54
|
|
|
146
|
-
|
|
55
|
+
## Diagnosing Frequent Updates
|
|
147
56
|
|
|
148
|
-
|
|
57
|
+
This looks like a screen that keeps waking up. Watch Update Groups together
|
|
58
|
+
with the Cause and Effect Graph.
|
|
149
59
|
|
|
150
|
-
|
|
60
|
+
Noisy dependencies to look for:
|
|
61
|
+
- a timer injected high in the tree,
|
|
62
|
+
- geometry stored in a shared model,
|
|
63
|
+
- one broad `@Observable` object at the root,
|
|
64
|
+
- environment values that change often.
|
|
151
65
|
|
|
152
|
-
|
|
66
|
+
Reduce the fan-out:
|
|
67
|
+
- split models by domain,
|
|
68
|
+
- move fast-changing state further down,
|
|
69
|
+
- hand children narrow derived values,
|
|
70
|
+
- apply a threshold to continuous values before storing them.
|
|
153
71
|
|
|
154
|
-
|
|
72
|
+
## Remediation
|
|
155
73
|
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
|
|
74
|
+
- Precompute display values such as strings and sorted arrays.
|
|
75
|
+
- Rows depend on row state, not on screen state.
|
|
76
|
+
- Representables update idempotently.
|
|
77
|
+
- Avoid feedback loops where geometry updates state that changes layout that
|
|
78
|
+
changes geometry.
|
|
79
|
+
- Keep lists identity-friendly: stable ids, data filtered beforehand, a row
|
|
80
|
+
count that does not fluctuate.
|
|
161
81
|
|
|
162
|
-
|
|
163
|
-
or navigation behavior. Verify the UX, not just the graph.
|
|
82
|
+
## Verification
|
|
164
83
|
|
|
165
|
-
|
|
84
|
+
Record the same interaction again and compare update counts, how often hitches
|
|
85
|
+
occur, the lane you were targeting, and the behaviour of the product. Fixes can
|
|
86
|
+
shift animation timing, placeholders or navigation, so check the experience as
|
|
87
|
+
well as the numbers.
|
|
166
88
|
|
|
167
|
-
|
|
89
|
+
## Guardrails
|
|
168
90
|
|
|
169
|
-
-
|
|
170
|
-
-
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
-
|
|
91
|
+
- Keep work out of `body`.
|
|
92
|
+
- Keep dependency surfaces small.
|
|
93
|
+
- Cache display data close to the model.
|
|
94
|
+
- No hidden allocations per row.
|
|
95
|
+
- Profile Release builds.
|
|
96
|
+
- Long updates and frequent updates are distinct bugs.
|
|
175
97
|
|
|
176
|
-
|
|
177
|
-
|
|
98
|
+
If the screen is still slow after `body` is clean, look at dependency fan-out
|
|
99
|
+
next.
|
package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md
CHANGED
|
@@ -1,27 +1,21 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- Use this when checking current SwiftUI Instrument lane names and remediation patterns.
|
|
23
|
-
|
|
24
|
-
## Understanding hangs in your app
|
|
25
|
-
|
|
26
|
-
- Transcript: [https://sosumi.ai/videos/play/wwdc2023/10248](https://sosumi.ai/videos/play/wwdc2023/10248)
|
|
27
|
-
- Use this when checking main run loop and Hangs instrument guidance.
|
|
1
|
+
# Apple Sources Behind This Skill
|
|
2
|
+
|
|
3
|
+
Search for these by title in the Developer app or on developer.apple.com.
|
|
4
|
+
Sessions are cited by title and year.
|
|
5
|
+
|
|
6
|
+
| Source | Kind | Consult it for |
|
|
7
|
+
|--------|------|----------------|
|
|
8
|
+
| "Optimize SwiftUI performance with Instruments" (WWDC25) | Session | The SwiftUI Instrument workflow, the Cause and Effect Graph, Instruments 26 terminology |
|
|
9
|
+
| "Demystify SwiftUI performance" (WWDC23) | Session | Dependency fan-out, identity, and guidance for lists and tables |
|
|
10
|
+
| "Understanding and improving SwiftUI performance" | Xcode documentation article | Current lane names and remediation for long and frequent updates |
|
|
11
|
+
| "Understanding hangs in your app" | Xcode documentation article | Hang thresholds, the main run loop, triage |
|
|
12
|
+
| "Analyze hangs with Instruments" (WWDC23) | Session | Using the Hangs instrument on the main run loop |
|
|
13
|
+
|
|
14
|
+
Which one to open:
|
|
15
|
+
- A trace from Instruments 26 with SwiftUI lanes: the WWDC25 session.
|
|
16
|
+
- Rows re-rendering, ids churning, a list that will not diff: the WWDC23
|
|
17
|
+
"Demystify" session.
|
|
18
|
+
- Deciding whether a problem is a long update or a frequent one: the SwiftUI
|
|
19
|
+
performance article.
|
|
20
|
+
- A freeze where you first need to prove the main thread is blocked: the hangs
|
|
21
|
+
article and the WWDC23 hangs session.
|