Quick summary: each tick the game tells Unity to move each port icon and apply new graphics to them. In most cases new and old graphics and location (cell) are unchanged, in which case time is spend doing absolutely nothing.
Disclaimer: I learned this while writing the mod High Flow Storage (source code, mainly files starting with ConduitPortDisplay). This is however specifically about performance issues in the vanilla method, not the mod. This is based on my experience with gas, liquid and solid ports, though it looks very likely that power and disease are also affected (Tick() handles those 5 overlays)
What happens right now:
1: If the overlay changed, hide all ports.
2: Switch case to find the current (new) overlay. If none are present, hide all ports.
3: For input port, check that it is in the current overlay, if it is, calculate which cell it should be in, if it's connected or not, look up connected/disconnected color and then draw the port
4: repeat step 3 for the 3 other ports (output port and secondary ports)
5: if no ports are found, hide all ports.
How I did the same while modding:
On building creation, add a port controller object. Add new port objects to it. It will sort the ports and have a list for each overlay. For each overlay it also makes a reduced list of ports, where connected and disconnected colors aren't identical. Preview buildings will add all ports to the "color changing list" because ports can move cell.
On new tick event, call the controller. It does the following:
1: if new overlay differs from the old one, hide the ports from the full list of the old overlay
2: get the list matching the overlay. Full list if overlay changed, reduced list otherwise
3: for each port object in the list, call Draw
4: the port object will figure out the color and cell and then call BuildingCellVisualizer::DrawUtilityIcon() only if the data differs from the last call.
Both look the same, but the modded code has a greatly reduced number of calls, both regarding internal calculations/lookup and calls to Unity. The reason that this works is that the port icons drawn on the cells will stay until explicitly told to move or hide. This means if (in case of vanilla ports) connected and unconnected colors are the same, then we only need to bother drawing the port when the overlay change, meaning we shouldn't bother to even consider that it exist each tick. Also there is no reason to look at ports, which we know will never be on the current overlay and checking if the magically moved overlay each tick is a waste of time.
Preview buildings can move and rotate, meaning there is no way around checking each port of the current overlay each tick. However that's not a major issue considering there is max one preview building on the screen at any time.
Steps to Reproduce
Invisible ingame. Read the source code.
This issue has been fixed in either a future version or updated in a previous version.