mirror of
https://github.com/jaandrle/deka-dom-el
synced 2025-07-29 07:00:16 +02:00
🔤
This commit is contained in:
@@ -25,19 +25,32 @@ export function page({ pkg, info }){
|
||||
el(h3, t`Debugging signals`),
|
||||
el("p").append(T`
|
||||
Signals are reactive primitives that update the UI when their values change. When debugging signals,
|
||||
you need to track their values, understand their dependencies, and identify why updates are or aren't happening.
|
||||
you need to track their values, understand their dependencies, and identify why updates are or aren’t
|
||||
happening.
|
||||
`),
|
||||
|
||||
el("h4", t`Inspecting signal values`),
|
||||
el("p").append(T`
|
||||
The simplest way to debug a signal is to log its current value by calling the get method:
|
||||
The simplest way to debug a signal is to log its current value by calling the get or valueOf method:
|
||||
`),
|
||||
el(code, { content: `
|
||||
const signal = S(0);
|
||||
console.log('Current value:', signal.get());
|
||||
// without triggering updates
|
||||
console.log('Current value:', signal.valueOf());
|
||||
`, page_id }),
|
||||
el("div", { className: "warning" }).append(
|
||||
el("p").append(T`
|
||||
${el("code", "signal.get")} is OK, but in some situations may lead to unexpected results:
|
||||
`),
|
||||
el(code, { content: `
|
||||
const signal = S(0);
|
||||
const derived = S(()=> {
|
||||
console.log('Current value:', signal.get());
|
||||
// ↑ in rare cases this will register unwanted dependency
|
||||
// but typically this is fine ↓
|
||||
return signal.get() + 1;
|
||||
});
|
||||
` })
|
||||
),
|
||||
el("p").append(T`
|
||||
You can also monitor signal changes by adding a listener:
|
||||
`),
|
||||
@@ -58,83 +71,7 @@ export function page({ pkg, info }){
|
||||
),
|
||||
el(example, { src: fileURL("./components/examples/debugging/consoleLog.js"), page_id }),
|
||||
|
||||
el(h3, t`Common signal debugging issues`),
|
||||
el("h4", t`Signal updates not triggering UI changes`),
|
||||
el("p", t`If signal updates aren’t reflected in the UI, check:`),
|
||||
el("ul").append(
|
||||
el("li", t`That you’re using signal.set() to update the value, not modifying objects/arrays directly`),
|
||||
el("li", t`For mutable objects, ensure you’re using actions or making proper copies before updating`),
|
||||
el("li", t`That the signal is actually connected to the DOM element (check your S.el or attribute binding code)`)
|
||||
),
|
||||
el(code, { src: fileURL("./components/examples/debugging/mutations.js"), page_id }),
|
||||
|
||||
el("h4", t`Memory leaks with signal listeners`),
|
||||
el("p").append(T`
|
||||
Signal listeners can cause memory leaks if not properly cleaned up. Always use AbortSignal
|
||||
to cancel listeners.
|
||||
`),
|
||||
|
||||
el("h4", t`Performance issues with frequently updating signals`),
|
||||
el("p", t`If you notice performance issues with signals that update very frequently:`),
|
||||
el("ul").append(
|
||||
el("li", t`Consider debouncing or throttling signal updates`),
|
||||
el("li", t`Make sure derived signals don’t perform expensive calculations unnecessarily`),
|
||||
el("li", t`Keep signal computations focused and minimal`)
|
||||
),
|
||||
el(code, { src: fileURL("./components/examples/debugging/debouncing.js"), page_id }),
|
||||
|
||||
el(h3, t`Browser DevTools tips for dd<el>`),
|
||||
el("p").append(T`
|
||||
When debugging in the browser, dd<el> provides several helpful DevTools-friendly features:
|
||||
`),
|
||||
|
||||
el("h4", t`Identifying components in the DOM`),
|
||||
el("p").append(T`
|
||||
dd<el> marks components in the DOM with special comment nodes to help you identify component boundaries.
|
||||
Components created with ${el("code", "el(ComponentFunction)")} are marked with comment nodes
|
||||
${el("code", `<!--<dde:mark type="component" name="MyComponent" host="parentElement"/>-->`)} and
|
||||
includes:
|
||||
`),
|
||||
el("ul").append(
|
||||
el("li", t`type - Identifies the type of marker ("component", "reactive", or "later")`),
|
||||
el("li", t`name - The name of the component function`),
|
||||
el("li", t`host - Indicates whether the host is "this" (for DocumentFragments) or "parentElement"`),
|
||||
),
|
||||
|
||||
el("h4", t`Finding reactive elements in the DOM`),
|
||||
el("p").append(T`
|
||||
When using ${el("code", "S.el()")}, dd<el> creates reactive elements in the DOM
|
||||
that are automatically updated when signal values change. These elements are wrapped in special
|
||||
comment nodes for debugging (to be true they are also used internally, so please do not edit them by hand):
|
||||
`),
|
||||
el(code, { src: fileURL("./components/examples/debugging/dom-reactive-mark.html"), page_id }),
|
||||
el("p").append(T`
|
||||
This is particularly useful when debugging why a reactive section isn’t updating as expected.
|
||||
You can inspect the elements between the comment nodes to see their current state and the
|
||||
signal connections through \`__dde_reactive\` of the host element.
|
||||
`),
|
||||
|
||||
el("h4", t`DOM inspection properties`),
|
||||
el("p").append(T`
|
||||
Elements created with the dd<el> library have special properties to aid in debugging:
|
||||
`),
|
||||
el("p").append(T`
|
||||
${el("code", "<element>.__dde_reactive")} - An array property on DOM elements that tracks signal-to-element
|
||||
relationships. This allows you to quickly identify which elements are reactive and what signals they’re
|
||||
bound to. Each entry in the array contains:
|
||||
`),
|
||||
el("ul").append(
|
||||
el("li", t`A pair of signal and listener function: [signal, listener]`),
|
||||
el("li", t`Additional context information about the element or attribute`),
|
||||
el("li", t`Automatically managed by signal.el(), signal.observedAttributes(), and processReactiveAttribute()`)
|
||||
),
|
||||
el("p").append(T`
|
||||
These properties make it easier to understand the reactive structure of your application when inspecting
|
||||
elements.
|
||||
`),
|
||||
el(example, { src: fileURL("./components/examples/signals/debugging-dom.js"), page_id }),
|
||||
|
||||
el("h4", t`Examining signal connections`),
|
||||
el("h4", t`Examining signal via DevTools`),
|
||||
el("p").append(T`
|
||||
${el("code", "<signal>.__dde_signal")} - A Symbol property used to identify and store the internal state of
|
||||
signal objects. It contains the following information:
|
||||
@@ -148,22 +85,8 @@ export function page({ pkg, info }){
|
||||
el("li", t`readonly: Boolean flag indicating if the signal is read-only`)
|
||||
),
|
||||
el("p").append(T`
|
||||
…to determine the current value of the signal, call ${el("code", "signal.valueOf()")}.
|
||||
`),
|
||||
el("p").append(T`
|
||||
You can inspect (host) element relationships and bindings with signals in the DevTools console using
|
||||
${el("code", "$0.__dde_reactive")} (for currently selected element). In the console you will see a list of
|
||||
${el("code", `[ [ signal, listener ], element, property ]`)}, where:
|
||||
`),
|
||||
el("ul").append(
|
||||
el("li", t`signal — the signal triggering the changes`),
|
||||
el("li", t`listener — the listener function (this is an internal function for dd<el>)`),
|
||||
el("li", t`element — the DOM element that is bound to the signal`),
|
||||
el("li", t`property — the attribute or property name which is changing based on the signal`),
|
||||
),
|
||||
el("p").append(T`
|
||||
…the structure of \`__dde_reactive\` utilizes the browser’s behavior of packing the first field,
|
||||
so you can see the element and property that changes in the console right away.
|
||||
…to determine the current value of the signal, call ${el("code", "signal.valueOf()")}. Don’t hesitate to
|
||||
use the debugger to inspect the signal object.
|
||||
`),
|
||||
|
||||
el("h4", t`Debugging with breakpoints`),
|
||||
@@ -185,5 +108,110 @@ export function page({ pkg, info }){
|
||||
`)
|
||||
),
|
||||
|
||||
el(h3, t`Common signal debugging issues`),
|
||||
el("h4", t`Signal updates not triggering UI changes`),
|
||||
el("p", t`If signal updates aren’t reflected in the UI, check:`),
|
||||
el("ul").append(
|
||||
el("li", t`That you’re using signal.set() to update the value, not modifying objects/arrays directly`),
|
||||
el("li", t`For mutable objects, ensure you’re using actions or making proper copies before updating`),
|
||||
el("li", t`That the signal is actually connected to the DOM element (check your S.el or attribute binding code)`)
|
||||
),
|
||||
el(code, { src: fileURL("./components/examples/debugging/mutations.js"), page_id }),
|
||||
|
||||
el("h4", t`Memory leaks with signal listeners`),
|
||||
el("p").append(T`
|
||||
Signal listeners can cause memory leaks if not properly cleaned up. Always use AbortSignal
|
||||
to cancel listeners when they are used ouside the dd<el> knowledge (el, assign, S.el, … auto cleanup
|
||||
unnecessarily signals automatically).
|
||||
`),
|
||||
|
||||
el("h4", t`Performance issues with frequently updating signals`),
|
||||
el("p", t`If you notice performance issues with signals that update very frequently:`),
|
||||
el("ul").append(
|
||||
el("li", t`Consider debouncing or throttling signal updates`),
|
||||
el("li", t`Make sure derived signals don’t perform expensive calculations unnecessarily`),
|
||||
el("li", t`Keep signal computations focused and minimal`)
|
||||
),
|
||||
el(code, { src: fileURL("./components/examples/debugging/debouncing.js"), page_id }),
|
||||
|
||||
el(h3, t`Browser DevTools tips for components and reactivity`),
|
||||
el("p").append(T`
|
||||
When debugging in the browser, dd<el> provides several helpful DevTools-friendly features:
|
||||
`),
|
||||
|
||||
el("h4", t`Finding reactive elements in the DOM`),
|
||||
el("p").append(T`
|
||||
When using ${el("code", "S.el()")}, dd<el> creates reactive elements in the DOM
|
||||
that are automatically updated when signal values change. These elements are wrapped in special
|
||||
comment nodes for debugging (to be true they are also used internally, so please do not edit them by hand):
|
||||
`),
|
||||
el(code, { src: fileURL("./components/examples/debugging/dom-reactive-mark.html"), page_id }),
|
||||
el("p").append(T`
|
||||
This is particularly useful when debugging why a reactive section isn’t updating as expected.
|
||||
You can inspect the elements between the comment nodes to see their current state and the
|
||||
signal connections through \`__dde_reactive\` of the host element.
|
||||
`),
|
||||
|
||||
el("h4", t`Identifying components in the DOM`),
|
||||
el("p").append(T`
|
||||
dd<el> marks components in the DOM with special comment nodes to help you identify component boundaries.
|
||||
Components created with ${el("code", "el(MyComponent)")} are marked with comment nodes
|
||||
${el("code", `<!--<dde:mark type="component" name="MyComponent" host="parentElement"/>-->`)} and
|
||||
includes:
|
||||
`),
|
||||
el("ul").append(
|
||||
el("li", t`type - Identifies the type of marker ("component", "reactive", …)`),
|
||||
el("li", t`name - The name of the component function`),
|
||||
el("li", t`host - Indicates whether the host is "this" (for DocumentFragments) or "parentElement"`),
|
||||
),
|
||||
|
||||
el("h4", t`Identifying reactive elements in the DOM`),
|
||||
el("p").append(T`
|
||||
You can inspect (host) element relationships and bindings with signals in the DevTools console using
|
||||
${el("code", "$0.__dde_reactive")} (for currently selected element). In the console you will see a list of
|
||||
${el("code", `[ [ signal, listener ], element, property ]`)}, where:
|
||||
`),
|
||||
el("ul").append(
|
||||
el("li", t`signal — the signal triggering the changes`),
|
||||
el("li", t`listener — the listener function (this is an internal function for dd<el>)`),
|
||||
el("li", t`element — the DOM element that is bound to the signal`),
|
||||
el("li", t`property — the attribute or property name which is changing based on the signal`),
|
||||
),
|
||||
el("p").append(T`
|
||||
…the structure of \`__dde_reactive\` utilizes the browser’s behavior of packing the first field,
|
||||
so you can see the element and property that changes in the console right away. These properties make it
|
||||
easier to understand the reactive structure of your application when inspecting elements.
|
||||
`),
|
||||
el(example, { src: fileURL("./components/examples/signals/debugging-dom.js"), page_id }),
|
||||
|
||||
el("p", { className: "note" }).append(T`
|
||||
${el("code", "<element>.__dde_reactive")} - An array property on DOM elements that tracks signal-to-element
|
||||
relationships. This allows you to quickly identify which elements are reactive and what signals they’re
|
||||
bound to. Each entry in the array contains:
|
||||
`),
|
||||
|
||||
el("h4", t`Inspecting events and listeners in DevTools`),
|
||||
el("p").append(T`
|
||||
Modern browser DevTools provide built-in tools for inspecting event listeners attached to DOM elements.
|
||||
For example, in Firefox and Chrome, you can:
|
||||
`),
|
||||
el("ol").append(
|
||||
el("li", t`Select an element in the Elements/Inspector panel`),
|
||||
el("li", t`Look for the "Event Listeners" tab or section`),
|
||||
el("li", t`See all event listeners attached to the element, including those added by dd<el>`)
|
||||
),
|
||||
el("p").append(T`
|
||||
Additionally, dd<el> provides special markers in the DOM that help identify debug information.
|
||||
Look for comments with ${el("code", "dde:mark")}, ${el("code", "dde:disconnected")} and ${el("code",
|
||||
"__dde_reactive")} which indicate components, reactive regions, and other internal relationships:
|
||||
`),
|
||||
el("figure").append(
|
||||
el("img", {
|
||||
src: "./assets/devtools.png",
|
||||
alt: "Screenshot of DevTools showing usage of “event” button to inspect event listeners",
|
||||
}),
|
||||
el("figcaption", t`Firefox DevTools showing dd<el> debugging information with event listeners and reactive
|
||||
markers`)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user