Requested by: @Crabcyborg
What: Every option of every field ships as a full <li> on initial render - classes/views/frm-fields/back-end/field-options.php loops show_single_option() for each option, and classes/views/frm-fields/single-option.php:41-67 prints a label <input> plus a wrapper <span> with its own saved-value <input>, each carrying name/id/class/data-frmchange attributes built from the field id and option key. This happens for every field regardless of whether that field's settings panel is ever opened - on a form with 1000+ fields, or any field with a long dropdown/radio/checkbox option list, that's a lot of markup nobody looks at, sent and parsed up front.
Where the panel-open dance and the templating precedent already exist: showFieldOptions() (js/src/admin/admin.js:8295-8337) already fires frmShowedFieldSettings every time a field's settings panel is first shown - the same hook #3432/#3433 use for their own defer-to-open fixes. Separately, addFieldOption() (js/src/admin/admin.js:4103-4160) already has a full no-request way to build a real option row: it clones the hidden .frm_option_template row's outerHTML and string-replaces the 000 placeholder key/ids with the real option key (admin.js:4106,4138-4142). That's the exact job needed here, just triggered by 'panel opened' instead of 'Add option clicked,' and driven by option data already on hand instead of a template already sitting in the DOM.
Suggested approach:
- Server-side (
field-options.php / single-option.php): stop rendering a full <li> per real option. Keep the single hidden .frm_option_template row (still needed for the existing add-option flow), and instead emit the field's options as compact JSON - key/label/value - e.g. a data-options attribute on #frm_field_<id>_opts. This travels down with the field's existing payload (initial page render or the frm_load_field ajax batch already in place), not a new request.
- Client-side: on
frmShowedFieldSettings, if a field with options hasn't had its option rows built yet, run addFieldOption()'s clone+rekey logic once per JSON entry to populate the real rows, then flag it built so reopening the panel doesn't rebuild.
Related: #3432, #3433 - same underlying pattern (real work deferred to first panel-open), different mechanism (markup weight/DOM node count here, not third-party widget boot cost there).
Once merged: a field's option rows exist in the DOM only once its settings panel is opened. Until then, only the compact JSON travels with the page - roughly 10-15x smaller than the current per-option markup by itself, on top of not building the DOM nodes at all until they're needed.
Requested by: @Crabcyborg
What: Every option of every field ships as a full
<li>on initial render -classes/views/frm-fields/back-end/field-options.phploopsshow_single_option()for each option, andclasses/views/frm-fields/single-option.php:41-67prints a label<input>plus a wrapper<span>with its own saved-value<input>, each carryingname/id/class/data-frmchangeattributes built from the field id and option key. This happens for every field regardless of whether that field's settings panel is ever opened - on a form with 1000+ fields, or any field with a long dropdown/radio/checkbox option list, that's a lot of markup nobody looks at, sent and parsed up front.Where the panel-open dance and the templating precedent already exist:
showFieldOptions()(js/src/admin/admin.js:8295-8337) already firesfrmShowedFieldSettingsevery time a field's settings panel is first shown - the same hook #3432/#3433 use for their own defer-to-open fixes. Separately,addFieldOption()(js/src/admin/admin.js:4103-4160) already has a full no-request way to build a real option row: it clones the hidden.frm_option_templaterow'souterHTMLand string-replaces the000placeholder key/ids with the real option key (admin.js:4106,4138-4142). That's the exact job needed here, just triggered by 'panel opened' instead of 'Add option clicked,' and driven by option data already on hand instead of a template already sitting in the DOM.Suggested approach:
field-options.php/single-option.php): stop rendering a full<li>per real option. Keep the single hidden.frm_option_templaterow (still needed for the existing add-option flow), and instead emit the field's options as compact JSON - key/label/value - e.g. adata-optionsattribute on#frm_field_<id>_opts. This travels down with the field's existing payload (initial page render or thefrm_load_fieldajax batch already in place), not a new request.frmShowedFieldSettings, if a field with options hasn't had its option rows built yet, runaddFieldOption()'s clone+rekey logic once per JSON entry to populate the real rows, then flag it built so reopening the panel doesn't rebuild.Related: #3432, #3433 - same underlying pattern (real work deferred to first panel-open), different mechanism (markup weight/DOM node count here, not third-party widget boot cost there).
Once merged: a field's option rows exist in the DOM only once its settings panel is opened. Until then, only the compact JSON travels with the page - roughly 10-15x smaller than the current per-option markup by itself, on top of not building the DOM nodes at all until they're needed.