fix: better docs and debuggability
This commit is contained in:
parent
ba02269e5a
commit
49cadcfeec
|
@ -68,9 +68,9 @@ up with breaking changes in Svelte or the tools in the Svelte ecosystem (e.g. Ro
|
|||
|
||||
The framework mostly gets the job done, but I took a few shortcuts since we didn't need all the possible bells and whistles. Here is a brief description.
|
||||
|
||||
First, all of the DOM nodes and update functions for those nodes are kept in-memory via a WeakMap pointing at the `state`. There's one `state` per instance of the `Picker.js` Svelte-esque component. So when the instance is GC'ed, everything related to the DOM and update functions should be GC'ed.
|
||||
First, all the DOM nodes and update functions for those nodes are kept in-memory via a `WeakMap` where the key is the `state`. There's one `state` per instance of the `Picker.js` Svelte-esque component. So when the instance is GC'ed, everything related to the DOM and update functions should be GC'ed. (The exception is the global `parseCache`, which only contains the clone-able `template` and bindings for each unique `tokens` array, which is unique per `html` tag template literal. These templates/bindings never changes per component instance, so it makes sense to just parse once and cache them forever, in case the `<emoji-picker>` element itself is constantly unmounted and re-created.)
|
||||
|
||||
Second, I took a shortcut, which is that all DOM nodes and update functions are keyed off of 1) the unique tokens for the tag template literal plus 2) a unique `key` from the `map` function (if it exists). These are only GC'ed when the whole `state` is GC'ed. So in the worst case, every DOM node for every emoji in the picker is kept in memory (e.g. if you click on every tab button), but this seemed like a reasonable tradeoff for simplicity, plus the perf improvement of avoiding re-rendering the same node when it's unchanged (this is especially important if the reactivity system is kind of chatty, and is constantly setting the same arrays over and over – the framework just notices that all the `children` are the same objects and doesn't re-render). This also works because the `map`ed DOM nodes are not highly dynamic.
|
||||
Second, I took a shortcut, which is that all unique (non-`<template>`) DOM nodes and update functions are keyed off of 1) the unique tokens for the tag template literal plus 2) a unique `key` from the `map` function (if it exists). These are only GC'ed when the whole `state` is GC'ed. So in the worst case, every DOM node for every emoji in the picker is kept in memory (e.g. if you click on every tab button), but this seemed like a reasonable tradeoff for simplicity, plus the perf improvement of avoiding re-rendering the same node when it's unchanged (this is especially important if the reactivity system is kind of chatty, and is constantly setting the same arrays over and over – the framework just notices that all the `children` are the same objects and doesn't re-render). This also works because the `map`ed DOM nodes are not highly dynamic.
|
||||
|
||||
Third, all refs and event listeners are only bound once – this just happens to work since most of the event listeners are hoisted (delegated) anyway.
|
||||
|
||||
|
|
|
@ -4,6 +4,13 @@ const parseCache = new WeakMap()
|
|||
const domInstancesCache = new WeakMap()
|
||||
const unkeyedSymbol = Symbol('un-keyed')
|
||||
|
||||
// for debugging
|
||||
/* istanbul ignore else */
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
window.parseCache = parseCache
|
||||
window.domInstancesCache = domInstancesCache
|
||||
}
|
||||
|
||||
// Not supported in Safari <=13
|
||||
const hasReplaceChildren = 'replaceChildren' in Element.prototype
|
||||
function replaceChildren (parentNode, newChildren) {
|
||||
|
|
Loading…
Reference in New Issue