ginskill-init 2.7.0

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 (128) hide show
  1. package/.wrangler/cache/pages.json +4 -0
  2. package/.wrangler/cache/wrangler-account.json +6 -0
  3. package/DEVELOPMENT.md +510 -0
  4. package/README.md +104 -0
  5. package/agents/developer.md +56 -0
  6. package/agents/frontend-design.md +69 -0
  7. package/agents/mobile-reviewer.md +36 -0
  8. package/agents/review-code.md +49 -0
  9. package/agents/security-scanner.md +50 -0
  10. package/agents/tester.md +72 -0
  11. package/bin/cli.js +461 -0
  12. package/landing/ai-build-ai.png +0 -0
  13. package/landing/index.html +1495 -0
  14. package/landing/logo.png +0 -0
  15. package/package.json +37 -0
  16. package/skills/active-life-dev/SKILL.md +157 -0
  17. package/skills/active-life-dev/docs/auth.md +187 -0
  18. package/skills/active-life-dev/docs/customers.md +216 -0
  19. package/skills/active-life-dev/docs/integrations.md +209 -0
  20. package/skills/active-life-dev/docs/inventory.md +192 -0
  21. package/skills/active-life-dev/docs/modules.md +181 -0
  22. package/skills/active-life-dev/docs/orders.md +180 -0
  23. package/skills/active-life-dev/docs/patterns.md +319 -0
  24. package/skills/active-life-dev/docs/products.md +216 -0
  25. package/skills/active-life-dev/docs/schema.md +502 -0
  26. package/skills/active-life-dev/docs/setup.md +169 -0
  27. package/skills/active-life-dev/docs/vouchers.md +144 -0
  28. package/skills/ai-asset-generator/SKILL.md +247 -0
  29. package/skills/ai-asset-generator/docs/gen-image.md +274 -0
  30. package/skills/ai-asset-generator/docs/genvideo.md +341 -0
  31. package/skills/ai-asset-generator/docs/remove-background.md +19 -0
  32. package/skills/ai-asset-generator/lib/bg-remove.mjs +34 -0
  33. package/skills/ai-asset-generator/lib/env.mjs +48 -0
  34. package/skills/ai-asset-generator/lib/kie-client.mjs +100 -0
  35. package/skills/ai-build-ai/SKILL.md +127 -0
  36. package/skills/ai-build-ai/docs/agent-teams.md +293 -0
  37. package/skills/ai-build-ai/docs/checkpointing.md +161 -0
  38. package/skills/ai-build-ai/docs/create-agent.md +399 -0
  39. package/skills/ai-build-ai/docs/create-mcp.md +395 -0
  40. package/skills/ai-build-ai/docs/create-skill.md +299 -0
  41. package/skills/ai-build-ai/docs/headless-mode.md +614 -0
  42. package/skills/ai-build-ai/docs/hooks.md +578 -0
  43. package/skills/ai-build-ai/docs/memory-claude-md.md +375 -0
  44. package/skills/ai-build-ai/docs/output-styles.md +208 -0
  45. package/skills/ai-build-ai/docs/overview.md +162 -0
  46. package/skills/ai-build-ai/docs/permissions.md +391 -0
  47. package/skills/ai-build-ai/docs/plugins.md +396 -0
  48. package/skills/ai-build-ai/docs/sandbox.md +262 -0
  49. package/skills/ai-build-ai/docs/team-lead-workflow.md +648 -0
  50. package/skills/ant-design/SKILL.md +323 -0
  51. package/skills/ant-design/docs/components.md +160 -0
  52. package/skills/ant-design/docs/data-entry.md +406 -0
  53. package/skills/ant-design/docs/display.md +594 -0
  54. package/skills/ant-design/docs/feedback.md +451 -0
  55. package/skills/ant-design/docs/key-components.md +414 -0
  56. package/skills/ant-design/docs/navigation.md +310 -0
  57. package/skills/ant-design/docs/pro-components.md +543 -0
  58. package/skills/ant-design/docs/setup.md +213 -0
  59. package/skills/ant-design/docs/theme.md +265 -0
  60. package/skills/flutter-performance/SKILL.md +803 -0
  61. package/skills/flutter-performance/references/flutter-patterns.md +595 -0
  62. package/skills/icon-generator/SKILL.md +270 -0
  63. package/skills/mobile-app-review/SKILL.md +321 -0
  64. package/skills/mobile-app-review/references/apple-review.md +132 -0
  65. package/skills/mobile-app-review/references/google-play-review.md +203 -0
  66. package/skills/mongodb/SKILL.md +667 -0
  67. package/skills/mongodb/references/mongoose-patterns.md +368 -0
  68. package/skills/nestjs-architecture/SKILL.md +1086 -0
  69. package/skills/nestjs-architecture/references/advanced-patterns.md +590 -0
  70. package/skills/performance/SKILL.md +509 -0
  71. package/skills/react-fsd-architecture/SKILL.md +693 -0
  72. package/skills/react-fsd-architecture/references/fsd-patterns.md +747 -0
  73. package/skills/react-native-expo/SKILL.md +128 -0
  74. package/skills/react-native-expo/references/data-layer.md +252 -0
  75. package/skills/react-native-expo/references/design-system.md +252 -0
  76. package/skills/react-native-expo/references/navigation.md +199 -0
  77. package/skills/react-native-expo/references/performance.md +229 -0
  78. package/skills/react-native-expo/references/platform-services.md +179 -0
  79. package/skills/react-native-expo/references/state-management.md +209 -0
  80. package/skills/react-native-expo/references/ui-patterns.md +301 -0
  81. package/skills/react-query/SKILL.md +685 -0
  82. package/skills/react-query/references/query-patterns.md +365 -0
  83. package/skills/review-code/SKILL.md +374 -0
  84. package/skills/review-code/references/clean-code-principles.md +395 -0
  85. package/skills/review-code/references/frontend-patterns.md +136 -0
  86. package/skills/review-code/references/nestjs-patterns.md +184 -0
  87. package/skills/security-scanner/SKILL.md +366 -0
  88. package/skills/security-scanner/references/nestjs-security.md +260 -0
  89. package/skills/security-scanner/references/nextjs-security.md +201 -0
  90. package/skills/security-scanner/references/react-native-security.md +199 -0
  91. package/skills/traefik/SKILL.md +105 -0
  92. package/skills/traefik/docs/advanced-routing.md +186 -0
  93. package/skills/traefik/docs/auth-providers.md +137 -0
  94. package/skills/traefik/docs/cicd-devops.md +396 -0
  95. package/skills/traefik/docs/core-config.md +171 -0
  96. package/skills/traefik/docs/distributed-config.md +96 -0
  97. package/skills/traefik/docs/docker-compose.md +182 -0
  98. package/skills/traefik/docs/ha-performance.md +177 -0
  99. package/skills/traefik/docs/kubernetes.md +278 -0
  100. package/skills/traefik/docs/middleware.md +205 -0
  101. package/skills/traefik/docs/monitoring.md +357 -0
  102. package/skills/traefik/docs/security.md +391 -0
  103. package/skills/traefik/docs/tls-acme.md +155 -0
  104. package/skills/ui-ux-pro-max/SKILL.md +377 -0
  105. package/skills/ui-ux-pro-max/data/charts.csv +26 -0
  106. package/skills/ui-ux-pro-max/data/colors.csv +97 -0
  107. package/skills/ui-ux-pro-max/data/icons.csv +101 -0
  108. package/skills/ui-ux-pro-max/data/landing.csv +31 -0
  109. package/skills/ui-ux-pro-max/data/products.csv +97 -0
  110. package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  111. package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  112. package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  113. package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  114. package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  115. package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  116. package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  117. package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  118. package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  119. package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  120. package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  121. package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  122. package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  123. package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  124. package/skills/ui-ux-pro-max/data/styles.csv +68 -0
  125. package/skills/ui-ux-pro-max/data/typography.csv +58 -0
  126. package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  127. package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  128. package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
@@ -0,0 +1,595 @@
1
+ # Flutter Performance — Advanced Patterns Reference
2
+
3
+ Deep-dive reference for advanced Flutter performance optimization. Read this when the SKILL.md quick reference isn't enough.
4
+
5
+ ## 1. Impeller Internals & Optimization
6
+
7
+ ### How Impeller Renders
8
+
9
+ Impeller replaces Skia as Flutter's rendering backend:
10
+ 1. **Build time**: All shaders compiled offline during Flutter Engine build
11
+ 2. **Tile-based rendering**: Divides each frame into ~256x256 pixel tiles
12
+ 3. **Dirty region tracking**: Only re-rasterizes tiles whose content changed
13
+ 4. **Pipeline state objects**: Built upfront, not lazily at runtime
14
+
15
+ ### Impeller vs Skia Performance Comparison
16
+
17
+ | Metric | Skia | Impeller |
18
+ |---|---|---|
19
+ | First-frame shader compile | 50-300ms jank | 0ms (pre-compiled) |
20
+ | Frame rasterization | Baseline | ~50% faster |
21
+ | 120fps consistency | Frequent drops | Stable |
22
+ | GPU memory usage | Higher (shader cache) | Lower (no runtime cache) |
23
+ | Complex clip paths | Fast | Slower (more draw calls) |
24
+
25
+ ### Impeller-Aware Coding Patterns
26
+
27
+ **Avoid complex clip operations:**
28
+ ```dart
29
+ // Impeller generates more draw calls for complex clips
30
+ // BAD — custom clipper with bezier curves
31
+ ClipPath(
32
+ clipper: WavyClipper(), // complex path = many draw calls
33
+ child: Image.asset('bg.webp'),
34
+ )
35
+
36
+ // GOOD — use decoration or simple clips
37
+ Container(
38
+ decoration: BoxDecoration(
39
+ borderRadius: BorderRadius.circular(16),
40
+ image: DecorationImage(image: AssetImage('bg.webp'), fit: BoxFit.cover),
41
+ ),
42
+ )
43
+ ```
44
+
45
+ **Minimize overlapping opacity layers:**
46
+ ```dart
47
+ // BAD — stacked Opacity widgets create separate composition layers
48
+ Stack(children: [
49
+ Opacity(opacity: 0.8, child: Background()),
50
+ Opacity(opacity: 0.5, child: Overlay()),
51
+ Opacity(opacity: 0.3, child: Shadow()),
52
+ ])
53
+
54
+ // GOOD — combine into single paint operation
55
+ Stack(children: [
56
+ Background(),
57
+ Container(color: Colors.black.withOpacity(0.5)),
58
+ // Use color-level opacity, not widget-level
59
+ ])
60
+ ```
61
+
62
+ ### Checking Impeller Status
63
+
64
+ ```dart
65
+ // Verify Impeller is active in debug builds
66
+ import 'dart:ui' as ui;
67
+
68
+ void checkImpeller() {
69
+ // In Flutter 3.27+, Impeller is default on iOS and Android API 29+
70
+ debugPrint('Renderer: ${ui.PlatformDispatcher.instance.implicitView?.display}');
71
+ }
72
+ ```
73
+
74
+ ### Disabling Impeller (Troubleshooting Only)
75
+
76
+ ```bash
77
+ # iOS — Info.plist
78
+ <key>FLTEnableImpeller</key>
79
+ <false/>
80
+
81
+ # Android — AndroidManifest.xml
82
+ <meta-data
83
+ android:name="io.flutter.embedding.android.EnableImpeller"
84
+ android:value="false" />
85
+ ```
86
+
87
+ ## 2. Custom RenderObject Performance
88
+
89
+ For maximum rendering performance, bypass the widget layer:
90
+
91
+ ```dart
92
+ class FastCircle extends LeafRenderObjectWidget {
93
+ final Color color;
94
+ final double radius;
95
+
96
+ const FastCircle({super.key, required this.color, required this.radius});
97
+
98
+ @override
99
+ RenderObject createRenderObject(BuildContext context) {
100
+ return _RenderFastCircle(color: color, radius: radius);
101
+ }
102
+
103
+ @override
104
+ void updateRenderObject(BuildContext context, _RenderFastCircle renderObject) {
105
+ renderObject
106
+ ..color = color
107
+ ..radius = radius;
108
+ }
109
+ }
110
+
111
+ class _RenderFastCircle extends RenderBox {
112
+ Color _color;
113
+ double _radius;
114
+
115
+ _RenderFastCircle({required Color color, required double radius})
116
+ : _color = color,
117
+ _radius = radius;
118
+
119
+ set color(Color value) {
120
+ if (_color == value) return; // skip if unchanged
121
+ _color = value;
122
+ markNeedsPaint(); // only repaint, no layout
123
+ }
124
+
125
+ set radius(double value) {
126
+ if (_radius == value) return;
127
+ _radius = value;
128
+ markNeedsLayout(); // layout changed
129
+ }
130
+
131
+ @override
132
+ void performLayout() {
133
+ size = Size(_radius * 2, _radius * 2);
134
+ }
135
+
136
+ @override
137
+ void paint(PaintingContext context, Offset offset) {
138
+ final paint = Paint()..color = _color;
139
+ context.canvas.drawCircle(
140
+ offset + Offset(_radius, _radius),
141
+ _radius,
142
+ paint,
143
+ );
144
+ }
145
+ }
146
+ ```
147
+
148
+ **When to use custom RenderObjects:**
149
+ - Rendering hundreds of similar elements (charts, graphs, games)
150
+ - Need sub-millisecond paint performance
151
+ - Widget overhead is measurable in profiling
152
+
153
+ ## 3. Platform Channel Optimization
154
+
155
+ ### Reduce Serialization Overhead
156
+
157
+ ```dart
158
+ // BAD — sending complex nested Maps, large strings
159
+ final result = await platform.invokeMethod('processData', {
160
+ 'items': items.map((e) => e.toJson()).toList(), // serializes entire list
161
+ });
162
+
163
+ // GOOD — send binary data for large payloads
164
+ final bytes = Uint8List.fromList(utf8.encode(jsonEncode(items)));
165
+ final result = await platform.invokeMethod('processData', bytes);
166
+
167
+ // BEST — use Pigeon for type-safe, efficient platform channels
168
+ // Pigeon generates optimized serialization code at build time
169
+ ```
170
+
171
+ ### Batch Platform Calls
172
+
173
+ ```dart
174
+ // BAD — N platform channel calls
175
+ for (final file in files) {
176
+ await platform.invokeMethod('processFile', file.path);
177
+ }
178
+
179
+ // GOOD — single call with batch
180
+ await platform.invokeMethod('processFiles', files.map((f) => f.path).toList());
181
+ ```
182
+
183
+ ### Use EventChannel for Streams
184
+
185
+ ```dart
186
+ // For continuous data from native (sensors, location, etc.)
187
+ const eventChannel = EventChannel('com.app/sensor_data');
188
+ final stream = eventChannel.receiveBroadcastStream();
189
+
190
+ // In widget
191
+ StreamBuilder<dynamic>(
192
+ stream: stream,
193
+ builder: (context, snapshot) {
194
+ if (!snapshot.hasData) return const SizedBox.shrink();
195
+ return SensorDisplay(data: snapshot.data);
196
+ },
197
+ )
198
+ ```
199
+
200
+ ## 4. Isolate Advanced Patterns
201
+
202
+ ### Worker Pool for Parallel Processing
203
+
204
+ ```dart
205
+ import 'dart:async';
206
+ import 'dart:isolate';
207
+
208
+ class IsolatePool {
209
+ final int size;
210
+ final List<Isolate> _isolates = [];
211
+ final List<SendPort> _sendPorts = [];
212
+ int _nextWorker = 0;
213
+
214
+ IsolatePool(this.size);
215
+
216
+ Future<void> start() async {
217
+ for (var i = 0; i < size; i++) {
218
+ final receivePort = ReceivePort();
219
+ final isolate = await Isolate.spawn(_worker, receivePort.sendPort);
220
+ _isolates.add(isolate);
221
+ _sendPorts.add(await receivePort.first as SendPort);
222
+ }
223
+ }
224
+
225
+ Future<R> execute<R>(Function task) async {
226
+ final worker = _sendPorts[_nextWorker % size];
227
+ _nextWorker++;
228
+ final responsePort = ReceivePort();
229
+ worker.send([task, responsePort.sendPort]);
230
+ return await responsePort.first as R;
231
+ }
232
+
233
+ void dispose() {
234
+ for (final isolate in _isolates) {
235
+ isolate.kill();
236
+ }
237
+ }
238
+
239
+ static void _worker(SendPort sendPort) {
240
+ final receivePort = ReceivePort();
241
+ sendPort.send(receivePort.sendPort);
242
+ receivePort.listen((message) {
243
+ final task = message[0] as Function;
244
+ final replyPort = message[1] as SendPort;
245
+ replyPort.send(task());
246
+ });
247
+ }
248
+ }
249
+ ```
250
+
251
+ ### Isolate with Streaming Results
252
+
253
+ ```dart
254
+ // For progress reporting from isolate
255
+ Future<void> processWithProgress(List<String> files) async {
256
+ final receivePort = ReceivePort();
257
+ await Isolate.spawn(_processFiles, _ProcessRequest(files, receivePort.sendPort));
258
+
259
+ await for (final message in receivePort) {
260
+ if (message is double) {
261
+ // Progress update (0.0 - 1.0)
262
+ setState(() => _progress = message);
263
+ } else if (message is List<ProcessedFile>) {
264
+ // Final result
265
+ setState(() => _results = message);
266
+ receivePort.close();
267
+ }
268
+ }
269
+ }
270
+
271
+ static void _processFiles(_ProcessRequest request) {
272
+ final results = <ProcessedFile>[];
273
+ for (var i = 0; i < request.files.length; i++) {
274
+ results.add(_process(request.files[i]));
275
+ request.sendPort.send((i + 1) / request.files.length); // progress
276
+ }
277
+ request.sendPort.send(results); // final result
278
+ }
279
+ ```
280
+
281
+ ## 5. State Management Performance Deep-Dive
282
+
283
+ ### Riverpod — select() Granularity
284
+
285
+ ```dart
286
+ // ANTI-PATTERN — watching entire provider
287
+ final user = ref.watch(userProvider);
288
+ // Rebuilds when ANY field changes: name, email, avatar, settings...
289
+
290
+ // Level 1 — select single field
291
+ final name = ref.watch(userProvider.select((u) => u.name));
292
+
293
+ // Level 2 — select computed value
294
+ final isAdmin = ref.watch(userProvider.select((u) => u.role == 'admin'));
295
+
296
+ // Level 3 — select multiple fields with record
297
+ final (name, avatar) = ref.watch(
298
+ userProvider.select((u) => (u.name, u.avatarUrl)),
299
+ );
300
+ ```
301
+
302
+ ### Provider — Consumer vs context.watch
303
+
304
+ ```dart
305
+ // BAD — context.watch at root
306
+ Widget build(BuildContext context) {
307
+ final theme = context.watch<ThemeModel>();
308
+ return MaterialApp(/* ... */); // ENTIRE app rebuilds on theme change
309
+ }
310
+
311
+ // GOOD — Consumer wraps only the dependent subtree
312
+ Consumer<ThemeModel>(
313
+ builder: (context, theme, child) {
314
+ return MaterialApp(
315
+ theme: theme.data,
316
+ home: child!, // child NOT rebuilt
317
+ );
318
+ },
319
+ child: const HomePage(),
320
+ )
321
+ ```
322
+
323
+ ### Bloc — Event Debouncing
324
+
325
+ ```dart
326
+ // Prevent rapid-fire events from causing rebuild storms
327
+ on<SearchChanged>(
328
+ (event, emit) async {
329
+ final results = await _search(event.query);
330
+ emit(state.copyWith(results: results));
331
+ },
332
+ transformer: debounce(const Duration(milliseconds: 300)),
333
+ );
334
+
335
+ EventTransformer<E> debounce<E>(Duration duration) {
336
+ return (events, mapper) => events.debounceTime(duration).flatMap(mapper);
337
+ }
338
+ ```
339
+
340
+ ## 6. Scroll Performance Advanced
341
+
342
+ ### AutomaticKeepAliveClientMixin
343
+
344
+ ```dart
345
+ // Keep tab content alive when switching tabs (avoid rebuild)
346
+ class _TabContentState extends State<TabContent>
347
+ with AutomaticKeepAliveClientMixin {
348
+
349
+ @override
350
+ bool get wantKeepAlive => true;
351
+
352
+ @override
353
+ Widget build(BuildContext context) {
354
+ super.build(context); // REQUIRED
355
+ return ExpensiveContent();
356
+ }
357
+ }
358
+ ```
359
+
360
+ ### SliverPrototypeExtentList (Variable But Similar Heights)
361
+
362
+ ```dart
363
+ // When items have similar but not identical heights
364
+ CustomScrollView(
365
+ slivers: [
366
+ SliverPrototypeExtentList(
367
+ prototypeItem: const ItemTile(item: Item.prototype),
368
+ delegate: SliverChildBuilderDelegate(
369
+ (context, index) => ItemTile(item: items[index]),
370
+ childCount: items.length,
371
+ ),
372
+ ),
373
+ ],
374
+ )
375
+ ```
376
+
377
+ ### Pagination with Scroll Controller
378
+
379
+ ```dart
380
+ class _ListState extends State<InfiniteList> {
381
+ final _scrollController = ScrollController();
382
+ bool _isLoading = false;
383
+
384
+ @override
385
+ void initState() {
386
+ super.initState();
387
+ _scrollController.addListener(_onScroll);
388
+ }
389
+
390
+ void _onScroll() {
391
+ if (_isLoading) return;
392
+ final maxScroll = _scrollController.position.maxScrollExtent;
393
+ final currentScroll = _scrollController.position.pixels;
394
+ if (currentScroll >= maxScroll - 200) { // 200px threshold
395
+ _loadMore();
396
+ }
397
+ }
398
+
399
+ @override
400
+ void dispose() {
401
+ _scrollController.dispose();
402
+ super.dispose();
403
+ }
404
+ }
405
+ ```
406
+
407
+ ## 7. Animation Advanced Patterns
408
+
409
+ ### Staggered Animations
410
+
411
+ ```dart
412
+ class _StaggeredState extends State<StaggeredDemo>
413
+ with SingleTickerProviderStateMixin {
414
+ late final AnimationController _controller;
415
+ late final Animation<double> _opacity;
416
+ late final Animation<Offset> _slide;
417
+ late final Animation<double> _scale;
418
+
419
+ @override
420
+ void initState() {
421
+ super.initState();
422
+ _controller = AnimationController(
423
+ vsync: this,
424
+ duration: const Duration(milliseconds: 800),
425
+ );
426
+
427
+ _opacity = Tween(begin: 0.0, end: 1.0).animate(
428
+ CurvedAnimation(parent: _controller, curve: const Interval(0.0, 0.3)),
429
+ );
430
+ _slide = Tween(begin: const Offset(0, 0.3), end: Offset.zero).animate(
431
+ CurvedAnimation(parent: _controller, curve: const Interval(0.1, 0.6, curve: Curves.easeOut)),
432
+ );
433
+ _scale = Tween(begin: 0.8, end: 1.0).animate(
434
+ CurvedAnimation(parent: _controller, curve: const Interval(0.3, 0.8, curve: Curves.easeOut)),
435
+ );
436
+
437
+ _controller.forward();
438
+ }
439
+
440
+ @override
441
+ Widget build(BuildContext context) {
442
+ return AnimatedBuilder(
443
+ animation: _controller,
444
+ builder: (context, child) {
445
+ return Opacity(
446
+ opacity: _opacity.value,
447
+ child: SlideTransition(
448
+ position: _slide,
449
+ child: ScaleTransition(scale: _scale, child: child),
450
+ ),
451
+ );
452
+ },
453
+ child: const CardContent(), // cached, not rebuilt
454
+ );
455
+ }
456
+ }
457
+ ```
458
+
459
+ ### Physics-Based Animations (60fps Guaranteed)
460
+
461
+ ```dart
462
+ final _spring = SpringSimulation(
463
+ const SpringDescription(mass: 1, stiffness: 200, damping: 15),
464
+ 0, // start
465
+ 1, // end
466
+ 0, // velocity
467
+ );
468
+
469
+ _controller.animateWith(_spring);
470
+ ```
471
+
472
+ ## 8. CI Performance Benchmarking
473
+
474
+ ### Flutter Integration Test Benchmarks
475
+
476
+ ```dart
477
+ // test_driver/perf_test.dart
478
+ import 'package:flutter_test/flutter_test.dart';
479
+ import 'package:integration_test/integration_test.dart';
480
+
481
+ void main() {
482
+ final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
483
+
484
+ testWidgets('scrolling performance', (tester) async {
485
+ await tester.pumpWidget(const MyApp());
486
+
487
+ await binding.traceAction(
488
+ () async {
489
+ final listFinder = find.byType(ListView);
490
+ await tester.fling(listFinder, const Offset(0, -500), 1000);
491
+ await tester.pumpAndSettle();
492
+ await tester.fling(listFinder, const Offset(0, 500), 1000);
493
+ await tester.pumpAndSettle();
494
+ },
495
+ reportKey: 'scrolling_timeline',
496
+ );
497
+ });
498
+ }
499
+ ```
500
+
501
+ ```bash
502
+ # Run benchmark and generate timeline
503
+ flutter drive \
504
+ --driver=test_driver/perf_test.dart \
505
+ --target=integration_test/app_test.dart \
506
+ --profile \
507
+ --no-dds
508
+
509
+ # CI pipeline example (GitHub Actions)
510
+ # Compare against baseline — fail if P99 frame time > 16ms
511
+ ```
512
+
513
+ ### Custom Performance Metrics
514
+
515
+ ```dart
516
+ // Track custom metrics with Timeline
517
+ import 'dart:developer';
518
+
519
+ void expensiveOperation() {
520
+ Timeline.startSync('ExpensiveOperation');
521
+ // ... work ...
522
+ Timeline.finishSync();
523
+ }
524
+
525
+ // Visible in DevTools Performance timeline
526
+ ```
527
+
528
+ ## 9. Memory Profiling Checklist
529
+
530
+ ### Using DevTools Memory View
531
+
532
+ 1. **Open Memory tab** in Flutter DevTools
533
+ 2. **Take heap snapshot** before and after navigation
534
+ 3. **Compare snapshots** — look for objects that should have been GC'd
535
+ 4. **Filter by class** — search for your widget/state classes
536
+ 5. **Check retaining paths** — find what's holding the reference
537
+
538
+ ### Common Leak Patterns & Detection
539
+
540
+ | Symptom | Likely Cause | Detection |
541
+ |---|---|---|
542
+ | Memory grows on repeated navigation | Undisposed controllers | Heap snapshot diff |
543
+ | Memory grows over time | Uncancelled subscriptions | Monitor RSS over 5 min |
544
+ | Sudden memory spikes | Large image decode | Memory timeline |
545
+ | OOM crash on low-end devices | Image cache too large | Monitor max RSS |
546
+
547
+ ### Leak Canary Equivalent for Flutter
548
+
549
+ ```dart
550
+ // Debug-only leak detection
551
+ assert(() {
552
+ // Track widget disposal
553
+ debugPrint('Widget disposed: $runtimeType');
554
+ return true;
555
+ }());
556
+ ```
557
+
558
+ ## 10. Production Monitoring
559
+
560
+ ### Firebase Performance (Recommended)
561
+
562
+ ```dart
563
+ import 'package:firebase_performance/firebase_performance.dart';
564
+
565
+ // Custom trace for critical paths
566
+ final trace = FirebasePerformance.instance.newTrace('checkout_flow');
567
+ await trace.start();
568
+ // ... checkout logic ...
569
+ trace.setMetric('items_count', cart.items.length);
570
+ await trace.stop();
571
+
572
+ // HTTP metric
573
+ final metric = FirebasePerformance.instance.newHttpMetric(url, HttpMethod.Get);
574
+ await metric.start();
575
+ final response = await http.get(Uri.parse(url));
576
+ metric.httpResponseCode = response.statusCode;
577
+ metric.responsePayloadSize = response.contentLength;
578
+ await metric.stop();
579
+ ```
580
+
581
+ ### Sentry Flutter Performance
582
+
583
+ ```dart
584
+ import 'package:sentry_flutter/sentry_flutter.dart';
585
+
586
+ await SentryFlutter.init(
587
+ (options) {
588
+ options.dsn = 'YOUR_DSN';
589
+ options.tracesSampleRate = 0.2;
590
+ options.profilesSampleRate = 0.1;
591
+ options.enableAutoPerformanceTracing = true;
592
+ },
593
+ appRunner: () => runApp(const MyApp()),
594
+ );
595
+ ```