I have a set of layouts that I prefix with sys_, short for system. They have no layout objects on them and they correspond to table occurrences. They may be equivalent your utility layouts.
Steve, we also use blank layouts, either to improve performance within scripts or in some cases, no matter whether ‘Freeze Window’ has been set or not, we can get screen refreshes (in Windows) displaying a background working layout. In this case, we’d also use a blank layout set to the correct context and styled so as not to draw attention to it.
Blank layouts can be difficult to test and debug, so we’ll often put:
If [ not IsEmpty ($$DEBUG ) ]
Go to layout [ LayoutDisplayingFields ]
Else
Go to layout [ BlankLayout]
End If
Using Let to set or clear $$DEBUG makes it easy to toggle before the two.
We use the same procedure to format JSON if we’re debugging.
blank layouts, one per anchor (we use anchor-buoy);
interface layouts for data viewing and entry;
interface layouts for dialogues, pickers and similar UI elements;
API layouts when needed;
specialized layouts needed by scripts.
I used "all fields" layouts until I realized they impacted performance. They were seldom used. I now create and destroy such layouts only when needed. I sometime create troubleshooting files. They have these layouts and are not on the server.
ALL FIELD layouts have zero performance impact, IF you don't allow the users to use them or the developer to code using them. Their purpose is more around data, independent of code.
I use all-field layouts as developer layouts: to modify records manually - e.g. for testing purposes or to iron out errors caused by a bug - or to get an overview of whole records.
I suggest leaving summary fields off all field layouts, otherwise you may be waiting a while after navigating to one of these. Particularly if your server is hosted on the Internet.
I try not to make that [novice] design mistake in creating layouts. Same is true of unstored calc fields (of which a summary calc field is just one example). Even conditional formatting and HIDE characteristics are unstored calcs, although often (not always) lighter "weight" than data changes (no field write, just UI).
With prudent design, unstored calc fields can be eliminated by using an auto-enter calc with an embedded LET statement to trigger the calc programmatically, rather than the "always" that a typical unstored calc does.
We hardly use any calculation fields and never cross-table calculations. The vast majority is script driven, although the continuing lack of an OnRecordExit or OnRecordUnload script trigger continues to complicate this unnecessarily.
We avoid summary fields as much as possible and have a scripted alternative which still needs a bit more work.
Also worth noting that if you have 'Show Sample Data' set, then FMP will still draw down summary data when viewing a layout in Layout Mode, so I tend to restrict their placement to where only where they are explicitly needed, and in general, I'll try and script the generation of summary data, again, all in the pursuit of performance!
It is often a requirement to de-normalize child table fields in a parent, sometimes for performance, but also for the results of a FIND to be dependent on the parent only.
IF you have a child field on a layout and do a FIND against the field, the FIND results are based on the child, independent of the parent, typically providing unrelated records in the results. In a scripted find, you can resolve this by adding the primary key as an additional search term to the FIND, but in list view, it becomes a very complex FIND process. If the layout is based on the child, you have a similar problem with a FIND against the fields shown from the parent.
De-normalizing child fields into the parent, is almost always the most straightforward solution.
Using unstored fields to perform this, is a big performance issue. You can, instead, use an auto-enter field with a LET statement to set a calc-local variable, to some value that is guaranteed to change (I use a timestamp), which forced the auto-enter calc to trigger. A PSoS for a list of records, setting the timestamp trigger field, and therefore, causing the auto-enter to evaluate, lets you programmatically control when [what used to be unstored] auto-enter calc fields to update.