ko.computed or ko.pureComputed for view models with many rarely-observed computeds?
0 reputation · 04 Aug 2021, 06:29 UTC
0 reputation · 04 Aug 2021, 06:29 UTC
I'm designing a Knockout view-model layer (Knockout 3.5.x) where a large list rendered with foreach produces many item view models, each carrying several computed values. Most of those computeds are only observed while their row is visible or bound, and the view models themselves can live for a long time.
The documented trade-off is clear in outline: ko.computed evaluates eagerly and keeps its subscriptions and cached value alive even with zero observers, while ko.pureComputed (available since 3.2) subscribes to its dependencies only while it has subscribers and goes to sleep otherwise, reevaluating on next read. Pure computeds look like the obvious fit for memory pressure, but the documentation also warns that their evaluators must not have side effects, and eager evaluation is sometimes exactly what you want when a subscription must fire regardless of UI observers.
What I'm missing is a principled rule for choosing between them at the codebase level rather than case by case.
Specifically:
ko.pureComputed and opting back into ko.computed only where eager evaluation is required a sound convention, or does the sleep/wake reevaluation behavior create subtle bugs that make the reverse default safer?ko.computed, or to restructure them as explicit subscriptions?18025 reputation · 04 Aug 2021, 08:02 UTC
ko.pureComputed and opt back into ko.computed only when you require eager evaluation or side effects that must persist independently of the UI.
In a large foreach list where item view models persist, using ko.computed will maintain an active dependency graph for every row, even if the row is off-screen or collapsed. ko.pureComputed mitigates this by allowing the evaluator to 'sleep' when the subscriber count drops to zero, significantly reducing CPU overhead.
ko.pureComputed is safer for memory pressure. The 'sleep/wake' behavior only creates bugs if your code assumes the computed is constantly running in the background to perform background tasks (like polling). If the computed is purely for data transformation for display, ko.pureComputed is ideal.ko.pureComputed. The accepted pattern is to restructure these as explicit ko.subscribe blocks or keep them as ko.computed. Pure computeds are designed to be pure functions; they may not run when you expect them to, leading to inconsistent state.ko.pureComputed depends on an eager ko.computed, the pure version will trigger the eager one only when the pure version becomes active. There are no documented pitfalls regarding missed notifications, as the eager computed will always have the latest value when the pure one wakes up.ko.pureComputed for any value that only exists to serve the view (e.g., formatted strings, visibility flags).ko.computed for logic that must update state even if the user isn't looking at that specific row.subscribe call to ensure it runs reliably when data changes.To provide a more specific recommendation, do any of your 'rarely-observed' values trigger API calls or update a global state object?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.