Option 2 as others have suggested is the best here since the script listens for a fired Tween.Completed event and then destroys the part. As opposed to the script waiting for certain operations to finish before carrying out the action which would cause the script to yield during those operations.
They pretty much do the exact same thing but tween.Completed is just the official way of doing it and so i would suggest that. Not sure but option 2 might be a tiny bit better for performance cause option 3 creates a whole new thread for the debris:AddItem function so it will not yield the code, which is unnecessary for what you are trying to do. but i can be totally wrong!
Oh my bad you are right! But really they do the same thing but tween.Completed is the official way so i would go for that to avoid any possible issues in the future.
The First Option would likely be fine. Though it should be kept in mind, that should the Tween for some reason finish instantly; you’d be yielded indefinitely. I’m not sure of any condition by which this would occur however.
The Second Option is problematic with respect to memory leakage, because you never :Disconnect() the connection to the Tween.Completed signal. I’d also call Tween:Play() only after the connection to the signal is created; for the same reasoning as Option One.
Option Three would likely always work just fine. Though you’re putting a lot of trust in Roblox’s scheduler being predictable and in sync. And again, should the Tween complete early for whatever reason; the destruction would be delayed.
So I think Option Two would be the best. Assuming you remember to :Disconnect() the signal connection, and call :Play() only after the signal connection is created.