Welcome to the Power and Performance group lab at WWDC. My name is Cole and I'm a core technologies evangelist here at Apple. Power and Performance is about getting the most out of your app, launching quickly when someone opens it, scrolling smoothly in lists and collection views, and being optimized for battery life and storage. So today I'm joined by a panel of experts. These are just a few of the folks that work on making Apple's own software fast and fast. and efficient, and build the tools that make it possible, like instruments, MetraKit, and more. And in addition to those on screen, there's a whole team of folks behind the scenes helping with the triage of all of your questions. So let's kick this off with some introductions. Maybe we'll start with Terry. Can you just maybe each talk a little bit about yourself and what you're focused on at Apple? TERRY BIRD: Yeah. So I'm Terry. I work on performance. So I help teams across Apple optimize many of the features that were announced this week at WWDC. Cool. Hi, I'm Yanni. I work on Metric Kit. Metric Kit is a framework that lets developers get metric and diagnostic data on device to improve their power and performance. Hi, my name is Katspar and I'm part of the Instruments team here at Apple. Instruments is part of Xcode Suite and it allows you to record, visualize and diagnose your app's performance and power usage. Excited to be here and whether you're just starting with profiling or you would like to dive a bit deeper, I would love to hear your questions. Hey folks, I'm Kunal. I work on power. Think about CoreOS Power, improving the power for features, applications, and optimizing them. So if you think about battery life, thermals, that's where my team really helps. And I help out with VisionOS, but also iOS third-party applications. Hi, I'm Marco. I'm a performance engineer here at Apple. My main area of focus is the render pipeline, animations, scrolling, all that type of stuff. Great. Well, thank you for joining me this morning. I see already there's a whole bunch of questions, but before we dive into the questions that we're getting online, I just want to start with talking about the new releases. I'd love to hear, maybe we can, I don't know who wants to go first. I'm going to look at Casper to go first. What are you most excited about for performance in the 27 releases? Yeah, I think that when looking at the instruments specifically, I'm really excited about the new run comparison feature. So maybe you don't know, but in instruments, you're able to record and name multiple runs depending on some of the experiments you're running. And instead of having to have two windows side by side and comparing them visually, now you have this new diffing feature that allows you to compare call trees and understand at a glance what regressed or improved so that you can make an informed decision and iterate further. That's awesome. How about Kunal? I think I'm excited about definitely the tooling support that's coming in, but also some of the metric support that's coming in, where we have state reporting and ability to kind of like slice metrics based on different application states. So we also have Xcode Organizer support to kind of like have metric goals. If you're looking at battery life goals or your historical performance of battery life, foreground energy terrain, you have this ability to now see metric goals that helps you figure out if your application is doing poorly or good. as far as battery life is concerned. So yeah, lots of exciting things. Marco, do you have anything that comes to mind? Yeah, I'm really excited for the combination of the state reporting and the metric kit. I feel like on the performance team, one of the hardest parts is just contextualizing what you're looking at and where the problem actually is. So being able to get that context of this is what the app was doing when there was a problem kind of cuts out the whole first part of trying to triage what went wrong. Totally. And Yanni, I think everyone stole your thunder because I know you worked a lot on these changes to Metric Kit, but anything that comes to mind for you? Yeah, I think I'm obviously very excited to hear that people are excited about the new features for Metric Kit. It is a very big year for us, so we have a brand new first API, and of course, like, the contextualizing piece is a big help for developers to understand, you know, what's happening in their app. So buy his vote here, but I think Metric Kit features are very exciting. That's awesome. And Terry? TERRY MCDON of talked about the new metric kit but metric kit is kind of getting rebuilt from the ground up like a lot of the existing metric API has been marked as to be deprecated there's a new as you said swift API for the framework can you talk a little bit about like the motivation for this change like that's a big change to the framework what is it that you know we're hoping to do with the new metric kit? Yeah, for sure. So the Swift first API, of course, will work very seamlessly with Swift, with Swift concurrency. So you can use a lot of our surface with more ergonomics, with modern Swift apps. Most importantly, we design it to work very well with our new granularity in the metric kit framework. So we're not only are we giving developers, you know, the daily report for metrics, but we're also having smaller breakdowns that developers can get more insights in smaller intervals. So the API is designed to sort of accommodate for these new different structures and data. And as well, there's new diagnostic and metric types that will be only for this new API. So it's hopefully good motivation for developers to move forward. That's awesome. Cool. Well, let's start with our first question here. The question that we're getting from our online audience is, as a beginner in iOS development, what are the main factors that affect app power usage and performance in SwiftUI? And how can I design simple apps that avoid battery drain and lag? Who wants to chat about this one? I could probably step in and start it off at the very least. I feel like for SwiftUI, one of the kind of main things you want to do is really separate your views from their inputs and make sure that when you're updating variables or things are changing, you're not redrawing stuff that doesn't actually rely on it. So making sure that the things that your views are looking at watching are actually things that care about and affect the view. So you're not doing redraws where you just end up with the same thing you had before and doing unnecessary work. So, you know, stuff like the new observable macro is really good for this because, you know, you only get updates for the fields that you read on those objects. So you kind of get like a separation for free. Yeah, totally. That's a great point. And I would say that you can always understand what kind of dependencies you have using the tooling that we have in instruments. So developers can profile their app using SwiftUI instrument. And then for the view updates, they can see cause and effect graph that allows them to understand these dependencies and break them up as necessary. Yeah. And to add on to the whole using instruments and stuff, I highly, highly recommend last year there was a talk, I believe it was like optimize SwiftUI using instruments that went through kind of a breakdown of how you can go from having an app, profiling it, kind of looking at the information provided by the instrument and kind of iterating on that. So I highly recommend checking that out if you're interested in kind of profiling, optimizing, kind of looking at the performance of your SwiftUI app. And there's two parts that I think, Kunal, is what you're about to say. There's like two parts to this, right? One part of this is like making sure that your SwiftUI usage is efficient. There's another part of this, which is actually trying to figure out if there's a power issue and if that's the case, where that power issue is. Kunal, do you have thoughts on where do you start for that? Yeah, I do have thoughts. I think SwiftUI performance is, I would say investing in SwiftUI performance is often going to get you power wins as well, right? Because it's compute bound. When you have compute bound operations and workloads, reducing the compute is going to help you not just with performance and latency. It's also going to help you with power. So one of the things I would say is whatever we said about invalidations, avoiding the invalidations of the views, avoiding redraws, making sure you have not a very deeply nested SwiftUI hierarchy. I think those are all good points to not just improve performance, but also power. And we get a lot of signals for these in our existing tools, right? We have energy logs that come in for Xcode Organizer that will share not just, like, you would often see, like, these deep call stacks of SwiftUI, which could, like, point to not just a CPU issue and an energy issue. But those same call stacks could also be seen in Hangs, which is like, oh, so we are not just seeing a hang because of SwiftUI taking a long time because of your UI hierarchy, but also power. So I would say go for it. Any SwiftUI optimization is not just going to help you with performance, but also with power. And there's also, we talked about the SwiftUI instrument, there's also the Power Profiler as well. Absolutely, yeah. Maybe it could indicate if you actually do have like a CPU issue that's landing in SwiftUI code. Very good call out. Power Profiler would definitely show up a bunch of the CPU energy being taken, you know, as SwiftUI rendering is going higher. And you might actually see some GPU energy as well out there. So it's a great, you know, I would say exercise to also run Power Profiler with your application connected. And then look at the SwiftUI instruments and the Power Profiler together to figure out, like, what's happening? What are the views that are, you know, causing most of the drain and the performance issues? Yeah, and I want to add on to that. If you're a beginner in iOS app development, maybe don't focus too much on SwiftUI at first. That might not actually be the problem. You can profile your app using a bunch of the other things and instruments just to see overall what is affecting performance of your app, what is using the power, things like that. If it says SwiftUI, then, yeah, sure, we can definitely follow all this advice and go down there. But it might turn out it's something completely different. Maybe you have some algorithm that's just churning a bunch of CPU, and that's really where all the power drain is going. So it's always good to just look at the overall picture first really before diving into one specific area. 100% agree with Terry out there. You have to understand the bigger picture. What are the bottlenecks in your application before you start investing? If you don't do a good job at measurement, at analyzing, you might end up optimizing something that's really not going to get you any wins or that might not be important for end users. So that's a great point. And that's not just in instruments too, right? Like sometimes, and I've seen this in discussions with developers too, where, you know, you kind of think you have a problem because it's showing up when you run it locally in instruments. And then you might look at your data in Xcode Organizer and find that actually the biggest cause of, say, hangs in your app is something else. And it's really hard to reproduce at your desk. So, you know, kind of using both sources of data I think is important. Local profiling is great for some things. Telemetry is really great for other things. I would also say like for the power profiler workflows, maybe there's like there's one lesser known flow where developers can actually disconnect from instruments, go and record these traces that can take multiple hours and then analyze them at desk. So that sometimes allows them to like, hey, let's try it out in the real world scenarios and not only at your desk in a very controlled environment. That's the performance trace in the performance trace. So developers can capture that and later airdrop to their Mac and open that in instruments. So yeah, both those modes, right, the tethered mode that you say where you're actually working side by side with instruments and the untethered mode, like you said, they're both very useful. It's great. Just speaking more about power, we have a question here, which is, what's the biggest power mistake you see in many apps that developers don't realize they're making? This is, I mean, there's not one, right? There could be like several, and it really depends. I have to choose one, Kuna. That was the question. I would say one of the most common pitfalls is not having the right amount of telemetry, not having the right amount of instrumentation, right? And so you end up focusing on areas that are not giving you the biggest return of investment. So understanding how your application is used, what are the scenarios and features that are most heavily used by our users, and instrumenting them, adding metric telemetry, analyzing them in detail, looking at field analytics, looking at Power Profiler or other profiling tools, is a real benefit to figure out what to invest in. And people underestimate this a lot. Often they might find a customer report that says there's one specific issue and over-index on that, while there could be field analytics that's showing a bigger problem or a larger set of issues. So I would say never underestimate the importance of instrumentation and measurement. You always want to measure stuff before you optimize it. Yeah. I think if I had to think of one thing that comes to my mind, I think it's not accounting for different types of state that might affect the power characteristics of the app. I know we've both seen, like, you know, you go to Xcode Organizer, you look at energy logs, and you'll see things like, why is this database taking so long to write and it's taking so much power and it's so much time to write this database? And it could be because a bug is writing too much data. It could just be your app wasn't really tested on very large sets of data, right? And at your desk, you know, connected to Xcode, you can't necessarily replicate that. But then when you look at different sources of data, you find that that's actually driving a huge power issue. Yeah, absolutely. And maybe it's part of, like, part of it is also just inducing different conditions. like maybe your device is under thermal state. And with Xcode, you could actually use a condition inducer feature to force your app in that state and then see how it behaves in instruments, like how many more hitches, how many more hangs you have, so that you can diagnose these scenarios. Great call-out, right? And even the untethered mode sometimes allows you to induce those conditions. Like when you're moving around, when you're traveling, and you have those cellular connections switching, I think both of those are great ways to have those conditions induced. I think something else that developers can sometimes take for granted is that everything uses power every time you're hitting the file system you're using a little bit more power every time you're sending off network requests you're using more power more precise location stuff, using more power so just kind of knowing what your app actually needs to be doing and how often it needs to be doing if you can send out network requests half as often that's a free power win totally we talked a little bit about instruments So I'm going to pick on this question here. The question from the developer is, what is the best documentation for instruments? Are there any written guides? Maybe I'll look at Casper. That's a great question. There's many written guides. But I would say that the best one, if someone is just starting with instruments, is the instruments tutorials. So this was written a couple of years ago, actually by an instruments engineer. And it was really designed to feel like you have an instruments engineer by you and getting through the app with you step by step. It comes with an associated project that has some of the performance issues built in so that you can just get started and learn how to detect hanks, like how do they appear visually, and then go through the whole process of profiling, fixing them, and instruments. So that would be the resource I would start with. And then as you are reaching for different tools, there are guides written for them. I would also say if you're missing any documentation, I would encourage folks to reach out to us using Feedback Assistant and let us know. Totally. Is there any, maybe this is too broad of a question, but anything about instruments or maybe some of the tools that are now available in the 27 releases that are a great place to start for beginners? Would you recommend using the time profiler as your first pass, or is there something else that you'd recommend? If you've never used instruments before, start with this and give it a try. I personally think using Time Profiler with the Flame Graph view is a really good way to start. I find that the way that Flame Graphs visually show you how much a particular operation or call stack is actually costing you, it's really easy to see where the performance is going in your app rather than just looking at a textual outline or something where you have to look at numbers. You can just directly see, oh, this is a really big portion of where my time is going. Totally. Yeah, that's a great point. And we've been investing in this, like, how do we make this data more approachable with top functions as well? So that's like yet another mode of the cult review and instruments. And that allows you to see a flat list of top helper and compiler runtime functions. So it's easier than going through like deeply nested outlines. And you can see offenders at a glance. Yeah. The first time someone explained the flame graph to me, I was very confused about what it meant. And then I clicked it and I was like, oh, that's neat. It actually makes it pretty simple. OK, there's a question here. This is kind of related to everything we've been talking about. The question is, our app shows UIKit slash SwiftUI screens without much background tasks, but it's still using high battery according to Xcode. I'm assuming this is referring to the energy gauges in Xcode. What are the best practices to know what's going on and why this might be happening? Yeah, this is an interesting one. So the UI, we're saying that the application shows UIKit and SwiftUI screens without much background tasks, but the developer is still seeing a high battery usage in the background. Yeah. Yeah, this could get interesting. I would say, like, there's probably modes of your application where you are actually scheduling background tasks. So this may not really be to do with your foreground usage of your application. The SwiftUI and the UIKit compute should basically reflect as foreground energy for the application. So if you're seeing background energy drain, what you really want to look at is, like, are there modes for your application where you're scheduling background tasks or doing certain location stuff when the application's not in the foreground? And today, you know, I would say the Power Profiler is a great way to look at that. I would use the untethered mode often to see, like, hey, are you accidentally scheduling background tasks when you're not supposed to? By untethered, you mean the option in developer settings. So you just, like, record a power trace on your device, not connected to instruments, and then open that up later. Move around, yeah, try to replicate a real-life scenario and then see what's really happening. And are you scheduling background workloads? So those should then be visible when you then connect and load that trace in instruments again. Yeah, that also shows you a breakdown of energy used by a subsystem. So you can see, like, how much is CPU, GPU display you're using. Maybe you're just doing something. Maybe the brightness is very high and you're doing a lot of swaps of colors. So there's many, many reasons where things can go wrong. Networking also shows up a lot. You know, I think one of the things that you could see in the power profiler is, like, the network that your application is using when in the background. So, yeah, these would be the ways I would actually try to narrow in on the problem. Excellent. Just looking through the questions here, this is a bit of a SwiftUI question, but maybe we'll have some thoughts on it. The question is, a theme object, like colors and tokens, is injected through environment object and read in every atomic component, dozens of nesting levels, hundreds of components on screen. At what scale does this become a bottleneck? And is there a recommended alternative for this use case? I guess I can pitch in on this one. It can be a little bit hard to tell specific numbers, especially because what the actual views are can change their behavior and how much of a performance impact they have. In general, putting things in the environment can be a very useful abstraction for passing things down through your view trees. So I think this is probably a case where using the SwiftUI instrument, you can actually kind of see how much downstream effect these changes are costing you because it is a very case-by-case basis. In some cases, maybe it's fine and it causes no issues, but there might be other kind of configurations of your views and your view tree that it might be problematic. And so really getting a view of what's happening and what the downstream costs of those are is really important for figuring out if it is a problem or if it isn't a problem. Any other thoughts on that? Awesome. Great. Let's move on to another question I'm seeing here. This one I think might be for Yanni, but we'll see how the conversation goes. How would you load large data sets, like 50,000, 500,000 records in SwiftUI tables? I don't know. I know you're not the SwiftUI expert in the panel here, But I think the interesting question maybe for you is, how would you record or analyze performance and regressions using metric kit? So let's say you're trying to figure this out. Like, you know, how are you going to sustainably or scalably load this large data set in SwiftUI? How do you use metric kit to, like, kind of analyze the performance? Yeah, I think I guess the first question is with a database that's this large, how like how much of it do you actually need to load at a time for your user experience? So really understanding what kind of experience you're providing your users. If your view is not actually showing this amount of data, the first question is, is there a particular reason why you're loading that much to begin with? And if you're just working with a database that's that large, then I think, yeah, the first step of optimization is just to think about what you actually need and just load what you needed so that you don't sort of incur, you know, work that you may not need. of your user is not scrolling to that view. The other thing in terms of understanding, you know, identifying regression through Metric Kit or other tools, you could, of course, use the new state reporting function in Metric Kit that would sort of allow you to basically get information on what state your app is in so you can better understand what is your user doing and triage. If you're seeing a regression, what is it that is happening in your app? So you can sort of pinpoint what the problem area is. So those would be good starting points in triaging this problem. Actually, in your session video, you basically talk about this exact example, right? Where you're kind of running an experiment in the app to use like small batches or large batches in an app, and you're using different states to get different performance metrics for those states. And then that might inform like, where do you invest more of your time? or how do you build out the rest of the app using that model? Interesting. So would I log my size of the list using state reporting, and that would show up? Yeah, so the recommendation is you shouldn't be logging very frequently changing numbers, so you wouldn't be the number of items on your list. But you can categorize them. For example, you can define what is it that your batch size is. If it's a large size, medium, or small, then you can use that information to see, okay, within this range, my performance has been changed. Because sometimes it's like 1,000 item versus 1,001 item may not make a difference, but then now you're incurring a lot of cost just to record that. So defining those boundaries that make sense for you to sort of analyze later will be very helpful. That makes sense. Awesome. Well, actually, to quickly add on to the SwiftUI portion of the beginning part of the question. Sure, yeah, yeah, please. What Yoni was saying about the kind of batching things is really important. And SwiftUI provides some lazy versions of like H stacks and V stacks that will kind of manage that for you and only load things as you're kind of scrolling and bringing them onto the screen. So you kind of benefit from SwiftUI handling that for you. Yeah, I think that's a really important point just overall in terms of like batching. And like, I know one of the things we think about for app launch time is like, what is the minimal set of information we need to draw the first frame? And like, try to optimize for that to get really great launch time. And then that kind of trickles through the rest of the app, too. As you're scrolling, you're just kind of loading the data that you really need. Great. I'm going to change topics a little bit because there's a question here that I think is really interesting. I'll just read the question, then we can talk about it. The question is, how does iOS 27 prioritize background tasks when the system is under heavy Apple intelligence workloads? I think this question is interesting because, you know, I can totally see the concern, which is like, you know, maybe my app does processing with background processing tasks. And it's really important that those processing tasks actually happen. Maybe my app uses app refresh tasks and I don't want those to like go away because the system is doing more work for for other things. Maybe I'm looking at Terry. Do you have any thoughts on kind of like how should we as developers kind of like reason about the new world of more intelligence features on the system when it comes to this stuff? Yeah, I think it's a good concern to have. Definitely. I mean, it sounds like we're adding all these new things like isn't this going to affect, you know, your apps and background tasks running on the device? I think, you know, in a lot of cases, it's not necessarily going to cause a problem. If you think about, you know, many of the Apple intelligence features, they run on the neural engine or they're running in private cloud compute. And so if your app is using CPU while the Apple intelligence workload is using the neural engine, you know, those might be able to run at the same time and not cause any problem. So it kind of depends exactly on what the workload is and, you know, what resources you're actually using. But I think in general, it's important just to make sure that you configure your background tasks into small chunks so the system's able to easily pause them and resume them when necessary. So that if you're doing some really big task and you have to stop in the middle and then the next time you have to start the whole thing over again, if you're scheduling it in chunks, then you can kind of still make progress even though the system might not be running you as frequently as you would hope to. yeah i would say from the tooling perspective we've also added some new things here for the system trace so i knew you're going to be able to see priorities of your threat so maybe sometimes you're misassigning priorities on your qos workloads or in your swiss concurrency task workflows and you will be able to see that in instruments see what tasks preempted your threat So this gives you more insight to understand the exact problem. Yeah. But I think the general thing to realize is that the system is trying to do its best to run your workloads. Even at Apple, we have a ton of workloads that run in the background. We don't want those to stop making progress either. So we're doing our best to make sure that everything's scheduled automatically for you and giving the best experience for the user. Totally. Cool. This is sort of related, but a little bit different. This is not so much about, I think, background tasks, but kind of doing background work when the app is in the foreground. The question is, to avoid blocking the main thread, I perform expensive tasks on background threads. However, during launch, this method causes a lot of thread hops. And there's kind of two questions here. One is, how expensive is frequent thread hopping as compared to thread blocking? And the second is, is there any better solution overall for performance? we're all looking at each other wondering who wants to talk first i guess i'll start with the specifically about the thread hopping yeah uh it's certainly a concern um you know if you're doing it way too frequently uh it will add overhead every time it has to switch to a different thread but in general if you're not doing it a whole lot like the overhead is pretty much negligible um so if you know i don't know of an exact number but i would say you know if you're not doing it like thousands of times per second or something, then it's probably fine. And then one technique you can use is also if you can wait to do some of that work as well. A lot of that work is not necessarily needed exactly at launch. We just talked about this in one of the previous questions. Think about what is the data you need, the minimum amount of data you need to get your app to its loaded state during launch. And then you can kind of delay everything else until after that has already happened. Also, what Kasper mentioned earlier for the background tasks, making sure we're prioritizing things correctly as well, that's really important. So all those background threads that maybe you're spinning up, as long as they're prioritized lower than the work that your app is actually doing to load its main content, then it hopefully won't have too much of an impact on what the user is actually experiencing. KASPERIN CHEN: Yeah, that's a great point, Terry. I think the lazy deferral of work, the non-critical work, I think that is a key to make sure your launch is really, really optimal. So there's other techniques as well, right? I think there's pre-warming of the application. Like if you have abilities to use BG App Refresh Tasks to actually fetch the information that's needed during the launch, you're reducing some of that workload when the launch actually happens. So keeping a really close eye on what's really needed and what can be deferred or done earlier is a really good way to minimize those context switches during the app launch. and what would be like the approach to kind of see if this is a problem like how do you what's the best way to like measure this and and see like is this a theoretical problem or is this an actual problem in instruments you will see a context switch count being graphed as a histogram so that can give you an idea on like how many context switches are happening and you can try to later correlate it with your uplaunch metrics for example so maybe you're trying different approaches and one of them context switch count spikes and see how that affects your your uplaunch but yeah i agree with the points made that try to defer the work. And I think that sometimes, you know, we see developers trying to fetch kind of like A-B test experiments during launch, things like that. And yeah, I would say maybe you can just cache the last result and change your business logic this way. So try to be creative about this. Yeah, I think you folks can keep me honest on this, but like, I think the bigger issue that we've seen across apps is not so much spinning off work. I mean, it can be a problem. I'm not saying it's not, but not so much spinning off work that needs to be done on different background cues, but it's often the case where you spin off a whole bunch of work and then you make the main thread wait for all of that to complete before your first frame because now the whole app is basically frozen until that background work is complete. so maybe this is like a tangential question what's the best way to identify that? like how do I know if like it's my problem isn't so much that the background work is happening but it's actually delaying my app launch because of all that work I mean if you were actually waiting on that you would see it in the main thread view and instrument so you would use system trace template that allows you to record all of your thread states and in this case your threat probably would become blocked like if someone is actually is actually blocking their main threat so you would you would look there but yeah I can definitely see I think very common cases like spawning too much background work during launch and that is competing and maybe you have your network request and a couple of other requests happening at the same time maybe from some framework that you're linking so really inspecting what's happening and what's on your critical path to launch. Gotcha. Sorry, go ahead. Sorry. I think one of the sort of more out-of-the-box sort of like way to think about this is also just if you're not even checking your launch time, I think a good starting point is to even look at your launch time to begin with. Like, what is your launch time? Like, what do you think about? Like, does that align with what you expect? Like, if you're the user and you're waiting this amount of time for your app to launch, how, like, what would you think about that? And then using that sort of metric to compare with different versions of your app to see if that has moved and how, like, is that expected? Or did you make a change that you need to sort of address this issue? Yeah, and then the other thing I wanted to add was if you have already shipped your app out to customers and they're actively using it, you might be able to open up Xcode Organizer and there's a launch area in there as well, which shows you not only the launch metrics, but also it can show you the top issues of the actual call stacks where users are hitting slow launches. And so in that case, without even profiling with instruments, you'll still get a similar view. And you can see if your app is blocking on other work or just doing too much CPU work during launch. TAYLOR WILSON: Totally. Great point. I actually, just talking about App Launch a little bit, I'm remembering a question we got in the labs yesterday at Apple Park around just measuring app launch time. Because I think there's a lot of folks that come up with kind of their own technique. They might be inspecting like kernel APIs to see when the process was created. And they're using that as one of the kind of goalposts for launch. But MetraKit doesn't do that at all, right? It uses a different technique for actually measuring launch. Do you want to talk a little bit about that? Yeah, so we obviously recommend the Apple technologies for folks to measure or launch and don't try to sort of speculate or inspect and cause actual more overhead in trying to get this information. I think if you use MetricIt or the organizer, you would get this information. The system would do that for you. It measures when the user taps on your app and when your app actually launches where the first screen is drawn. So all of that is done for you at an efficient way that will not incur extra cost to your app. So definitely recommend using our tools. Yeah. That's the same thing we use for our own apps, right? When we're measuring launch time for the mail app, for example? Yeah. Yeah. And I think that what's really cool about that is that it measures something that you can't measure inside your app process, which is when someone actually taps on your app icon on the home screen. Your app is far away from existing yet, And yet MetricKit and the organizer are able to kind of give you that interval, which is really great. Okay, I'm going to go back to some of the questions we're getting here. This question is kind of going back to battery. I know we touched on this a little bit already, but the question is, besides background tasks, what's the most common silent battery killer in SwiftUI? How much power does view over invalidation actually drain? And what's the best instruments workflow to catch it before release? Yeah I mean I'll hit the SwiftUI side of it and then you can go for the power stuff I mean view over invalidation can be like a very big killer of battery life just because you are just redrawing doing a lot more work on the CPU and also it is like a very silent thing because by definition over invalidation is you are recreating a view that looks exactly the same so you can be looking at your phone and you can see nothing's changing on screen but in the background if you're over invalidating you can have the CPU just churning and churning and churning. Yeah, I completely agree with you. I think for SwiftUI, I would just mainly focus on minimizing the redraws and maybe flattening your UI hierarchy as well. I think that's a big one. These should help minimize your foreground energy drain quite a lot. And then looking at other work that you're dispatching on the background threads, those could be other aspects that are happening. SwiftUI threads are dispatching workloads in order to get information, fetch data so that they can show it. Keeping a close eye on that is also useful. Using the basic principles of software engineering, cache when possible, minimize repetitive work. I think those are all the things that you should focus on. And I would say as far as our tooling support is concerned, SwiftUI instruments is a great way to actually focus on those. Gotcha. Yeah. Just kind of on the topic of SwiftUI, there's a question here, and I know you folks are not the SwiftUI engineers, so maybe this is a question better suited for our SwiftUI group lab, but maybe you folks have thoughts anyway. Are there any performance improvements for very large lists and table views in SwiftUI for macOS 27? What are some best practices for making long SwiftUI lists and tables work well with tens or hundreds or thousands of items? Do you have any thoughts on this, Marco? Yeah. I mean, I think for having large lists and stuff like that, one of the things is if you're keeping your list size constant, then SwiftUI can kind of know how to manage it, whereas if you're kind of constantly changing the size of your list, that can change the height of things. As long as you're keeping things more or less constant, that works pretty well with SwiftUI's model of kind of updating things as needed. And there are some lazy data structures and stuff that can kind of help you. And then also, you know, moving some of that kind of filtering and stuff into the kind of model side of things. So instead of having like an if statement in your for each, that is, you know, checking each thing in your list and like having to do that calculation. If you do that before you even provide the list to SwiftUI, then SwiftUI doesn't need to kind of like chew on that. It can just display what it needs to display and nothing more. Are there any other kind of sources of hitches that you've seen with, like, very long listen tables apart from just, like, kind of, like you said, batching it in the model? Is there anything else that people should be, like, on the lookout for? I know that's, like, a broad question. Maybe the answer is no. It's kind of tough. I mean, I think a lot of the things is like when people have cells inside of their list that are changing size, it kind of has a cascading effect where, you know, if something in the middle list changes size, suddenly everything below it has moved. And we have to do recalculations of knowing like what would be on screen at this kind of like offset in the scroll view. So we kind of have to do more work to figure out, like, okay, what state are we in now versus, you know, keeping things very similar, clean, tidy, constant size, where Swift can kind of utilize its kind of caching capability that it uses behind the scene, I think is very important. Gotcha. Great. And on the kind of similar topic of SwiftUI, this is a fairly advanced SwiftUI question. But the question is, I use AnyView for type erasure in several places. How expensive is it in practice? Is there a concrete threshold, like end views, end redraws, beyond which any view becomes a problem? Or is avoiding it premature optimization? I'll take this one, too. Sure. So using any view and kind of using type erasure does add a bit of overhead when you're creating the view. And I would try to avoid it if you can easily avoid it. However, I do think it's one of those things where you can address it if it becomes a problem. I think trying to kind of bend yourself around not using it, you're kind of missing a return on investment. And if it becomes a problem, you can maybe keep it in mind as something on the roadmap of maybe this will be a problem. But I think trying to focus on that, I think there are probably time better spent elsewhere. Yeah. I think I'm focusing on measurement, not only in SwiftUI. I feel like when I'm working on instruments itself and sometimes I have a need to make something threat safe and add unfair log, for example. I have a perception of, like, oh, it's going to be really expensive. But then I add it, and it's just so quick. So really base your, like, actions on the measurements. Yeah, I think that's important, too, because, like, we try really hard not to build API that are, like, a rake to step on. Like, you know, certainly there are, you know, patterns that work better than others. I'm not saying otherwise. But, for example, I'm thinking about there's an accessibility session this year that talks about using any layout to switch between a horizontal layout or a vertical layout, depending on if you have larger text enabled. That's totally fine. Like, that's probably you can measure it, but that's probably not going to have this huge performance impact. But you could totally go overboard and do something that might have impact. So I totally agree. Measurement is kind of the best place to start. Yeah. And the features are there for a reason, right? Yeah. If they are more expensive, like, sure. that you might need to take that cost, and that's fine in a lot of cases. Yeah. Great. I'm going to move on. Let's just kind of switching gears back to Metric Kit and state reporting. The question is, Metric Kit, state reporting, and crash report extensions are new and noteworthy this year. Are there any other headlining developer tools that didn't make the updates page on the developer site worth looking at? I know we talked a little bit about some of our favorite things this year, but anything come to mind we haven't talked about yet? Yeah, I think there's a lot going on with Xcode Organizer. So it does provide field data like Metric Kit. It is a different population that is aggregated across all of your users. It does provide like a visualization, but it has less flexibility in terms of how you want to aggregate data compared to Metric Kit. So some of the very exciting things, because it is aggregating across different apps, we do have improvements in metric goals. So developers can actually get a bit more guidance in terms of how you're performing compared to apps that are comparable to your app. So this helps with forming a baseline, which is a very hard thing if you're just given a number. How am I supposed to know? Is it doing OK? Should it be better? So I think that is a very helpful way for developers to-- if you're just starting out and you haven't measuring out of the box, you kind of already have a guidance line there. I think this is so neat because I think one of the questions we get in the labs all the time is folks open up their Xcode organizer and show it to us and say, I'm a video app. I play video all day long. My power is through the roof, I think, maybe. Or is this fine? I don't know, right? Like, what's a video app supposed to use in terms of power? So now you get that. Like, you can actually see, you know, compared to similar apps, what's their performance look like and kind of make decisions based on your stuff. Exactly. Any other kind of tools or thoughts of the new stuff? Yeah, I think I'd like what I didn't talk about things like foundation models. So for example, foundation models has a new updated tool and instruments. And this year it's extending. So last year we've had just some basic metrics on the tokens, on the token counts. Right now it's a fully, fully debugging tool that allows you to inspect all of your requests, prompts, understand how many tokens are being cached. So if you can, if you want to look into the performance side of things, that's going to be your great tool for that. There's also a tool that shipped in 26.4 for profiling long term metal apps. So we actually didn't talk about it. There's a dedicated session. But this tool allows you to record performance of your game over hours and understand FPS metrics, understand the outliers. And pairing it, for example, with the state reporting would allow you to maybe see-- maybe you were dropping frames in a specific level and inspect some of these workflows. So I would recommend sessions for checking these workflows out. That's awesome. What else? I think the other thing that I would point people to is there's a post on the developer forums that is, I believe, in the metric it tag that talks about kind of all the new stuff. So if you haven't been taking active notes throughout the group lab, you can check out that forum post. It will redirect you to all the new stuff that we have for Perf and Power this year. Great. I guess here's a question. I guess if, you know, knowing the new tools that are out there, if there's kind of like one thing you think, you know, you would encourage developers to like go check out for their app as kind of like a homework assignment from all the new stuff that they can do this year, what's like for you the one big thing that you want folks to give it a shot before they wrap up their WWDC work? I can take that one. Go for it. I think definitely looking at metric goals is a big one, right? because now you're going to see the metric goals and compare your metrics, how they're doing with it. So similar applications and having a sense of how similar applications are doing against your metric is a great way to understand what areas you need to invest in, whether it's power, foreground energy, launches, hitches, hangs. So that would be one big point. And then the second one I'm going to give a shout out to is the state reporting. I think it really allows you to slice the data and figure out in what application states are your metrics doing poorly. So if you're using a combination of metric-it-metrics along with state reporting, I think you can zoom in on the specific areas in your application that need attention. So, yeah, those two things. Awesome. I'm going to take a question that's a little bit different. So the question reads, Swift performance is something I'm genuinely passionate about and want to go deep on. Beyond WWDC sessions and Swift evolution proposals, what does the pathway look like? Specific code bases to study, compiler internals, books, benchmarks for building real deep expertise in this area? I think when it comes to understanding not just Swift and SwiftUI, but any kind of technology, I think it's just experience is kind of king here. And I think that given all the views and perspectives that Instruments tools provides, there's so many different templates like the Time Profiler, SwiftUI instrument, and all that stuff that just building things out and looking at them from that point of view and seeing what's actually happening and going on can kind of give you a better grasp and mental model on what these frameworks are doing behind the scenes. So I think just trying things out, opening it up in Instruments, trying out different templates and just seeing what it looks like when you do certain things can be a really good way to just kind of really immerse your something basically immersion right immersive learning yeah that's a great point and i think that's from the resources that apple provides we have had optimized cpu performance with instruments last year and that was a fantastic talk that went a bit deeper and it covered not only time profiler but also cpu profiler processor tray so that you can get the full overview of the suite for CPU usage. And there's also Apple Silicon Optimization Guide that allows you to understand how really things work under the hood. So developers can check that out. Awesome. Anything to add? Yeah, I was just going to echo the Apple Silicon Optimization Guide. I think one really important part is really understanding how our CPUs and our hardware works. If you have a really great understanding of that, then you can really take advantage of actually implementing Swift algorithms and things like that, which will perform really well on Apple hardware. That's great. Okay, this kind of goes back to SwiftUI a little bit, but let's take a look at this question. So the question is, so this person attended one of our performance events in October and learned to avoid kind of escaping closure-based parameters because closures are hard to compare, and that makes SwiftUI do more view and validations. The question is, it's been limiting because they're having to pass view builder content itself, whereas sometimes passing in an escaping parameter is essential. This also might be a question better suited for the SwiftUI group lab, but any thoughts on how to architect SwiftUI in trying to avoid escaping closures that could cause performance problems? So I think calling the closure in your init rather than in the body of the view so that it doesn't just run every time the view is reevaluated can be a good thing. I don't know a ton about this area, but then I think in general also, if you're finding that closures are causing a performance issue, maybe there's another API or a different kind of structure that you can use to get the same functionality without the same kind of performance hit of using a closure. But yeah, I'd highly recommend the SwiftUI group lab. I think tomorrow at 9 a.m. is? I think that's right. It's all in the line. You can check the schedule. Awesome. Anything to add? All right. Okay. This might be for both Marco and Kunal. The question is, this is a beginner developer, a mom of nine, former nurse getting back into tech. When handling dynamic data or heavy assets in SwiftUI, what are the best practices for ensuring view updates don't cause performance stutters, like hitches, or high CPU spikes on older devices? I mean, I think for stuff like heavy assets, I think there is something to be said about kind of tailoring what assets you're using depending on the use case. For example, you don't need like a 2,000 by 2,000 pixel image if it's just going to be a thumbnail. So I think making sure that the assets you're using are properly suited for the use case can be very important. Kunal, do you have thoughts on like CPU spikes? Like how do you kind of detect when those things happen and if they're bad and if you need to do something about it? Yeah, I would say assets and, you know, like in general loading data, especially during launch times or, you know, when you're showing a new page, initializing a view, paying attention to not just what Marco said, which is like, hey, minimizing the resolution or having the most lean weight version of that asset is very useful. But then there's another thing, right? Caching, I think caching is a good one. Once you've actually shown that asset, just making sure that you have a cache that can be accessed again and again would really help with minimizing some of the CPU workloads that can happen by either processing or parsing the network call that fetch the data. So being mindful of, you know, making sure that the assets that you're sharing are lean, as well as that you're not refetching them or recomputing aspects of that asset can be very useful. Something else to add, actually, is that oftentimes, like, if this asset is not, like, load-bearing in your application, then you can do something like, you know, put a placeholder image up or, like, a loading placeholder thing. So that way you don't have to load the image on the main thread and the rest of your app can kind of continue on and do its work while the image gets loaded in the background, I think can also be very good for kind of. Perceived performance. Yeah, yeah. Perceived performance and kind of that responsiveness feel. Yeah. What about the aspect of this question that's around like older devices? Like if you have a newer device and you're, you know, you're an independent developer and you have a newer device and you want to make sure performance is good on older devices, but you don't have one. And any thoughts on how you would kind of get a feel for if you're having this problem there? I think one really easy thing you can try, even if you have a newer device, is just turn on low power mode. Okay. Because that makes the CPUs run a lot slower to save battery. But it also means you might encounter some issues that you wouldn't normally see if you weren't in low power mode. And those might be similar issues that you would encounter on an older device. And it's also just a great way to generally optimize your app. Lots of users love low power mode, and so they're going to have it enabled. And if your app doesn't feel great in that mode, then you should definitely look into optimizing that. Yeah, and there are also condition inducers that I mentioned. I would also say that we see developers profiling on simulators. And, yeah, there's no difference depending on which simulator you use on what performance do you get because it all runs on your Mac. So that's one thing that is done. So I would recommend just always use a physical device for profiling specifically. I think another note is because physical devices are sometimes harder to get as a developer, tools like, you know, like Metric Kit and Organizer will allow you to give get field data, which you would have a bigger data set from your users. So if you naturally have users that have different types of devices, different conditions, those would be really good ways for you to get information on your CPU usage on a larger data set in real environments. I want to talk about this. You mentioned the condition inducers a couple times. Can you just say more about what that is? Like, how does it induce a thermal condition? Does it make the device hot? Like, what's going on? Not really. That just artificially induces that. And that's a feature that's part of Xcode. So developers are able to start a debug session. Or I believe it might be, I'm not sure, it might be in the new device hub. they are able to put their device in an artificially state, and they could limit things like network, speed, and other variables as well. Gotcha. So it is reducing CPU and other things. It's just simulating what would happen if the device were warm. Got it. Okay. Well, since we're talking about power, I have another question here that's kind of along the same lines. The question is, our app heavily relies on ARKit, Metal, and other compute-intensive processing. Since it is primarily used outdoors in direct sunlight, devices frequently experience elevated thermal states. What are the recommended strategies for managing thermal pressure and preserving a good user experience? Yeah. I sympathize with an app that's used in direct sunlight all the time. Yeah. It's a challenge. Yeah, one of the things I would definitely advise is there is an API out there that, you know, like indicates when you're running into like the higher thermal states. Yeah. So make sure your applications is listening for that. There's the process info.thermalstate. Go ahead and make sure your application is able to listen to higher thermal states. And based on that, back off on the experience, right? I think if there's often experiences can be designed in a way that they need, they don't have to be rich all the time. You can back off of some of the richer experiences without significantly compromising the end user experience. So looking at those thermal states is a good way to avoid such situations. Yeah. Do you have examples of what you could back off? Is anything maybe non-obvious that someone could do to back off the work in thermal pressure? Yeah, I think this is pretty case-by-case. It would really depend. For example, let's say you had heavy assets that you were downloading from the network that result in heavy parsing times and a lot of decoding that's happening on your device. Now, one of the things you could do is in your heavier thermal state, you could actually make those HTTP requests and request for more lighter resources from the network so that you're not going to be spending a lot of processing time on your device. There's other things you could do, like if you have heavier animations or more richer, smoother transitions, you could back off on those and have more simpler navigations or simpler animations. It's pretty case-by-case, actually. I think that the frame rate thing is actually pretty cool, too, right? I think we've seen that strategy in a lot of cases where you just reduce the frame rate until you exit that pressure condition. Yes. That one definitely helps. And often the system can also, like, in heavier thermal states, the system also puts in certain mechanisms to minimize animation frame rates as well as, like, display frame rates. So there's some benefit you get just by default, and then you can add on top of those. Gotcha. Any other thoughts on kind of thermal conditions? Yeah, I mean, just, like, yeah, frame rate, kind of backing off on frame rate, stuff like backing off on resolution. So if normally you're running at a high resolution, you get a thermal state indicator. that might be a good time to kind of lower the resolution, you know, pushing less data around, less pixels, it's going to be less work. And ultimately, at the end of the day, you're just, your app is in a use case where you kind of have to keep performance in mind, and you just have to optimize your app in that case. There's no getting around thermodynamics. Well, and I think that's the interesting thing about this problem is that, like, there's a part of this that you control, which is your app and the compute that your app needs and the power draw that your app needs. there's a part of this you don't control. Like ultimately, you know, devices can't run at 100 degrees Celsius. It doesn't work. So there's an aspect to this which is like optimize the heck out of the part that you do control. And that'll give the best possible chance that someone in those conditions are going to be able to use the app. Great. I think we have time for maybe one more question. I'm just going to peruse here a little bit. let's look at I think we talked about the environment briefly so maybe this will be somewhat quick but the question is does using a lot of at environment properties in a large SwiftUI app have any performance impact? For example, if many values are injected into the environment across a deep view hierarchy does that affect rendering or update performance in any way? So for the environment, the biggest thing for performance and kind of all that stuff is environment churn. So if you're just putting values in the environment and reading them out of your views, it's not that bad. It's not that expensive. It's when you start kind of like updating those in a high frequency and causing environment churn because other views that are reading from the environment now have to reevaluate. Like, has something in my environment changed? So putting things in the environment is not necessarily that expensive, but it's when you start kind of like really churning the environment. That's when you start to run into issues. Gotcha. And of course, you can see this in the variety of instruments we talked about, like the SwiftUI instrument today. Absolutely. That's great. Well, I think that's about all the time we have for this group lab. We're so thankful that you joined us today and hope that you found today's conversation helpful. Thank you to all of our panelists, as well as the folks behind the scenes working hard to make today happen. If we didn't get to your questions, please visit the Apple Developer Forums at developer.apple.com slash forums, including the Power and Performance Q&A, which is taking place on the forums on Thursday at 10 a.m. Pacific. And, of course, if you have any feedback or bugs, file them at feedbackassistant.apple.com. And you can also try out the new generative AI search experience at developer.apple.com to get answers about frameworks, design, accounts, and everything related to development on our platforms. And speaking of feedback, you'll receive an email with a survey link to let us know about your experience at WWDC. We would love to incorporate your feedback in future events. Thank you so much for joining us today, and have a great WWDC.