agy-superpowers 5.0.8 → 5.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/package.json +1 -1
  2. package/template/agent/rules/superpowers.md +54 -0
  3. package/template/agent/skills/frontend-developer/SKILL.md +39 -0
  4. package/template/agent/skills/frontend-developer/references/react-nextjs.md +343 -0
  5. package/template/agent/skills/frontend-developer/references/react-rules/_sections.md +46 -0
  6. package/template/agent/skills/frontend-developer/references/react-rules/_template.md +28 -0
  7. package/template/agent/skills/frontend-developer/references/react-rules/advanced-event-handler-refs.md +55 -0
  8. package/template/agent/skills/frontend-developer/references/react-rules/advanced-init-once.md +42 -0
  9. package/template/agent/skills/frontend-developer/references/react-rules/advanced-use-latest.md +39 -0
  10. package/template/agent/skills/frontend-developer/references/react-rules/async-api-routes.md +38 -0
  11. package/template/agent/skills/frontend-developer/references/react-rules/async-defer-await.md +80 -0
  12. package/template/agent/skills/frontend-developer/references/react-rules/async-dependencies.md +51 -0
  13. package/template/agent/skills/frontend-developer/references/react-rules/async-parallel.md +28 -0
  14. package/template/agent/skills/frontend-developer/references/react-rules/async-suspense-boundaries.md +99 -0
  15. package/template/agent/skills/frontend-developer/references/react-rules/bundle-barrel-imports.md +59 -0
  16. package/template/agent/skills/frontend-developer/references/react-rules/bundle-conditional.md +31 -0
  17. package/template/agent/skills/frontend-developer/references/react-rules/bundle-defer-third-party.md +49 -0
  18. package/template/agent/skills/frontend-developer/references/react-rules/bundle-dynamic-imports.md +35 -0
  19. package/template/agent/skills/frontend-developer/references/react-rules/bundle-preload.md +50 -0
  20. package/template/agent/skills/frontend-developer/references/react-rules/client-event-listeners.md +74 -0
  21. package/template/agent/skills/frontend-developer/references/react-rules/client-localstorage-schema.md +71 -0
  22. package/template/agent/skills/frontend-developer/references/react-rules/client-passive-event-listeners.md +48 -0
  23. package/template/agent/skills/frontend-developer/references/react-rules/client-swr-dedup.md +56 -0
  24. package/template/agent/skills/frontend-developer/references/react-rules/js-batch-dom-css.md +107 -0
  25. package/template/agent/skills/frontend-developer/references/react-rules/js-cache-function-results.md +80 -0
  26. package/template/agent/skills/frontend-developer/references/react-rules/js-cache-property-access.md +28 -0
  27. package/template/agent/skills/frontend-developer/references/react-rules/js-cache-storage.md +70 -0
  28. package/template/agent/skills/frontend-developer/references/react-rules/js-combine-iterations.md +32 -0
  29. package/template/agent/skills/frontend-developer/references/react-rules/js-early-exit.md +50 -0
  30. package/template/agent/skills/frontend-developer/references/react-rules/js-flatmap-filter.md +60 -0
  31. package/template/agent/skills/frontend-developer/references/react-rules/js-hoist-regexp.md +45 -0
  32. package/template/agent/skills/frontend-developer/references/react-rules/js-index-maps.md +37 -0
  33. package/template/agent/skills/frontend-developer/references/react-rules/js-length-check-first.md +49 -0
  34. package/template/agent/skills/frontend-developer/references/react-rules/js-min-max-loop.md +82 -0
  35. package/template/agent/skills/frontend-developer/references/react-rules/js-set-map-lookups.md +24 -0
  36. package/template/agent/skills/frontend-developer/references/react-rules/js-tosorted-immutable.md +57 -0
  37. package/template/agent/skills/frontend-developer/references/react-rules/rendering-activity.md +26 -0
  38. package/template/agent/skills/frontend-developer/references/react-rules/rendering-animate-svg-wrapper.md +47 -0
  39. package/template/agent/skills/frontend-developer/references/react-rules/rendering-conditional-render.md +40 -0
  40. package/template/agent/skills/frontend-developer/references/react-rules/rendering-content-visibility.md +38 -0
  41. package/template/agent/skills/frontend-developer/references/react-rules/rendering-hoist-jsx.md +46 -0
  42. package/template/agent/skills/frontend-developer/references/react-rules/rendering-hydration-no-flicker.md +82 -0
  43. package/template/agent/skills/frontend-developer/references/react-rules/rendering-hydration-suppress-warning.md +30 -0
  44. package/template/agent/skills/frontend-developer/references/react-rules/rendering-resource-hints.md +85 -0
  45. package/template/agent/skills/frontend-developer/references/react-rules/rendering-script-defer-async.md +68 -0
  46. package/template/agent/skills/frontend-developer/references/react-rules/rendering-svg-precision.md +28 -0
  47. package/template/agent/skills/frontend-developer/references/react-rules/rendering-usetransition-loading.md +75 -0
  48. package/template/agent/skills/frontend-developer/references/react-rules/rerender-defer-reads.md +39 -0
  49. package/template/agent/skills/frontend-developer/references/react-rules/rerender-dependencies.md +45 -0
  50. package/template/agent/skills/frontend-developer/references/react-rules/rerender-derived-state-no-effect.md +40 -0
  51. package/template/agent/skills/frontend-developer/references/react-rules/rerender-derived-state.md +29 -0
  52. package/template/agent/skills/frontend-developer/references/react-rules/rerender-functional-setstate.md +74 -0
  53. package/template/agent/skills/frontend-developer/references/react-rules/rerender-lazy-state-init.md +58 -0
  54. package/template/agent/skills/frontend-developer/references/react-rules/rerender-memo-with-default-value.md +38 -0
  55. package/template/agent/skills/frontend-developer/references/react-rules/rerender-memo.md +44 -0
  56. package/template/agent/skills/frontend-developer/references/react-rules/rerender-move-effect-to-event.md +45 -0
  57. package/template/agent/skills/frontend-developer/references/react-rules/rerender-no-inline-components.md +82 -0
  58. package/template/agent/skills/frontend-developer/references/react-rules/rerender-simple-expression-in-memo.md +35 -0
  59. package/template/agent/skills/frontend-developer/references/react-rules/rerender-split-combined-hooks.md +64 -0
  60. package/template/agent/skills/frontend-developer/references/react-rules/rerender-transitions.md +40 -0
  61. package/template/agent/skills/frontend-developer/references/react-rules/rerender-use-deferred-value.md +59 -0
  62. package/template/agent/skills/frontend-developer/references/react-rules/rerender-use-ref-transient-values.md +73 -0
  63. package/template/agent/skills/frontend-developer/references/react-rules/server-after-nonblocking.md +73 -0
  64. package/template/agent/skills/frontend-developer/references/react-rules/server-auth-actions.md +96 -0
  65. package/template/agent/skills/frontend-developer/references/react-rules/server-cache-lru.md +41 -0
  66. package/template/agent/skills/frontend-developer/references/react-rules/server-cache-react.md +76 -0
  67. package/template/agent/skills/frontend-developer/references/react-rules/server-dedup-props.md +65 -0
  68. package/template/agent/skills/frontend-developer/references/react-rules/server-hoist-static-io.md +142 -0
  69. package/template/agent/skills/frontend-developer/references/react-rules/server-parallel-fetching.md +83 -0
  70. package/template/agent/skills/frontend-developer/references/react-rules/server-serialization.md +38 -0
  71. package/template/agent/skills/frontend-developer/references/svelte-sveltekit.md +220 -0
  72. package/template/agent/skills/frontend-developer/references/vanilla.md +275 -0
  73. package/template/agent/skills/frontend-developer/references/vue-nuxt.md +289 -0
  74. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/_index.md +154 -0
  75. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/animation-class-based-technique.md +254 -0
  76. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/animation-state-driven-technique.md +291 -0
  77. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-async.md +97 -0
  78. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-data-flow.md +307 -0
  79. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-fallthrough-attrs.md +174 -0
  80. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-keep-alive.md +137 -0
  81. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-slots.md +216 -0
  82. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-suspense.md +228 -0
  83. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-teleport.md +108 -0
  84. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-transition-group.md +128 -0
  85. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/component-transition.md +125 -0
  86. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/composables.md +290 -0
  87. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/directives.md +162 -0
  88. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/perf-avoid-component-abstraction-in-lists.md +159 -0
  89. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/perf-v-once-v-memo-directives.md +182 -0
  90. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/perf-virtualize-large-lists.md +187 -0
  91. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/plugins.md +166 -0
  92. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/reactivity.md +344 -0
  93. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/render-functions.md +201 -0
  94. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/sfc.md +310 -0
  95. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/state-management.md +135 -0
  96. package/template/agent/skills/frontend-developer/references/vue-rules/best-practices/updated-hook-performance.md +187 -0
  97. package/template/agent/skills/frontend-developer/references/vue-rules/router/_index.md +23 -0
  98. package/template/agent/skills/frontend-developer/references/vue-rules/router/router-beforeenter-no-param-trigger.md +167 -0
  99. package/template/agent/skills/frontend-developer/references/vue-rules/router/router-beforerouteenter-no-this.md +176 -0
  100. package/template/agent/skills/frontend-developer/references/vue-rules/router/router-guard-async-await-pattern.md +227 -0
  101. package/template/agent/skills/frontend-developer/references/vue-rules/router/router-navigation-guard-infinite-loop.md +187 -0
  102. package/template/agent/skills/frontend-developer/references/vue-rules/router/router-navigation-guard-next-deprecated.md +150 -0
  103. package/template/agent/skills/frontend-developer/references/vue-rules/router/router-param-change-no-lifecycle.md +181 -0
  104. package/template/agent/skills/frontend-developer/references/vue-rules/router/router-simple-routing-cleanup.md +209 -0
  105. package/template/agent/skills/frontend-developer/references/vue-rules/router/router-use-vue-router-for-production.md +183 -0
  106. package/template/agent/skills/frontend-developer/references/vue-rules/testing/_index.md +29 -0
  107. package/template/agent/skills/frontend-developer/references/vue-rules/testing/async-component-testing.md +163 -0
  108. package/template/agent/skills/frontend-developer/references/vue-rules/testing/teleport-testing-complexity.md +158 -0
  109. package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-async-await-flushpromises.md +175 -0
  110. package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-browser-vs-node-runners.md +208 -0
  111. package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-component-blackbox-approach.md +144 -0
  112. package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-composables-helper-wrapper.md +238 -0
  113. package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-e2e-playwright-recommended.md +242 -0
  114. package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-no-snapshot-only.md +197 -0
  115. package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-pinia-store-setup.md +228 -0
  116. package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-suspense-async-components.md +229 -0
  117. package/template/agent/skills/frontend-developer/references/vue-rules/testing/testing-vitest-recommended-for-vue.md +204 -0
  118. package/template/agent/skills/mobile-developer/SKILL.md +52 -0
  119. package/template/agent/skills/mobile-developer/references/android-native.md +396 -0
  120. package/template/agent/skills/mobile-developer/references/android-rules/android-accessibility.md +36 -0
  121. package/template/agent/skills/mobile-developer/references/android-rules/android-architecture.md +52 -0
  122. package/template/agent/skills/mobile-developer/references/android-rules/android-coroutines.md +139 -0
  123. package/template/agent/skills/mobile-developer/references/android-rules/android-data-layer.md +51 -0
  124. package/template/agent/skills/mobile-developer/references/android-rules/android-emulator-skill.md +108 -0
  125. package/template/agent/skills/mobile-developer/references/android-rules/android-gradle-logic.md +126 -0
  126. package/template/agent/skills/mobile-developer/references/android-rules/android-retrofit.md +142 -0
  127. package/template/agent/skills/mobile-developer/references/android-rules/android-testing.md +102 -0
  128. package/template/agent/skills/mobile-developer/references/android-rules/android-viewmodel.md +43 -0
  129. package/template/agent/skills/mobile-developer/references/android-rules/coil-compose.md +74 -0
  130. package/template/agent/skills/mobile-developer/references/android-rules/compose-navigation.md +422 -0
  131. package/template/agent/skills/mobile-developer/references/android-rules/compose-performance-audit.md +199 -0
  132. package/template/agent/skills/mobile-developer/references/android-rules/compose-ui.md +49 -0
  133. package/template/agent/skills/mobile-developer/references/android-rules/gradle-build-performance.md +346 -0
  134. package/template/agent/skills/mobile-developer/references/android-rules/kotlin-concurrency-expert.md +169 -0
  135. package/template/agent/skills/mobile-developer/references/android-rules/rxjava-to-coroutines-migration.md +101 -0
  136. package/template/agent/skills/mobile-developer/references/android-rules/xml-to-compose-migration.md +338 -0
  137. package/template/agent/skills/mobile-developer/references/flutter-rules/dart-best-practices.md +52 -0
  138. package/template/agent/skills/mobile-developer/references/flutter-rules/dart-checks-migration.md +134 -0
  139. package/template/agent/skills/mobile-developer/references/flutter-rules/dart-cli-app-best-practices.md +123 -0
  140. package/template/agent/skills/mobile-developer/references/flutter-rules/dart-doc-validation.md +45 -0
  141. package/template/agent/skills/mobile-developer/references/flutter-rules/dart-matcher-best-practices.md +106 -0
  142. package/template/agent/skills/mobile-developer/references/flutter-rules/dart-modern-features.md +241 -0
  143. package/template/agent/skills/mobile-developer/references/flutter-rules/dart-package-maintenance.md +75 -0
  144. package/template/agent/skills/mobile-developer/references/flutter-rules/dart-test-fundamentals.md +124 -0
  145. package/template/agent/skills/mobile-developer/references/flutter.md +291 -0
  146. package/template/agent/skills/mobile-developer/references/ios-native.md +358 -0
  147. package/template/agent/skills/mobile-developer/references/ios-rules/accessibility-patterns.md +215 -0
  148. package/template/agent/skills/mobile-developer/references/ios-rules/animation-advanced.md +403 -0
  149. package/template/agent/skills/mobile-developer/references/ios-rules/animation-basics.md +284 -0
  150. package/template/agent/skills/mobile-developer/references/ios-rules/animation-transitions.md +326 -0
  151. package/template/agent/skills/mobile-developer/references/ios-rules/charts-accessibility.md +135 -0
  152. package/template/agent/skills/mobile-developer/references/ios-rules/charts.md +602 -0
  153. package/template/agent/skills/mobile-developer/references/ios-rules/image-optimization.md +203 -0
  154. package/template/agent/skills/mobile-developer/references/ios-rules/latest-apis.md +464 -0
  155. package/template/agent/skills/mobile-developer/references/ios-rules/layout-best-practices.md +266 -0
  156. package/template/agent/skills/mobile-developer/references/ios-rules/liquid-glass.md +416 -0
  157. package/template/agent/skills/mobile-developer/references/ios-rules/list-patterns.md +394 -0
  158. package/template/agent/skills/mobile-developer/references/ios-rules/macos-scenes.md +318 -0
  159. package/template/agent/skills/mobile-developer/references/ios-rules/macos-views.md +357 -0
  160. package/template/agent/skills/mobile-developer/references/ios-rules/macos-window-styling.md +303 -0
  161. package/template/agent/skills/mobile-developer/references/ios-rules/performance-patterns.md +403 -0
  162. package/template/agent/skills/mobile-developer/references/ios-rules/scroll-patterns.md +293 -0
  163. package/template/agent/skills/mobile-developer/references/ios-rules/sheet-navigation-patterns.md +363 -0
  164. package/template/agent/skills/mobile-developer/references/ios-rules/state-management.md +417 -0
  165. package/template/agent/skills/mobile-developer/references/ios-rules/view-structure.md +389 -0
  166. package/template/agent/skills/mobile-developer/references/react-native-rules/_sections.md +86 -0
  167. package/template/agent/skills/mobile-developer/references/react-native-rules/_template.md +28 -0
  168. package/template/agent/skills/mobile-developer/references/react-native-rules/animation-derived-value.md +53 -0
  169. package/template/agent/skills/mobile-developer/references/react-native-rules/animation-gesture-detector-press.md +95 -0
  170. package/template/agent/skills/mobile-developer/references/react-native-rules/animation-gpu-properties.md +65 -0
  171. package/template/agent/skills/mobile-developer/references/react-native-rules/design-system-compound-components.md +66 -0
  172. package/template/agent/skills/mobile-developer/references/react-native-rules/fonts-config-plugin.md +71 -0
  173. package/template/agent/skills/mobile-developer/references/react-native-rules/imports-design-system-folder.md +68 -0
  174. package/template/agent/skills/mobile-developer/references/react-native-rules/js-hoist-intl.md +61 -0
  175. package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-callbacks.md +44 -0
  176. package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-function-references.md +132 -0
  177. package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-images.md +53 -0
  178. package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-inline-objects.md +97 -0
  179. package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-item-expensive.md +94 -0
  180. package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-item-memo.md +82 -0
  181. package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-item-types.md +104 -0
  182. package/template/agent/skills/mobile-developer/references/react-native-rules/list-performance-virtualize.md +67 -0
  183. package/template/agent/skills/mobile-developer/references/react-native-rules/monorepo-native-deps-in-app.md +46 -0
  184. package/template/agent/skills/mobile-developer/references/react-native-rules/monorepo-single-dependency-versions.md +63 -0
  185. package/template/agent/skills/mobile-developer/references/react-native-rules/navigation-native-navigators.md +188 -0
  186. package/template/agent/skills/mobile-developer/references/react-native-rules/react-compiler-destructure-functions.md +50 -0
  187. package/template/agent/skills/mobile-developer/references/react-native-rules/react-compiler-reanimated-shared-values.md +48 -0
  188. package/template/agent/skills/mobile-developer/references/react-native-rules/react-state-dispatcher.md +91 -0
  189. package/template/agent/skills/mobile-developer/references/react-native-rules/react-state-fallback.md +56 -0
  190. package/template/agent/skills/mobile-developer/references/react-native-rules/react-state-minimize.md +65 -0
  191. package/template/agent/skills/mobile-developer/references/react-native-rules/rendering-no-falsy-and.md +74 -0
  192. package/template/agent/skills/mobile-developer/references/react-native-rules/rendering-text-in-text-component.md +36 -0
  193. package/template/agent/skills/mobile-developer/references/react-native-rules/scroll-position-no-state.md +82 -0
  194. package/template/agent/skills/mobile-developer/references/react-native-rules/state-ground-truth.md +80 -0
  195. package/template/agent/skills/mobile-developer/references/react-native-rules/ui-expo-image.md +66 -0
  196. package/template/agent/skills/mobile-developer/references/react-native-rules/ui-image-gallery.md +104 -0
  197. package/template/agent/skills/mobile-developer/references/react-native-rules/ui-measure-views.md +78 -0
  198. package/template/agent/skills/mobile-developer/references/react-native-rules/ui-menus.md +174 -0
  199. package/template/agent/skills/mobile-developer/references/react-native-rules/ui-native-modals.md +77 -0
  200. package/template/agent/skills/mobile-developer/references/react-native-rules/ui-pressable.md +61 -0
  201. package/template/agent/skills/mobile-developer/references/react-native-rules/ui-safe-area-scroll.md +65 -0
  202. package/template/agent/skills/mobile-developer/references/react-native-rules/ui-scrollview-content-inset.md +45 -0
  203. package/template/agent/skills/mobile-developer/references/react-native-rules/ui-styling.md +87 -0
  204. package/template/agent/skills/mobile-developer/references/react-native.md +345 -0
@@ -0,0 +1,182 @@
1
+ ---
2
+ title: Use v-once and v-memo to Skip Unnecessary Updates
3
+ impact: MEDIUM
4
+ impactDescription: v-once skips all future updates for static content; v-memo conditionally memoizes subtrees
5
+ type: efficiency
6
+ tags: [vue3, performance, v-once, v-memo, optimization, directives]
7
+ ---
8
+
9
+ # Use v-once and v-memo to Skip Unnecessary Updates
10
+
11
+ **Impact: MEDIUM** - Vue re-evaluates templates on every reactive change. For content that never changes or changes infrequently, `v-once` and `v-memo` tell Vue to skip updates, reducing render work.
12
+
13
+ Use `v-once` for truly static content and `v-memo` for conditionally-static content in lists.
14
+
15
+ ## Task List
16
+
17
+ - Apply `v-once` to elements that use runtime data but never need updating
18
+ - Apply `v-memo` to list items that should only update on specific condition changes
19
+ - Verify memoized content doesn't need to respond to other state changes
20
+ - Profile with Vue DevTools to confirm update skipping
21
+
22
+ ## v-once: Render Once, Never Update
23
+
24
+ **BAD:**
25
+ ```vue
26
+ <template>
27
+ <!-- BAD: Re-evaluated on every parent re-render -->
28
+ <div class="terms-content">
29
+ <h1>Terms of Service</h1>
30
+ <p>Version: {{ termsVersion }}</p>
31
+ <div v-html="termsContent"></div>
32
+ </div>
33
+
34
+ <!-- This content NEVER changes, but Vue checks it every render -->
35
+ <footer>
36
+ <p>Copyright {{ copyrightYear }} {{ companyName }}</p>
37
+ </footer>
38
+ </template>
39
+ ```
40
+
41
+ **GOOD:**
42
+ ```vue
43
+ <template>
44
+ <!-- GOOD: Rendered once, skipped on all future updates -->
45
+ <div class="terms-content" v-once>
46
+ <h1>Terms of Service</h1>
47
+ <p>Version: {{ termsVersion }}</p>
48
+ <div v-html="termsContent"></div>
49
+ </div>
50
+
51
+ <!-- v-once tells Vue this never needs to update -->
52
+ <footer v-once>
53
+ <p>Copyright {{ copyrightYear }} {{ companyName }}</p>
54
+ </footer>
55
+ </template>
56
+
57
+ <script setup>
58
+ // These values are set once at component creation
59
+ const termsVersion = '2.1'
60
+ const termsContent = fetchedTermsHTML
61
+ const copyrightYear = 2024
62
+ const companyName = 'Acme Corp'
63
+ </script>
64
+ ```
65
+
66
+ ## v-memo: Conditional Memoization for Lists
67
+
68
+ **BAD:**
69
+ ```vue
70
+ <template>
71
+ <!-- BAD: All items re-render when selectedId changes -->
72
+ <div v-for="item in list" :key="item.id">
73
+ <div :class="{ selected: item.id === selectedId }">
74
+ <ExpensiveComponent :data="item" />
75
+ </div>
76
+ </div>
77
+ </template>
78
+ ```
79
+
80
+ **GOOD:**
81
+ ```vue
82
+ <template>
83
+ <!-- GOOD: Items only re-render when their selection state changes -->
84
+ <div
85
+ v-for="item in list"
86
+ :key="item.id"
87
+ v-memo="[item.id === selectedId]"
88
+ >
89
+ <div :class="{ selected: item.id === selectedId }">
90
+ <ExpensiveComponent :data="item" />
91
+ </div>
92
+ </div>
93
+ </template>
94
+
95
+ <script setup>
96
+ import { ref } from 'vue'
97
+
98
+ const list = ref([/* many items */])
99
+ const selectedId = ref(null)
100
+
101
+ // When selectedId changes:
102
+ // - Only the previously-selected item re-renders (selected: true -> false)
103
+ // - Only the newly-selected item re-renders (selected: false -> true)
104
+ // - All other items are SKIPPED (v-memo values unchanged)
105
+ </script>
106
+ ```
107
+
108
+ ## v-memo with Multiple Dependencies
109
+
110
+ ```vue
111
+ <template>
112
+ <!-- Re-render only when item's selection OR editing state changes -->
113
+ <div
114
+ v-for="item in items"
115
+ :key="item.id"
116
+ v-memo="[item.id === selectedId, item.id === editingId]"
117
+ >
118
+ <ItemCard
119
+ :item="item"
120
+ :selected="item.id === selectedId"
121
+ :editing="item.id === editingId"
122
+ />
123
+ </div>
124
+ </template>
125
+
126
+ <script setup>
127
+ const selectedId = ref(null)
128
+ const editingId = ref(null)
129
+ const items = ref([/* ... */])
130
+ </script>
131
+ ```
132
+
133
+ ## v-memo with Empty Array = v-once
134
+
135
+ ```vue
136
+ <template>
137
+ <!-- v-memo="[]" is equivalent to v-once -->
138
+ <div v-for="item in staticList" :key="item.id" v-memo="[]">
139
+ {{ item.name }}
140
+ </div>
141
+ </template>
142
+ ```
143
+
144
+ ## When NOT to Use These Directives
145
+
146
+ ```vue
147
+ <template>
148
+ <!-- DON'T: Content that DOES need to update -->
149
+ <div v-once>
150
+ <span>Count: {{ count }}</span> <!-- count won't update! -->
151
+ </div>
152
+
153
+ <!-- DON'T: When child components have their own reactive state -->
154
+ <div v-memo="[selected]">
155
+ <InputField v-model="item.name" /> <!-- v-model won't work properly -->
156
+ </div>
157
+
158
+ <!-- DON'T: When the memoization benefit is minimal -->
159
+ <span v-once>{{ simpleText }}</span> <!-- Overhead not worth it -->
160
+ </template>
161
+ ```
162
+
163
+ ## Performance Comparison
164
+
165
+ | Scenario | Without Directive | With v-once/v-memo |
166
+ |----------|-------------------|-------------------|
167
+ | Static header, parent re-renders 100x | Re-evaluated 100x | Evaluated 1x |
168
+ | 1000 items, selection changes | 1000 items re-render | 2 items re-render |
169
+ | Complex child component | Full re-render | Skipped if memoized |
170
+
171
+ ## Debugging Memoized Components
172
+
173
+ ```vue
174
+ <script setup>
175
+ import { onUpdated } from 'vue'
176
+
177
+ // This won't fire if v-memo prevents update
178
+ onUpdated(() => {
179
+ console.log('Component updated')
180
+ })
181
+ </script>
182
+ ```
@@ -0,0 +1,187 @@
1
+ ---
2
+ title: Virtualize Large Lists to Avoid DOM Overload
3
+ impact: HIGH
4
+ impactDescription: Rendering thousands of list items creates excessive DOM nodes, causing slow renders and high memory usage
5
+ type: efficiency
6
+ tags: [vue3, performance, virtual-list, large-data, dom, optimization]
7
+ ---
8
+
9
+ # Virtualize Large Lists to Avoid DOM Overload
10
+
11
+ **Impact: HIGH** - Rendering all items in a large list (hundreds or thousands) creates massive amounts of DOM nodes. Each node consumes memory, slows down initial render, and makes updates expensive. List virtualization only renders visible items, dramatically improving performance.
12
+
13
+ Use a virtualization library when dealing with lists that could exceed 50-100 items, especially if items have complex content.
14
+
15
+ ## Task List
16
+
17
+ - Identify lists that render more than 50-100 items
18
+ - Install a virtualization library (vue-virtual-scroller, @tanstack/vue-virtual)
19
+ - Replace standard `v-for` with virtualized component
20
+ - Ensure list items have consistent or estimable heights
21
+ - Test with realistic data volumes during development
22
+
23
+ ## Recommended Libraries
24
+
25
+ | Library | Best For | Notes |
26
+ |---------|----------|-------|
27
+ | `vue-virtual-scroller` | General use, easy setup | Most popular, good defaults |
28
+ | `@tanstack/vue-virtual` | Complex layouts, headless | Framework-agnostic, flexible |
29
+ | `vue-virtual-scroll-grid` | Grid layouts | 2D virtualization |
30
+ | `vueuc/VVirtualList` | Naive UI projects | Part of Naive UI ecosystem |
31
+
32
+ **BAD:**
33
+ ```vue
34
+ <template>
35
+ <!-- BAD: Renders ALL 10,000 items immediately -->
36
+ <div class="user-list">
37
+ <UserCard
38
+ v-for="user in users"
39
+ :key="user.id"
40
+ :user="user"
41
+ />
42
+ </div>
43
+ </template>
44
+
45
+ <script setup>
46
+ import { ref, onMounted } from 'vue'
47
+ import UserCard from './UserCard.vue'
48
+
49
+ const users = ref([])
50
+
51
+ onMounted(async () => {
52
+ // 10,000 DOM nodes created, browser struggles
53
+ users.value = await fetchAllUsers()
54
+ })
55
+ </script>
56
+ ```
57
+
58
+ **GOOD:**
59
+ ```vue
60
+ <template>
61
+ <!-- GOOD: Only renders ~20 visible items at a time -->
62
+ <RecycleScroller
63
+ class="user-list"
64
+ :items="users"
65
+ :item-size="80"
66
+ key-field="id"
67
+ v-slot="{ item }"
68
+ >
69
+ <UserCard :user="item" />
70
+ </RecycleScroller>
71
+ </template>
72
+
73
+ <script setup>
74
+ import { ref, onMounted } from 'vue'
75
+ import { RecycleScroller } from 'vue-virtual-scroller'
76
+ import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
77
+ import UserCard from './UserCard.vue'
78
+
79
+ const users = ref([])
80
+
81
+ onMounted(async () => {
82
+ // 10,000 items in memory, but only ~20 DOM nodes
83
+ users.value = await fetchAllUsers()
84
+ })
85
+ </script>
86
+
87
+ <style scoped>
88
+ .user-list {
89
+ height: 600px; /* Container must have fixed height */
90
+ }
91
+ </style>
92
+ ```
93
+
94
+ ## Using @tanstack/vue-virtual
95
+
96
+ ```vue
97
+ <template>
98
+ <div ref="parentRef" class="list-container">
99
+ <div
100
+ :style="{
101
+ height: `${rowVirtualizer.getTotalSize()}px`,
102
+ position: 'relative'
103
+ }"
104
+ >
105
+ <div
106
+ v-for="virtualRow in rowVirtualizer.getVirtualItems()"
107
+ :key="virtualRow.key"
108
+ :style="{
109
+ position: 'absolute',
110
+ top: 0,
111
+ left: 0,
112
+ width: '100%',
113
+ height: `${virtualRow.size}px`,
114
+ transform: `translateY(${virtualRow.start}px)`
115
+ }"
116
+ >
117
+ <UserCard :user="users[virtualRow.index]" />
118
+ </div>
119
+ </div>
120
+ </div>
121
+ </template>
122
+
123
+ <script setup>
124
+ import { ref } from 'vue'
125
+ import { useVirtualizer } from '@tanstack/vue-virtual'
126
+
127
+ const users = ref([/* 10,000 users */])
128
+ const parentRef = ref(null)
129
+
130
+ const rowVirtualizer = useVirtualizer({
131
+ count: users.value.length,
132
+ getScrollElement: () => parentRef.value,
133
+ estimateSize: () => 80, // Estimated row height
134
+ overscan: 5 // Render 5 extra items above/below viewport
135
+ })
136
+ </script>
137
+
138
+ <style scoped>
139
+ .list-container {
140
+ height: 600px;
141
+ overflow: auto;
142
+ }
143
+ </style>
144
+ ```
145
+
146
+ ## Dynamic Heights with vue-virtual-scroller
147
+
148
+ ```vue
149
+ <template>
150
+ <!-- For variable height items, use DynamicScroller -->
151
+ <DynamicScroller
152
+ :items="messages"
153
+ :min-item-size="54"
154
+ key-field="id"
155
+ >
156
+ <template #default="{ item, index, active }">
157
+ <DynamicScrollerItem
158
+ :item="item"
159
+ :active="active"
160
+ :data-index="index"
161
+ >
162
+ <ChatMessage :message="item" />
163
+ </DynamicScrollerItem>
164
+ </template>
165
+ </DynamicScroller>
166
+ </template>
167
+
168
+ <script setup>
169
+ import { DynamicScroller, DynamicScrollerItem } from 'vue-virtual-scroller'
170
+ </script>
171
+ ```
172
+
173
+ ## Performance Comparison
174
+
175
+ | Approach | 100 Items | 1,000 Items | 10,000 Items |
176
+ |----------|-----------|-------------|--------------|
177
+ | Regular v-for | ~100 DOM nodes | ~1,000 DOM nodes | ~10,000 DOM nodes |
178
+ | Virtualized | ~20 DOM nodes | ~20 DOM nodes | ~20 DOM nodes |
179
+ | Initial render | Fast | Slow | Very slow / crashes |
180
+ | Virtualized render | Fast | Fast | Fast |
181
+
182
+ ## When NOT to Virtualize
183
+
184
+ - Lists under 50 items with simple content
185
+ - Lists where all items must be accessible to screen readers simultaneously
186
+ - Print layouts where all content must render
187
+ - SEO-critical content that must be in initial HTML
@@ -0,0 +1,166 @@
1
+ ---
2
+ title: Vue Plugin Best Practices
3
+ impact: MEDIUM
4
+ impactDescription: Incorrect plugin structure or injection key strategy causes install failures, collisions, and unsafe APIs
5
+ type: best-practice
6
+ tags: [vue3, plugins, provide-inject, typescript, dependency-injection]
7
+ ---
8
+
9
+ # Vue Plugin Best Practices
10
+
11
+ **Impact: MEDIUM** - Vue plugins should follow the `app.use()` contract, expose explicit capabilities, and use collision-safe injection keys. This keeps plugin setup predictable and composable across large apps.
12
+
13
+ ## Task List
14
+
15
+ - Export plugins as an object with `install()` or as an install function
16
+ - Use the `app` instance in `install()` to register components/directives/provides
17
+ - Type plugin APIs with `Plugin` (and options tuple types when needed)
18
+ - Use symbol keys (prefer `InjectionKey<T>`) for `provide/inject` in plugins
19
+ - Add a small typed composable wrapper for required injections to fail fast
20
+
21
+ ## Structure Plugins for `app.use()`
22
+
23
+ A Vue plugin must be either:
24
+ - An object with `install(app, options?)`
25
+ - A function with the same signature
26
+
27
+ **BAD:**
28
+ ```ts
29
+ const notAPlugin = {
30
+ doSomething() {}
31
+ }
32
+
33
+ app.use(notAPlugin)
34
+ ```
35
+
36
+ **GOOD:**
37
+ ```ts
38
+ import type { App } from 'vue'
39
+
40
+ interface PluginOptions {
41
+ prefix?: string
42
+ debug?: boolean
43
+ }
44
+
45
+ const myPlugin = {
46
+ install(app: App, options: PluginOptions = {}) {
47
+ const { prefix = 'my', debug = false } = options
48
+
49
+ if (debug) {
50
+ console.log('Installing myPlugin with prefix:', prefix)
51
+ }
52
+
53
+ app.provide('myPlugin', { prefix })
54
+ }
55
+ }
56
+
57
+ app.use(myPlugin, { prefix: 'custom', debug: true })
58
+ ```
59
+
60
+ **GOOD:**
61
+ ```ts
62
+ import type { App } from 'vue'
63
+
64
+ function simplePlugin(app: App, options?: { message: string }) {
65
+ app.config.globalProperties.$greet = () => options?.message ?? 'Hello!'
66
+ }
67
+
68
+ app.use(simplePlugin, { message: 'Welcome!' })
69
+ ```
70
+
71
+ ## Register Capabilities Explicitly in `install()`
72
+
73
+ Inside `install()`, wire behavior through Vue application APIs:
74
+ - `app.component()` for global components
75
+ - `app.directive()` for global directives
76
+ - `app.provide()` for injectable services and config
77
+ - `app.config.globalProperties` for optional global helpers (sparingly)
78
+
79
+ **BAD:**
80
+ ```ts
81
+ const uselessPlugin = {
82
+ install(app, options) {
83
+ const service = createService(options)
84
+ }
85
+ }
86
+ ```
87
+
88
+ **GOOD:**
89
+ ```ts
90
+ const usefulPlugin = {
91
+ install(app, options) {
92
+ const service = createService(options)
93
+ app.provide(serviceKey, service)
94
+ }
95
+ }
96
+ ```
97
+
98
+ ## Type Plugin Contracts
99
+
100
+ Use Vue's `Plugin` type to keep install signatures and options type-safe.
101
+
102
+ ```ts
103
+ import type { App, Plugin } from 'vue'
104
+
105
+ interface MyOptions {
106
+ apiKey: string
107
+ }
108
+
109
+ const myPlugin: Plugin<[MyOptions]> = {
110
+ install(app: App, options: MyOptions) {
111
+ app.provide(apiKeyKey, options.apiKey)
112
+ }
113
+ }
114
+ ```
115
+
116
+ ## Use Symbol Injection Keys in Plugins
117
+
118
+ String keys can collide (`'http'`, `'config'`, `'i18n'`). Use symbol keys with `InjectionKey<T>` so injections are unique and typed.
119
+
120
+ **BAD:**
121
+ ```ts
122
+ export default {
123
+ install(app) {
124
+ app.provide('http', axios)
125
+ app.provide('config', appConfig)
126
+ }
127
+ }
128
+ ```
129
+
130
+ **GOOD:**
131
+ ```ts
132
+ import type { InjectionKey } from 'vue'
133
+ import type { AxiosInstance } from 'axios'
134
+
135
+ interface AppConfig {
136
+ apiUrl: string
137
+ timeout: number
138
+ }
139
+
140
+ export const httpKey: InjectionKey<AxiosInstance> = Symbol('http')
141
+ export const configKey: InjectionKey<AppConfig> = Symbol('appConfig')
142
+
143
+ export default {
144
+ install(app) {
145
+ app.provide(httpKey, axios)
146
+ app.provide(configKey, { apiUrl: '/api', timeout: 5000 })
147
+ }
148
+ }
149
+ ```
150
+
151
+ ## Provide Required Injection Helpers
152
+
153
+ Wrap required injections in composables that throw clear setup errors.
154
+
155
+ ```ts
156
+ import { inject } from 'vue'
157
+ import { authKey, type AuthService } from '@/injection-keys'
158
+
159
+ export function useAuth(): AuthService {
160
+ const auth = inject(authKey)
161
+ if (!auth) {
162
+ throw new Error('Auth plugin not installed. Did you forget app.use(authPlugin)?')
163
+ }
164
+ return auth
165
+ }
166
+ ```