View in English

  • Apple Developer
    • Get Started

    Explore Get Started

    • Overview
    • Learn
    • Apple Developer Program

    Stay Updated

    • Latest News
    • Hello Developer
    • Platforms

    Explore Platforms

    • Apple Platforms
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    Featured

    • Design
    • Distribution
    • Games
    • Accessories
    • Web
    • Home
    • CarPlay
    • Technologies

    Explore Technologies

    • Overview
    • Xcode
    • Swift
    • SwiftUI

    Featured

    • Accessibility
    • App Intents
    • Apple Intelligence
    • Games
    • Machine Learning & AI
    • Security
    • Xcode Cloud
    • Community

    Explore Community

    • Overview
    • Meet with Apple events
    • Community-driven events
    • Developer Forums
    • Open Source

    Featured

    • WWDC
    • Swift Student Challenge
    • Developer Stories
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Centers
    • Documentation

    Explore Documentation

    • Documentation Library
    • Technology Overviews
    • Sample Code
    • Human Interface Guidelines
    • Videos

    Release Notes

    • Featured Updates
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • Downloads

    Explore Downloads

    • All Downloads
    • Operating Systems
    • Applications
    • Design Resources

    Featured

    • Xcode
    • TestFlight
    • Fonts
    • SF Symbols
    • Icon Composer
    • Support

    Explore Support

    • Overview
    • Help Guides
    • Developer Forums
    • Feedback Assistant
    • Contact Us

    Featured

    • Account Help
    • App Review Guidelines
    • App Store Connect Help
    • Upcoming Requirements
    • Agreements and Guidelines
    • System Status
  • Quick Links

    • Events
    • News
    • Forums
    • Sample Code
    • Videos
 

Vidéos

Ouvrir le menu Fermer le menu
  • Collections
  • Toutes les vidéos
  • À propos

Plus de vidéos

  • À propos
  • Code
  • Analyze hangs with Instruments

    User interface elements often mimic real-world interactions, including real-time responses. Apps with a noticeable delay in user interaction — a hang — can break that illusion and create frustration. We'll show you how to use Instruments to analyze, understand, and fix hangs in your apps on all Apple platforms. Discover how you can efficiently navigate an Instruments trace document, interpret trace data, and record additional profiling data to better understand your specific hang.

    If you aren't familiar with using Instruments, we recommend first watching "Getting Started with Instruments." And to learn about other tools that can help you discover hangs in your app, check out "Track down hangs with Xcode and on-device detection."

    Chapitres

    • 1:56 - What is a hang?
    • 3:51 - What is instant?
    • 4:39 - Event handling and rendering loop
    • 8:25 - Keep main thread work below 100ms
    • 9:15 - Busy main thread hang
    • 14:26 - Too long or too often?
    • 21:46 - LazyVGrid still hangs on iPad
    • 24:31 - Fix: Use task modifier to load thumbnail asynchronously
    • 25:52 - Asynchronous hangs
    • 32:38 - Fix: Get off of the main actor
    • 35:57 - Blocked Main Thread Hang
    • 39:19 - Fix: Make shared property async
    • 40:35 - Blocked Thread does not imply unresponsive app

    Ressources

    • Analyzing responsiveness issues in your shipping app
    • Improving app responsiveness
      • Vidéo HD
      • Vidéo SD

    Vidéos connexes

    WWDC23

    • Demystify SwiftUI performance
    • Meet RealityKit Trace

    WWDC22

    • Track down hangs with Xcode and on-device detection
    • Visualize and optimize Swift concurrency

    WWDC21

    • Swift concurrency: Behind the scenes
    • Understand and eliminate hangs from your app

    Tech Talks

    • Explore UI animation hitches and the render loop

    WWDC20

    • Stacks, Grids, and Outlines in SwiftUI

    WWDC19

    • Getting Started with Instruments

    WWDC16

    • System Trace in Depth
  • Rechercher dans cette vidéo…
    • 19:38 - BackgroundThumbnailView

      struct BackgroundThumbnailView: View {
          static let thumbnailSize = CGSize(width:128, height:128)
          
          var background: BackyardBackground
          
          var body: some View {
              Image(uiImage: background.thumbnail)
          }
      }
    • 19:58 - BackgroundSelectionView with Grid

      var body: some View {
              ScrollView {
                  Grid {
                      ForEach(backgroundsGrid) { row in
                          GridRow {
                              ForEach(row.items) { background in
                                  BackgroundThumbnailView(background: background)
                                      .onTapGesture {
                                          selectedBackground = background
                                      }
                              }
                          }
                      }
                  }
              }
          }
    • 20:03 - BackgroundSelectionView with Grid (simplified)

      var body: some View {
          ScrollView {
              Grid {
                  ForEach(backgroundsGrid) { row in
                      GridRow {
                          ForEach(row.items) { background in
                              BackgroundThumbnailView(background: background)
                          }
                      }
                  }
              }
          }
      }
    • 20:26 - LazyVGrid variant

      var body: some View {
          ScrollView {
              LazyVGrid(columns: [.init(.adaptive(minimum: BackgroundThumbnailView.thumbnailSize.width))]) {
                  ForEach(BackyardBackground.allBackgrounds) { background in
                      BackgroundThumbnailView(background: background)
                  }
              }
          }
      }
    • 24:05 - BackgroundThumbnailView

      struct BackgroundThumbnailView: View {
          static let thumbnailSize = CGSize(width:128, height:128)
          
          var background: BackyardBackground
          
          var body: some View {
              Image(uiImage: background.thumbnail)
          }
      }
    • 24:59 - BackgroundThumbnailView with progress (but without loading)

      struct BackgroundThumbnailView: View {
          static let thumbnailSize = CGSize(width:128, height:128)
          
          var background: BackyardBackground
          @State private var image: UIImage?
          
          var body: some View {
              if let image {
                  Image(uiImage: image)
              } else {
                  ProgressView()
                      .frame(width: Self.thumbnailSize.width, height: Self.thumbnailSize.height, alignment: .center)
              }
          }
      }
    • 25:26 - BackgroundThumbnailView with async loading on main thread

      struct BackgroundThumbnailView: View {
          static let thumbnailSize = CGSize(width:128, height:128)
          
          var background: BackyardBackground
          @State private var image: UIImage?
          
          var body: some View {
              if let image {
                  Image(uiImage: image)
              } else {
                  ProgressView()
                      .frame(width: Self.thumbnailSize.width, height: Self.thumbnailSize.height, alignment: .center)
                      .task {
                          image = background.thumbnail
                      }
              }
          }
      }
    • 29:59 - BackgroundThumbnailView with async loading on main thread

      struct BackgroundThumbnailView: View {
          static let thumbnailSize = CGSize(width:128, height:128)
          
          var background: BackyardBackground
          @State private var image: UIImage?
          
          var body: some View {
              if let image {
                  Image(uiImage: image)
              } else {
                  ProgressView()
                      .frame(width: Self.thumbnailSize.width, height: Self.thumbnailSize.height, alignment: .center)
                      .task {
                          image = background.thumbnail
                      }
              }
          }
      }
    • 31:41 - BackgroundThumbnailView with async loading on main thread (simplified)

      struct BackgroundThumbnailView: View {
          // [...]
          
          var body: some View {
              // [...]
              ProgressView()
                  .task {
                      image = background.thumbnail
                  }
              // [...]
          }
      }
    • 33:40 - BackgroundThumbnailView with async loading on main thread

      struct BackgroundThumbnailView: View {
          static let thumbnailSize = CGSize(width:128, height:128)
          
          var background: BackyardBackground
          @State private var image: UIImage?
          
          var body: some View {
              if let image {
                  Image(uiImage: image)
              } else {
                  ProgressView()
                      .frame(width: Self.thumbnailSize.width, height: Self.thumbnailSize.height, alignment: .center)
                      .task {
                          image = background.thumbnail
                      }
              }
          }
      }
    • 33:59 - synchronous thumbnail property

      public var thumbnail: UIImage {
          get {
              // compute and cache thumbnail
          }
      }
    • 34:03 - asynchronous thumbnail property

      public var thumbnail: UIImage {
          get async {
              // compute and cache thumbnail
          }
      }
    • 34:08 - BackgroundThumbnailView with async loading in background

      struct BackgroundThumbnailView: View {
          static let thumbnailSize = CGSize(width:128, height:128)
          
          var background: BackyardBackground
          @State private var image: UIImage?
          
          var body: some View {
              if let image {
                  Image(uiImage: image)
              } else {
                  ProgressView()
                      .frame(width: Self.thumbnailSize.width, height: Self.thumbnailSize.height, alignment: .center)
                      .task {
                          image = await background.thumbnail
                      }
              }
          }
      }
    • 38:52 - shared property causes blocked main thread

      var body: some View {
          mainContent
              .task(id: imageMode) {
                  defer {
                      loading = false
                  }
                  do {
                      var image = await background.thumbnail
                      if imageMode == .colorized {
                          let colorizer = ColorizingService.shared
                          image = try await colorizer.colorize(image)
                      }
                      self.image = image
                  } catch {
                      self.error = error
                  }
              }
      }
    • 39:00 - shared property causes blocked main thread (simplified)

      struct ImageTile: View {
          // [...]
          
          // implicit @MainActor
          var body: some View {
              mainContent
                  .task() { // inherits @MainActor isolation
                      // [...]
                      let colorizer = ColorizingService.shared
                      result = try await colorizer.colorize(image)
                  }
          }
      }
    • 39:10 - shared property causes blocked main thread + ColorizingService (simplified)

      class ColorizingService {
          static let shared = ColorizingService()
         
      
          // [...]
      }
      
      struct ImageTile: View {
          // [...]
          
          // implicit @MainActor
          var body: some View {
              mainContent
                  .task() { // inherits @MainActor isolation
                      // [...]
                      let colorizer = ColorizingService.shared
                      result = try await colorizer.colorize(image)
                  }
          }
      }
    • 39:25 - shared synchronous property after await keyword still causes blocked main thread

      class ColorizingService {
          static let shared = ColorizingService()
         
      
          // [...]
      }
      
      struct ImageTile: View {
          // [...]
          
          // implicit @MainActor
          var body: some View {
              mainContent
                  .task() { // inherits @MainActor isolation
                      // [...]
                      result = try await ColorizingService.shared.colorize(image)
                  }
          }
      }
    • 39:39 - shared synchronous property after await keyword still causes blocked main thread (+colorize function)

      class ColorizingService {
          static let shared = ColorizingService()
         
          func colorize(_ grayscaleImage: CGImage) async throws -> CGImage
          // [...]
      }
      
      struct ImageTile: View {
          // [...]
          
          // implicit @MainActor
          var body: some View {
              mainContent
                  .task() { // inherits @MainActor isolation
                      // [...]
                      result = try await ColorizingService.shared.colorize(image)
                  }
          }
      }

Developer Footer

  • Vidéos
  • WWDC23
  • Analyze hangs with Instruments
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • Apple Intelligence
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Downloads
    • Sample Code
    • Videos
    Open Menu Close Menu
    • Help Guides & Articles
    • Contact Us
    • Forums
    • Feedback & Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • Mini Apps Partner Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Read the latest news.
    Get the Apple Developer app.
    Copyright © 2026 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines