We all have been told countless times that parenting parts is expensive, because of the physics and other calculations performed when you do so. Always parent after assigning properties, don’t use the second parameter of Instance.new(), etc.
My question is this: Does this apply to ViewportFrames? They don’t render physics, but I’m not sure if other things are still in play. Does anyone have a more detailed understanding of the internals?
I want to know because I’m curious if I can parent and unparent objects into a ViewportFrame without killing all performance.
I’m sure that there are still internal things that occur, even when parenting to a view port frame, because it still has to render the actual object and if you’re editing things after it’s been parented, it has to replicate it to show to the client and all of that takes time. So, I’d still follow the rule of setting properties before parenting.
Since it still ends up rendering what you add inside, it’s probably better to set before parenting to avoid any issues. That being said, as the point of the topic states, not quite sure how this applies to ViewportFrames. Better to be safe with practices we already do.
The PSA regarding the Parent argument of Instance applies to all objects in the DataModel, not just parts. Here’s the post again in case you want to re-read it. The post itself actually has a decent enough explanation to cover the issues and reasons against the practice of parenting first before setting.
By nature of the above, it also applies to ViewportFrames. Once a ViewportFrame is in the DataModel, it’s no longer detached from the DataModel (as it starts off on creation) and internal Roblox systems start acting and listening on the object.
It’s always good practice for any objects going into the DataModel to have their properties (states) set before being added, regardless of what it is.
It doesn’t have to be a descendant of the Workspace. Workspace is a child and descendant of the DataModel. Anything that gets parented to the DataModel or one of its descendants (i.e. services - Workspace, ReplicatedStorage, whatever) is no longer detached from the DataModel. Physics don’t need to be present.
What kind of internal systems being used on the object is dependent on what it is. For non-BaseParts, it probably wouldn’t be the physics engine but more than likely something else. The provided sample up there is mostly an example outlining a scenario where Parent is assigned first before states.
ViewportFrames don’t register any physics updates, no. Though each stage has its own respective hand to play in performance. Cutting out a few steps still leaves the other ones in play, which are equally worthy to account for or take heed towards.
It is a common principle in programming to fully update/populate an object before handig it off to an external system, because they might expect to receive a complete object and might optimize for that (i.e. changes after the fact may be more expensive than you can observe from the outside, which is a waste of performance, or changes may not be taken into account if you change them after the fact (not for Roblox’s systems, but your own might)).
You should set the properties of any object before you parent it into the DataModel, because once it is in the DataModel it will start calling signals such as ChildAdded, DescendantAdded, CollectionService’s instance added signal, etc, and moreover it will start participating in the physics and rendering subsystems. It is quite untidy to first parent the object and then change its properties, as this might unnecessarily fire other signals / hooks in subsystems in your game. It also makes the job of your own systems that you define in your game harder (such as entity-component systems working on certain CollectionService tags), as the component would have to dynamically react to updates in these properties if you change them after parenting them into the game.
This holds regardless of what or where you are parenting a certain object to. There is also really no reason why you shouldn’t do this apart from it taking an extra line of code (.Parent call after setting properties rather than inside the Instance.new).