@wazir-dev/cli 1.0.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.
- package/AGENTS.md +111 -0
- package/CHANGELOG.md +14 -0
- package/CONTRIBUTING.md +101 -0
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/assets/composition-engine.mmd +34 -0
- package/assets/demo-script.sh +17 -0
- package/assets/logo-dark.svg +14 -0
- package/assets/logo.svg +14 -0
- package/assets/pipeline.mmd +39 -0
- package/assets/record-demo.sh +51 -0
- package/docs/README.md +51 -0
- package/docs/adapters/context-mode.md +60 -0
- package/docs/concepts/architecture.md +87 -0
- package/docs/concepts/artifact-model.md +60 -0
- package/docs/concepts/composition-engine.md +36 -0
- package/docs/concepts/indexing-and-recall.md +160 -0
- package/docs/concepts/observability.md +41 -0
- package/docs/concepts/roles-and-workflows.md +59 -0
- package/docs/concepts/terminology-policy.md +27 -0
- package/docs/getting-started/01-installation.md +78 -0
- package/docs/getting-started/02-first-run.md +102 -0
- package/docs/getting-started/03-adding-to-project.md +15 -0
- package/docs/getting-started/04-host-setup.md +15 -0
- package/docs/guides/ci-integration.md +15 -0
- package/docs/guides/creating-skills.md +15 -0
- package/docs/guides/expertise-module-authoring.md +15 -0
- package/docs/guides/hook-development.md +15 -0
- package/docs/guides/memory-and-learnings.md +34 -0
- package/docs/guides/multi-host-export.md +15 -0
- package/docs/guides/troubleshooting.md +101 -0
- package/docs/guides/writing-custom-roles.md +15 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
- package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
- package/docs/readmes/INDEX.md +99 -0
- package/docs/readmes/features/expertise/README.md +171 -0
- package/docs/readmes/features/exports/README.md +222 -0
- package/docs/readmes/features/hooks/README.md +103 -0
- package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
- package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
- package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
- package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
- package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
- package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
- package/docs/readmes/features/hooks/session-start.md +119 -0
- package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
- package/docs/readmes/features/roles/README.md +157 -0
- package/docs/readmes/features/roles/clarifier.md +152 -0
- package/docs/readmes/features/roles/content-author.md +190 -0
- package/docs/readmes/features/roles/designer.md +193 -0
- package/docs/readmes/features/roles/executor.md +184 -0
- package/docs/readmes/features/roles/learner.md +210 -0
- package/docs/readmes/features/roles/planner.md +182 -0
- package/docs/readmes/features/roles/researcher.md +164 -0
- package/docs/readmes/features/roles/reviewer.md +184 -0
- package/docs/readmes/features/roles/specifier.md +162 -0
- package/docs/readmes/features/roles/verifier.md +215 -0
- package/docs/readmes/features/schemas/README.md +178 -0
- package/docs/readmes/features/skills/README.md +63 -0
- package/docs/readmes/features/skills/brainstorming.md +96 -0
- package/docs/readmes/features/skills/debugging.md +148 -0
- package/docs/readmes/features/skills/design.md +120 -0
- package/docs/readmes/features/skills/prepare-next.md +109 -0
- package/docs/readmes/features/skills/run-audit.md +159 -0
- package/docs/readmes/features/skills/scan-project.md +109 -0
- package/docs/readmes/features/skills/self-audit.md +176 -0
- package/docs/readmes/features/skills/tdd.md +137 -0
- package/docs/readmes/features/skills/using-skills.md +92 -0
- package/docs/readmes/features/skills/verification.md +120 -0
- package/docs/readmes/features/skills/writing-plans.md +104 -0
- package/docs/readmes/features/tooling/README.md +320 -0
- package/docs/readmes/features/workflows/README.md +186 -0
- package/docs/readmes/features/workflows/author.md +181 -0
- package/docs/readmes/features/workflows/clarify.md +154 -0
- package/docs/readmes/features/workflows/design-review.md +171 -0
- package/docs/readmes/features/workflows/design.md +169 -0
- package/docs/readmes/features/workflows/discover.md +162 -0
- package/docs/readmes/features/workflows/execute.md +173 -0
- package/docs/readmes/features/workflows/learn.md +167 -0
- package/docs/readmes/features/workflows/plan-review.md +165 -0
- package/docs/readmes/features/workflows/plan.md +170 -0
- package/docs/readmes/features/workflows/prepare-next.md +167 -0
- package/docs/readmes/features/workflows/review.md +169 -0
- package/docs/readmes/features/workflows/run-audit.md +191 -0
- package/docs/readmes/features/workflows/spec-challenge.md +159 -0
- package/docs/readmes/features/workflows/specify.md +160 -0
- package/docs/readmes/features/workflows/verify.md +177 -0
- package/docs/readmes/packages/README.md +50 -0
- package/docs/readmes/packages/ajv.md +117 -0
- package/docs/readmes/packages/context-mode.md +118 -0
- package/docs/readmes/packages/gray-matter.md +116 -0
- package/docs/readmes/packages/node-test.md +137 -0
- package/docs/readmes/packages/yaml.md +112 -0
- package/docs/reference/configuration-reference.md +159 -0
- package/docs/reference/expertise-index.md +52 -0
- package/docs/reference/git-flow.md +43 -0
- package/docs/reference/hooks.md +87 -0
- package/docs/reference/host-exports.md +50 -0
- package/docs/reference/launch-checklist.md +172 -0
- package/docs/reference/marketplace-listings.md +76 -0
- package/docs/reference/release-process.md +34 -0
- package/docs/reference/roles-reference.md +77 -0
- package/docs/reference/skills.md +33 -0
- package/docs/reference/templates.md +29 -0
- package/docs/reference/tooling-cli.md +94 -0
- package/docs/truth-claims.yaml +222 -0
- package/expertise/PROGRESS.md +63 -0
- package/expertise/README.md +18 -0
- package/expertise/antipatterns/PROGRESS.md +56 -0
- package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
- package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
- package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
- package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
- package/expertise/antipatterns/backend/index.md +24 -0
- package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
- package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
- package/expertise/antipatterns/code/async-antipatterns.md +622 -0
- package/expertise/antipatterns/code/code-smells.md +1186 -0
- package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
- package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
- package/expertise/antipatterns/code/index.md +27 -0
- package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
- package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
- package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
- package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
- package/expertise/antipatterns/design/dark-patterns.md +1121 -0
- package/expertise/antipatterns/design/index.md +22 -0
- package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
- package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
- package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
- package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
- package/expertise/antipatterns/frontend/index.md +23 -0
- package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
- package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
- package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
- package/expertise/antipatterns/index.md +31 -0
- package/expertise/antipatterns/performance/index.md +20 -0
- package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
- package/expertise/antipatterns/performance/premature-optimization.md +623 -0
- package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
- package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
- package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
- package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
- package/expertise/antipatterns/process/index.md +23 -0
- package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
- package/expertise/antipatterns/security/index.md +20 -0
- package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
- package/expertise/antipatterns/security/security-theater.md +843 -0
- package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
- package/expertise/architecture/PROGRESS.md +70 -0
- package/expertise/architecture/data/caching-architecture.md +671 -0
- package/expertise/architecture/data/data-consistency.md +574 -0
- package/expertise/architecture/data/data-modeling.md +536 -0
- package/expertise/architecture/data/event-streams-and-queues.md +634 -0
- package/expertise/architecture/data/index.md +25 -0
- package/expertise/architecture/data/search-architecture.md +663 -0
- package/expertise/architecture/data/sql-vs-nosql.md +708 -0
- package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
- package/expertise/architecture/decisions/build-vs-buy.md +616 -0
- package/expertise/architecture/decisions/index.md +23 -0
- package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
- package/expertise/architecture/decisions/technology-selection.md +616 -0
- package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
- package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
- package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
- package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
- package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
- package/expertise/architecture/distributed/index.md +25 -0
- package/expertise/architecture/distributed/saga-pattern.md +797 -0
- package/expertise/architecture/foundations/architectural-thinking.md +460 -0
- package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
- package/expertise/architecture/foundations/design-principles-solid.md +649 -0
- package/expertise/architecture/foundations/domain-driven-design.md +719 -0
- package/expertise/architecture/foundations/index.md +25 -0
- package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
- package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
- package/expertise/architecture/index.md +34 -0
- package/expertise/architecture/integration/api-design-graphql.md +638 -0
- package/expertise/architecture/integration/api-design-grpc.md +804 -0
- package/expertise/architecture/integration/api-design-rest.md +892 -0
- package/expertise/architecture/integration/index.md +25 -0
- package/expertise/architecture/integration/third-party-integration.md +795 -0
- package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
- package/expertise/architecture/integration/websockets-realtime.md +791 -0
- package/expertise/architecture/mobile-architecture/index.md +22 -0
- package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
- package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
- package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
- package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
- package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
- package/expertise/architecture/patterns/event-driven.md +797 -0
- package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
- package/expertise/architecture/patterns/index.md +27 -0
- package/expertise/architecture/patterns/layered-architecture.md +736 -0
- package/expertise/architecture/patterns/microservices.md +753 -0
- package/expertise/architecture/patterns/modular-monolith.md +692 -0
- package/expertise/architecture/patterns/monolith.md +626 -0
- package/expertise/architecture/patterns/plugin-architecture.md +735 -0
- package/expertise/architecture/patterns/serverless.md +780 -0
- package/expertise/architecture/scaling/database-scaling.md +615 -0
- package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
- package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
- package/expertise/architecture/scaling/index.md +24 -0
- package/expertise/architecture/scaling/multi-tenancy.md +800 -0
- package/expertise/architecture/scaling/stateless-design.md +787 -0
- package/expertise/backend/embedded-firmware.md +625 -0
- package/expertise/backend/go.md +853 -0
- package/expertise/backend/index.md +24 -0
- package/expertise/backend/java-spring.md +448 -0
- package/expertise/backend/node-typescript.md +625 -0
- package/expertise/backend/python-fastapi.md +724 -0
- package/expertise/backend/rust.md +458 -0
- package/expertise/backend/solidity.md +711 -0
- package/expertise/composition-map.yaml +443 -0
- package/expertise/content/foundations/content-modeling.md +395 -0
- package/expertise/content/foundations/editorial-standards.md +449 -0
- package/expertise/content/foundations/index.md +24 -0
- package/expertise/content/foundations/microcopy.md +455 -0
- package/expertise/content/foundations/terminology-governance.md +509 -0
- package/expertise/content/index.md +34 -0
- package/expertise/content/patterns/accessibility-copy.md +518 -0
- package/expertise/content/patterns/index.md +24 -0
- package/expertise/content/patterns/notification-content.md +433 -0
- package/expertise/content/patterns/sample-content.md +486 -0
- package/expertise/content/patterns/state-copy.md +439 -0
- package/expertise/design/PROGRESS.md +58 -0
- package/expertise/design/disciplines/dark-mode-theming.md +577 -0
- package/expertise/design/disciplines/design-systems.md +595 -0
- package/expertise/design/disciplines/index.md +25 -0
- package/expertise/design/disciplines/information-architecture.md +800 -0
- package/expertise/design/disciplines/interaction-design.md +788 -0
- package/expertise/design/disciplines/responsive-design.md +552 -0
- package/expertise/design/disciplines/usability-testing.md +516 -0
- package/expertise/design/disciplines/user-research.md +792 -0
- package/expertise/design/foundations/accessibility-design.md +796 -0
- package/expertise/design/foundations/color-theory.md +797 -0
- package/expertise/design/foundations/iconography.md +795 -0
- package/expertise/design/foundations/index.md +26 -0
- package/expertise/design/foundations/motion-and-animation.md +653 -0
- package/expertise/design/foundations/rtl-design.md +585 -0
- package/expertise/design/foundations/spacing-and-layout.md +607 -0
- package/expertise/design/foundations/typography.md +800 -0
- package/expertise/design/foundations/visual-hierarchy.md +761 -0
- package/expertise/design/index.md +32 -0
- package/expertise/design/patterns/authentication-flows.md +474 -0
- package/expertise/design/patterns/content-consumption.md +789 -0
- package/expertise/design/patterns/data-display.md +618 -0
- package/expertise/design/patterns/e-commerce.md +1494 -0
- package/expertise/design/patterns/feedback-and-states.md +642 -0
- package/expertise/design/patterns/forms-and-input.md +819 -0
- package/expertise/design/patterns/gamification.md +801 -0
- package/expertise/design/patterns/index.md +31 -0
- package/expertise/design/patterns/microinteractions.md +449 -0
- package/expertise/design/patterns/navigation.md +800 -0
- package/expertise/design/patterns/notifications.md +705 -0
- package/expertise/design/patterns/onboarding.md +700 -0
- package/expertise/design/patterns/search-and-filter.md +601 -0
- package/expertise/design/patterns/settings-and-preferences.md +768 -0
- package/expertise/design/patterns/social-and-community.md +748 -0
- package/expertise/design/platforms/desktop-native.md +612 -0
- package/expertise/design/platforms/index.md +25 -0
- package/expertise/design/platforms/mobile-android.md +825 -0
- package/expertise/design/platforms/mobile-cross-platform.md +983 -0
- package/expertise/design/platforms/mobile-ios.md +699 -0
- package/expertise/design/platforms/tablet.md +794 -0
- package/expertise/design/platforms/web-dashboard.md +790 -0
- package/expertise/design/platforms/web-responsive.md +550 -0
- package/expertise/design/psychology/behavioral-nudges.md +449 -0
- package/expertise/design/psychology/cognitive-load.md +1191 -0
- package/expertise/design/psychology/error-psychology.md +778 -0
- package/expertise/design/psychology/index.md +22 -0
- package/expertise/design/psychology/persuasive-design.md +736 -0
- package/expertise/design/psychology/user-mental-models.md +623 -0
- package/expertise/design/tooling/open-pencil.md +266 -0
- package/expertise/frontend/angular.md +1073 -0
- package/expertise/frontend/desktop-electron.md +546 -0
- package/expertise/frontend/flutter.md +782 -0
- package/expertise/frontend/index.md +27 -0
- package/expertise/frontend/native-android.md +409 -0
- package/expertise/frontend/native-ios.md +490 -0
- package/expertise/frontend/react-native.md +1160 -0
- package/expertise/frontend/react.md +808 -0
- package/expertise/frontend/vue.md +1089 -0
- package/expertise/humanize/domain-rules-code.md +79 -0
- package/expertise/humanize/domain-rules-content.md +67 -0
- package/expertise/humanize/domain-rules-technical-docs.md +56 -0
- package/expertise/humanize/index.md +35 -0
- package/expertise/humanize/self-audit-checklist.md +87 -0
- package/expertise/humanize/sentence-patterns.md +218 -0
- package/expertise/humanize/vocabulary-blacklist.md +105 -0
- package/expertise/i18n/PROGRESS.md +65 -0
- package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
- package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
- package/expertise/i18n/advanced/complex-scripts.md +30 -0
- package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
- package/expertise/i18n/advanced/testing-i18n.md +28 -0
- package/expertise/i18n/content/content-adaptation.md +23 -0
- package/expertise/i18n/content/locale-specific-formatting.md +23 -0
- package/expertise/i18n/content/machine-translation-integration.md +28 -0
- package/expertise/i18n/content/translation-management.md +29 -0
- package/expertise/i18n/foundations/date-time-calendars.md +67 -0
- package/expertise/i18n/foundations/i18n-architecture.md +272 -0
- package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
- package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
- package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
- package/expertise/i18n/foundations/string-externalization.md +236 -0
- package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
- package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
- package/expertise/i18n/index.md +38 -0
- package/expertise/i18n/platform/backend-i18n.md +31 -0
- package/expertise/i18n/platform/flutter-i18n.md +148 -0
- package/expertise/i18n/platform/native-android-i18n.md +36 -0
- package/expertise/i18n/platform/native-ios-i18n.md +36 -0
- package/expertise/i18n/platform/react-i18n.md +103 -0
- package/expertise/i18n/platform/web-css-i18n.md +81 -0
- package/expertise/i18n/rtl/arabic-specific.md +175 -0
- package/expertise/i18n/rtl/hebrew-specific.md +149 -0
- package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
- package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
- package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
- package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
- package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
- package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
- package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
- package/expertise/i18n/rtl/rtl-typography.md +160 -0
- package/expertise/index.md +113 -0
- package/expertise/index.yaml +216 -0
- package/expertise/infrastructure/cloud-aws.md +597 -0
- package/expertise/infrastructure/cloud-gcp.md +599 -0
- package/expertise/infrastructure/cybersecurity.md +816 -0
- package/expertise/infrastructure/database-mongodb.md +447 -0
- package/expertise/infrastructure/database-postgres.md +400 -0
- package/expertise/infrastructure/devops-cicd.md +787 -0
- package/expertise/infrastructure/index.md +27 -0
- package/expertise/performance/PROGRESS.md +50 -0
- package/expertise/performance/backend/api-latency.md +1204 -0
- package/expertise/performance/backend/background-jobs.md +506 -0
- package/expertise/performance/backend/connection-pooling.md +1209 -0
- package/expertise/performance/backend/database-query-optimization.md +515 -0
- package/expertise/performance/backend/index.md +23 -0
- package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
- package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
- package/expertise/performance/foundations/caching-strategies.md +489 -0
- package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
- package/expertise/performance/foundations/index.md +24 -0
- package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
- package/expertise/performance/foundations/memory-management.md +964 -0
- package/expertise/performance/foundations/performance-budgets.md +1314 -0
- package/expertise/performance/index.md +31 -0
- package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
- package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
- package/expertise/performance/infrastructure/index.md +22 -0
- package/expertise/performance/infrastructure/load-balancing.md +1081 -0
- package/expertise/performance/infrastructure/observability.md +1079 -0
- package/expertise/performance/mobile/index.md +23 -0
- package/expertise/performance/mobile/mobile-animations.md +544 -0
- package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
- package/expertise/performance/mobile/mobile-network.md +452 -0
- package/expertise/performance/mobile/mobile-rendering.md +599 -0
- package/expertise/performance/mobile/mobile-startup-time.md +505 -0
- package/expertise/performance/platform-specific/flutter-performance.md +647 -0
- package/expertise/performance/platform-specific/index.md +22 -0
- package/expertise/performance/platform-specific/node-performance.md +1307 -0
- package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
- package/expertise/performance/platform-specific/react-performance.md +1403 -0
- package/expertise/performance/web/bundle-optimization.md +1239 -0
- package/expertise/performance/web/image-and-media.md +636 -0
- package/expertise/performance/web/index.md +24 -0
- package/expertise/performance/web/network-optimization.md +1133 -0
- package/expertise/performance/web/rendering-performance.md +1098 -0
- package/expertise/performance/web/ssr-and-hydration.md +918 -0
- package/expertise/performance/web/web-vitals.md +1374 -0
- package/expertise/quality/accessibility.md +985 -0
- package/expertise/quality/evidence-based-verification.md +499 -0
- package/expertise/quality/index.md +24 -0
- package/expertise/quality/ml-model-audit.md +614 -0
- package/expertise/quality/performance.md +600 -0
- package/expertise/quality/testing-api.md +891 -0
- package/expertise/quality/testing-mobile.md +496 -0
- package/expertise/quality/testing-web.md +849 -0
- package/expertise/security/PROGRESS.md +54 -0
- package/expertise/security/agentic-identity.md +540 -0
- package/expertise/security/compliance-frameworks.md +601 -0
- package/expertise/security/data/data-encryption.md +364 -0
- package/expertise/security/data/data-privacy-gdpr.md +692 -0
- package/expertise/security/data/database-security.md +1171 -0
- package/expertise/security/data/index.md +22 -0
- package/expertise/security/data/pii-handling.md +531 -0
- package/expertise/security/foundations/authentication.md +1041 -0
- package/expertise/security/foundations/authorization.md +603 -0
- package/expertise/security/foundations/cryptography.md +1001 -0
- package/expertise/security/foundations/index.md +25 -0
- package/expertise/security/foundations/owasp-top-10.md +1354 -0
- package/expertise/security/foundations/secrets-management.md +1217 -0
- package/expertise/security/foundations/secure-sdlc.md +700 -0
- package/expertise/security/foundations/supply-chain-security.md +698 -0
- package/expertise/security/index.md +31 -0
- package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
- package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
- package/expertise/security/infrastructure/container-security.md +721 -0
- package/expertise/security/infrastructure/incident-response.md +1295 -0
- package/expertise/security/infrastructure/index.md +24 -0
- package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
- package/expertise/security/infrastructure/network-security.md +1337 -0
- package/expertise/security/mobile/index.md +23 -0
- package/expertise/security/mobile/mobile-android-security.md +1218 -0
- package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
- package/expertise/security/mobile/mobile-data-storage.md +1265 -0
- package/expertise/security/mobile/mobile-ios-security.md +1401 -0
- package/expertise/security/mobile/mobile-network-security.md +1520 -0
- package/expertise/security/smart-contract-security.md +594 -0
- package/expertise/security/testing/index.md +22 -0
- package/expertise/security/testing/penetration-testing.md +1258 -0
- package/expertise/security/testing/security-code-review.md +1765 -0
- package/expertise/security/testing/threat-modeling.md +1074 -0
- package/expertise/security/testing/vulnerability-scanning.md +1062 -0
- package/expertise/security/web/api-security.md +586 -0
- package/expertise/security/web/cors-and-headers.md +433 -0
- package/expertise/security/web/csrf.md +562 -0
- package/expertise/security/web/file-upload.md +1477 -0
- package/expertise/security/web/index.md +25 -0
- package/expertise/security/web/injection.md +1375 -0
- package/expertise/security/web/session-management.md +1101 -0
- package/expertise/security/web/xss.md +1158 -0
- package/exports/README.md +17 -0
- package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
- package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
- package/exports/hosts/claude/.claude/agents/designer.md +55 -0
- package/exports/hosts/claude/.claude/agents/executor.md +55 -0
- package/exports/hosts/claude/.claude/agents/learner.md +51 -0
- package/exports/hosts/claude/.claude/agents/planner.md +53 -0
- package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
- package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
- package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
- package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
- package/exports/hosts/claude/.claude/commands/author.md +42 -0
- package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
- package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
- package/exports/hosts/claude/.claude/commands/design.md +44 -0
- package/exports/hosts/claude/.claude/commands/discover.md +37 -0
- package/exports/hosts/claude/.claude/commands/execute.md +48 -0
- package/exports/hosts/claude/.claude/commands/learn.md +38 -0
- package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
- package/exports/hosts/claude/.claude/commands/plan.md +39 -0
- package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
- package/exports/hosts/claude/.claude/commands/review.md +40 -0
- package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
- package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
- package/exports/hosts/claude/.claude/commands/specify.md +38 -0
- package/exports/hosts/claude/.claude/commands/verify.md +37 -0
- package/exports/hosts/claude/.claude/settings.json +34 -0
- package/exports/hosts/claude/CLAUDE.md +19 -0
- package/exports/hosts/claude/export.manifest.json +38 -0
- package/exports/hosts/claude/host-package.json +67 -0
- package/exports/hosts/codex/AGENTS.md +19 -0
- package/exports/hosts/codex/export.manifest.json +38 -0
- package/exports/hosts/codex/host-package.json +41 -0
- package/exports/hosts/cursor/.cursor/hooks.json +16 -0
- package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
- package/exports/hosts/cursor/export.manifest.json +38 -0
- package/exports/hosts/cursor/host-package.json +42 -0
- package/exports/hosts/gemini/GEMINI.md +19 -0
- package/exports/hosts/gemini/export.manifest.json +38 -0
- package/exports/hosts/gemini/host-package.json +41 -0
- package/hooks/README.md +18 -0
- package/hooks/definitions/loop_cap_guard.yaml +21 -0
- package/hooks/definitions/post_tool_capture.yaml +24 -0
- package/hooks/definitions/pre_compact_summary.yaml +19 -0
- package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
- package/hooks/definitions/protected_path_write_guard.yaml +19 -0
- package/hooks/definitions/session_start.yaml +19 -0
- package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
- package/hooks/loop-cap-guard +17 -0
- package/hooks/post-tool-lint +36 -0
- package/hooks/protected-path-write-guard +17 -0
- package/hooks/session-start +41 -0
- package/llms-full.txt +2355 -0
- package/llms.txt +43 -0
- package/package.json +79 -0
- package/roles/README.md +20 -0
- package/roles/clarifier.md +42 -0
- package/roles/content-author.md +63 -0
- package/roles/designer.md +55 -0
- package/roles/executor.md +55 -0
- package/roles/learner.md +51 -0
- package/roles/planner.md +53 -0
- package/roles/researcher.md +43 -0
- package/roles/reviewer.md +54 -0
- package/roles/specifier.md +47 -0
- package/roles/verifier.md +71 -0
- package/schemas/README.md +24 -0
- package/schemas/accepted-learning.schema.json +20 -0
- package/schemas/author-artifact.schema.json +156 -0
- package/schemas/clarification.schema.json +19 -0
- package/schemas/design-artifact.schema.json +80 -0
- package/schemas/docs-claim.schema.json +18 -0
- package/schemas/export-manifest.schema.json +20 -0
- package/schemas/hook.schema.json +67 -0
- package/schemas/host-export-package.schema.json +18 -0
- package/schemas/implementation-plan.schema.json +19 -0
- package/schemas/proposed-learning.schema.json +19 -0
- package/schemas/research.schema.json +18 -0
- package/schemas/review.schema.json +29 -0
- package/schemas/run-manifest.schema.json +18 -0
- package/schemas/spec-challenge.schema.json +18 -0
- package/schemas/spec.schema.json +20 -0
- package/schemas/usage.schema.json +102 -0
- package/schemas/verification-proof.schema.json +29 -0
- package/schemas/wazir-manifest.schema.json +173 -0
- package/skills/README.md +40 -0
- package/skills/brainstorming/SKILL.md +77 -0
- package/skills/debugging/SKILL.md +50 -0
- package/skills/design/SKILL.md +61 -0
- package/skills/dispatching-parallel-agents/SKILL.md +128 -0
- package/skills/executing-plans/SKILL.md +70 -0
- package/skills/finishing-a-development-branch/SKILL.md +169 -0
- package/skills/humanize/SKILL.md +123 -0
- package/skills/init-pipeline/SKILL.md +124 -0
- package/skills/prepare-next/SKILL.md +20 -0
- package/skills/receiving-code-review/SKILL.md +123 -0
- package/skills/requesting-code-review/SKILL.md +105 -0
- package/skills/requesting-code-review/code-reviewer.md +108 -0
- package/skills/run-audit/SKILL.md +197 -0
- package/skills/scan-project/SKILL.md +41 -0
- package/skills/self-audit/SKILL.md +153 -0
- package/skills/subagent-driven-development/SKILL.md +154 -0
- package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/skills/subagent-driven-development/implementer-prompt.md +102 -0
- package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/skills/tdd/SKILL.md +23 -0
- package/skills/using-git-worktrees/SKILL.md +163 -0
- package/skills/using-skills/SKILL.md +95 -0
- package/skills/verification/SKILL.md +22 -0
- package/skills/wazir/SKILL.md +463 -0
- package/skills/writing-plans/SKILL.md +30 -0
- package/skills/writing-skills/SKILL.md +157 -0
- package/skills/writing-skills/anthropic-best-practices.md +122 -0
- package/skills/writing-skills/persuasion-principles.md +50 -0
- package/templates/README.md +20 -0
- package/templates/artifacts/README.md +10 -0
- package/templates/artifacts/accepted-learning.md +19 -0
- package/templates/artifacts/accepted-learning.template.json +12 -0
- package/templates/artifacts/author.md +74 -0
- package/templates/artifacts/author.template.json +19 -0
- package/templates/artifacts/clarification.md +21 -0
- package/templates/artifacts/clarification.template.json +12 -0
- package/templates/artifacts/execute-notes.md +19 -0
- package/templates/artifacts/implementation-plan.md +21 -0
- package/templates/artifacts/implementation-plan.template.json +11 -0
- package/templates/artifacts/learning-proposal.md +19 -0
- package/templates/artifacts/next-run-handoff.md +21 -0
- package/templates/artifacts/plan-review.md +19 -0
- package/templates/artifacts/proposed-learning.template.json +12 -0
- package/templates/artifacts/research.md +21 -0
- package/templates/artifacts/research.template.json +12 -0
- package/templates/artifacts/review-findings.md +19 -0
- package/templates/artifacts/review.template.json +11 -0
- package/templates/artifacts/run-manifest.template.json +8 -0
- package/templates/artifacts/spec-challenge.md +19 -0
- package/templates/artifacts/spec-challenge.template.json +11 -0
- package/templates/artifacts/spec.md +21 -0
- package/templates/artifacts/spec.template.json +12 -0
- package/templates/artifacts/verification-proof.md +19 -0
- package/templates/artifacts/verification-proof.template.json +11 -0
- package/templates/examples/accepted-learning.example.json +14 -0
- package/templates/examples/author.example.json +152 -0
- package/templates/examples/clarification.example.json +15 -0
- package/templates/examples/docs-claim.example.json +8 -0
- package/templates/examples/export-manifest.example.json +7 -0
- package/templates/examples/host-export-package.example.json +11 -0
- package/templates/examples/implementation-plan.example.json +17 -0
- package/templates/examples/proposed-learning.example.json +13 -0
- package/templates/examples/research.example.json +15 -0
- package/templates/examples/research.example.md +6 -0
- package/templates/examples/review.example.json +17 -0
- package/templates/examples/run-manifest.example.json +9 -0
- package/templates/examples/spec-challenge.example.json +14 -0
- package/templates/examples/spec.example.json +21 -0
- package/templates/examples/verification-proof.example.json +21 -0
- package/templates/examples/wazir-manifest.example.yaml +65 -0
- package/templates/task-definition-schema.md +99 -0
- package/tooling/README.md +20 -0
- package/tooling/src/adapters/context-mode.js +50 -0
- package/tooling/src/capture/command.js +376 -0
- package/tooling/src/capture/store.js +99 -0
- package/tooling/src/capture/usage.js +270 -0
- package/tooling/src/checks/branches.js +50 -0
- package/tooling/src/checks/brand-truth.js +110 -0
- package/tooling/src/checks/changelog.js +231 -0
- package/tooling/src/checks/command-registry.js +36 -0
- package/tooling/src/checks/commits.js +102 -0
- package/tooling/src/checks/docs-drift.js +103 -0
- package/tooling/src/checks/docs-truth.js +201 -0
- package/tooling/src/checks/runtime-surface.js +156 -0
- package/tooling/src/cli.js +116 -0
- package/tooling/src/command-options.js +56 -0
- package/tooling/src/commands/validate.js +320 -0
- package/tooling/src/doctor/command.js +91 -0
- package/tooling/src/export/command.js +77 -0
- package/tooling/src/export/compiler.js +498 -0
- package/tooling/src/guards/loop-cap-guard.js +52 -0
- package/tooling/src/guards/protected-path-write-guard.js +67 -0
- package/tooling/src/index/command.js +152 -0
- package/tooling/src/index/storage.js +1061 -0
- package/tooling/src/index/summarizers.js +261 -0
- package/tooling/src/loaders.js +18 -0
- package/tooling/src/project-root.js +22 -0
- package/tooling/src/recall/command.js +225 -0
- package/tooling/src/schema-validator.js +30 -0
- package/tooling/src/state-root.js +40 -0
- package/tooling/src/status/command.js +71 -0
- package/wazir.manifest.yaml +135 -0
- package/workflows/README.md +19 -0
- package/workflows/author.md +42 -0
- package/workflows/clarify.md +38 -0
- package/workflows/design-review.md +46 -0
- package/workflows/design.md +44 -0
- package/workflows/discover.md +37 -0
- package/workflows/execute.md +48 -0
- package/workflows/learn.md +38 -0
- package/workflows/plan-review.md +42 -0
- package/workflows/plan.md +39 -0
- package/workflows/prepare-next.md +37 -0
- package/workflows/review.md +40 -0
- package/workflows/run-audit.md +41 -0
- package/workflows/spec-challenge.md +41 -0
- package/workflows/specify.md +38 -0
- package/workflows/verify.md +37 -0
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
# Mobile Rendering Performance — Performance Expertise Module
|
|
2
|
+
|
|
3
|
+
> Mobile rendering must hit 60fps (16.67ms per frame) or 120fps (8.33ms) on ProMotion/high-refresh displays. Dropped frames (jank) are immediately perceptible to users and create a perception of poor quality. Mobile rendering is constrained by thermal throttling, limited GPU memory, and variable device capabilities spanning a 10x performance range from low-end to flagship.
|
|
4
|
+
|
|
5
|
+
> **Impact:** Critical
|
|
6
|
+
> **Applies to:** Mobile (iOS, Android, Flutter, React Native)
|
|
7
|
+
> **Key metrics:** Frame render time, Jank rate (% dropped frames), GPU overdraw ratio, View hierarchy depth, CPU/GPU utilization per frame
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Why This Matters
|
|
12
|
+
|
|
13
|
+
Every frame has a hard deadline. At 60fps you get 16.67ms; at 120fps only 8.33ms. Miss by 1ms and the Choreographer (Android) or CADisplayLink (iOS) drops the frame entirely. The pipeline is deeply parallel -- when the display shows frame N, SurfaceFlinger composites N+1, RenderThread prepares N+2, and the UI thread builds N+3. A stall anywhere cascades forward.
|
|
14
|
+
|
|
15
|
+
**User perception:** A single dropped frame during scroll is perceptible as "stutter." Two to three consecutive drops (33-50ms gap) register as "laggy." Frames exceeding 700ms are classified as frozen -- users assume the app has crashed.
|
|
16
|
+
|
|
17
|
+
**Business impact:** Amazon found every 100ms of latency costs 1% in sales. Google research shows 53% of mobile users abandon experiences taking >3s. Akamai measured a 7% conversion drop per 100ms of delay. Moving from a 3-star to 4-star app rating increases download conversions by 89%, and rendering jank is a leading driver of poor ratings.
|
|
18
|
+
|
|
19
|
+
**Google Play Vitals thresholds** that affect store ranking:
|
|
20
|
+
|
|
21
|
+
| Metric | Threshold | Consequence |
|
|
22
|
+
|--------|-----------|-------------|
|
|
23
|
+
| Slow rendering | >50% of frames exceed 16ms in a session | Flagged in Play Vitals |
|
|
24
|
+
| Frozen frames | >0.1% of frames exceed 700ms | Flagged as excessive |
|
|
25
|
+
| Slow game sessions | >25% slow frames at <20 FPS | Flagged for games |
|
|
26
|
+
|
|
27
|
+
Apps exceeding these thresholds receive reduced visibility in the Play Store. Apple does not publish equivalent thresholds but MetricKit and Xcode Organizer surface comparable hitch-rate data.
|
|
28
|
+
|
|
29
|
+
**Thermal throttling** compounds the problem: mobile devices sustain 30-50% performance degradation under load. Research shows frame rates dropping from 35 FPS to 23 FPS (34% degradation) with frequency capping increasing frame defects by up to 146%. Compact form factors with passive cooling mean throttling begins within 2-5 minutes of sustained rendering, making initial benchmarks misleading.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Performance Budgets & Targets
|
|
34
|
+
|
|
35
|
+
### Frame Time Budgets
|
|
36
|
+
|
|
37
|
+
| Refresh Rate | Frame Budget | Realistic App Budget* | GPU Budget |
|
|
38
|
+
|-------------|-------------|----------------------|------------|
|
|
39
|
+
| 60 Hz | 16.67ms | ~12ms | ~6ms |
|
|
40
|
+
| 90 Hz | 11.11ms | ~8ms | ~4ms |
|
|
41
|
+
| 120 Hz | 8.33ms | ~6ms | ~3ms |
|
|
42
|
+
|
|
43
|
+
*Realistic budget accounts for ~3-4ms system overhead (vsync scheduling, compositor, OS services).
|
|
44
|
+
|
|
45
|
+
### Acceptable Jank Rates
|
|
46
|
+
|
|
47
|
+
| Rating | Jank Rate | Dropped Frames/min (60fps) |
|
|
48
|
+
|--------|-----------|---------------------------|
|
|
49
|
+
| Excellent | <1% | <36 |
|
|
50
|
+
| Good | 1-3% | 36-108 |
|
|
51
|
+
| Acceptable | 3-5% | 108-180 |
|
|
52
|
+
| Poor | 5-10% | 180-360 |
|
|
53
|
+
| Unacceptable | >10% | >360 |
|
|
54
|
+
|
|
55
|
+
### GPU Overdraw Limits
|
|
56
|
+
|
|
57
|
+
| Overdraw | Debug Color | Target |
|
|
58
|
+
|----------|-------------|--------|
|
|
59
|
+
| None (1x) | True color | Ideal |
|
|
60
|
+
| 1x (2x draw) | Blue | Acceptable |
|
|
61
|
+
| 2x (3x draw) | Green | Maximum for most areas |
|
|
62
|
+
| 3x (4x draw) | Pink | Needs optimization |
|
|
63
|
+
| 4x+ (5x+ draw) | Red | Immediate fix required |
|
|
64
|
+
|
|
65
|
+
### View Hierarchy Depth Targets
|
|
66
|
+
|
|
67
|
+
| Platform | Maximum Recommended | Ideal |
|
|
68
|
+
|----------|-------------------|-------|
|
|
69
|
+
| Android XML Views | 10 levels | 5-7 levels |
|
|
70
|
+
| Jetpack Compose | N/A (flat by design) | Minimize recomposition scope |
|
|
71
|
+
| iOS UIKit | 8 levels | 4-6 levels |
|
|
72
|
+
| SwiftUI | N/A (flat by design) | Minimize body recomputation |
|
|
73
|
+
| Flutter | N/A (widget tree) | Minimize rebuild scope |
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Measurement & Profiling
|
|
78
|
+
|
|
79
|
+
### Android
|
|
80
|
+
|
|
81
|
+
- **GPU Rendering Profiler:** On-device bars via Developer Options > "Profile GPU rendering." Blue=draw, Purple=upload, Red=GPU execute, Orange=CPU wait. Green line marks 16ms threshold.
|
|
82
|
+
- **Perfetto (replaces Systrace):** Google's primary trace tool. Key tracks: `Choreographer#doFrame` (frame start), `RenderThread` (syncAndDrawFrame, queueBuffer), `FrameTimeline` (Expected vs Actual with JankType classification), `SurfaceFlinger` (composition timing, present fences), `GPU Completion` (actual GPU work duration).
|
|
83
|
+
- **JankStats API (AndroidX):** Production jank measurement. Auto-adjusts thresholds for 60fps vs 120fps devices. Tags frames with UI state via `PerformanceMetricsState` for correlating jank with user actions. Android 16 adds `AppJankStats` with `RelativeFrameTimeHistogram` for runtime analysis without third-party libraries.
|
|
84
|
+
- **Layout Inspector:** Live view hierarchy with recomposition counts (Compose) or measure/layout/draw timing (Views). Identifies deep nesting and unnecessary recompositions.
|
|
85
|
+
|
|
86
|
+
### iOS
|
|
87
|
+
|
|
88
|
+
- **Core Animation Instrument:** FPS gauge, Color Blended Layers (red=blended/green=opaque), Color Offscreen-Rendered (yellow overlay marks off-screen renders costing 2-5ms context switch each), Color Hits Green and Misses Red (shouldRasterize cache hit rate).
|
|
89
|
+
- **GPU Driver Instrument:** Measures GPU utilization, tiler utilization, renderer utilization. Above 70% sustained utilization risks thermal throttling.
|
|
90
|
+
- **MetricKit (MXSignpostMetric):** Production hitch rate measured as ms of hitch per second of scroll, delivered in 24-hour payloads. Available iOS 14+.
|
|
91
|
+
- **Xcode View Debugger:** 3D visualization of view hierarchy. Identifies unexpected layers and depth issues. Debug > View Debugging > Capture View Hierarchy.
|
|
92
|
+
|
|
93
|
+
### Flutter
|
|
94
|
+
|
|
95
|
+
- **Performance Overlay:** Two graphs -- UI thread (build+layout+paint) and Raster thread (GPU rasterization). Red bars indicate janky frames exceeding budget. Enable via DevTools or programmatically.
|
|
96
|
+
- **DevTools Timeline:** Frame-by-frame analysis showing Build, Layout, Paint, Compositing, and Rasterization phases. Selecting a janky (red) frame surfaces diagnostic hints identifying expensive operations.
|
|
97
|
+
- **Widget Rebuild Indicators:** IDE plugin shows rebuild counts per widget. `debugProfileBuildsEnabled` and `debugProfilePaintsEnabled` flags add granular Timeline events for every build/paint call.
|
|
98
|
+
|
|
99
|
+
### React Native
|
|
100
|
+
|
|
101
|
+
- **Performance Monitor (in-app):** Shows JS FPS (business logic) and UI FPS (native rendering). JS drop without UI drop = JS-side bottleneck. Both dropping = rendering bottleneck.
|
|
102
|
+
- **Flipper:** Plugin ecosystem -- React DevTools for component render timing, Network inspector for blocking requests, Layout Inspector for native view hierarchy.
|
|
103
|
+
- **New Architecture (Fabric + JSI):** JSI enables direct synchronous JS-to-native communication, reducing bridge serialization overhead from 5-15ms per crossing to <1ms.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Common Bottlenecks
|
|
108
|
+
|
|
109
|
+
1. **Expensive layout passes** (2-15ms): Nested `LinearLayout` with `layout_weight` triggers double measure. Complex Auto Layout constraint systems scale O(n^2) in worst cases. Deep `Column`/`Row` with `weight` modifiers causes multi-pass measurement.
|
|
110
|
+
2. **GPU overdraw** (linear GPU cost): Stacked backgrounds on nested views, full-screen semi-transparent overlays, default backgrounds on containers fully covered by children.
|
|
111
|
+
3. **Large bitmap decoding on main thread** (10-200ms): A 12MP image at ARGB_8888 consumes 48MB of memory. Must decode off-thread and downsample to display size.
|
|
112
|
+
4. **Main thread blocking** (any >4ms operation): Database queries, JSON parsing, file I/O steal from frame budget. At 120fps, even a 3ms disk read drops a frame.
|
|
113
|
+
5. **Deep view hierarchies**: A 15-level hierarchy consumes 8-12ms in layout alone. Flat hierarchies with ConstraintLayout or Compose reduce this to 2-4ms.
|
|
114
|
+
6. **Unnecessary invalidations** (1-5ms each): Calling `invalidate()`/`requestLayout()` when no visual change occurred. In Compose, reading state at a wider scope than necessary recomposes entire subtrees.
|
|
115
|
+
7. **Off-screen rendering (iOS)** (2-8ms per layer): `cornerRadius` + `masksToBounds`, shadows without `shadowPath`, `mask` layers, `shouldRasterize` on frequently changing views. Each requires a temporary framebuffer allocation.
|
|
116
|
+
8. **Transparency and alpha blending** (1-3ms): Semi-transparent views force the GPU to read-blend-write vs. opaque skip-read.
|
|
117
|
+
9. **Excessive recomposition** (2-20ms): State change at high scope triggers full-tree rebuild in declarative frameworks. Compose Layout Inspector shows recomposition counts per composable.
|
|
118
|
+
10. **Unoptimized RecyclerView**: Missing `setHasFixedSize(true)`, using `notifyDataSetChanged()` instead of DiffUtil, performing heavy work in `onBindViewHolder`.
|
|
119
|
+
11. **Shadow without cached path** (1-5ms/frame/shadow iOS; 0.5-2ms Android): Core Animation ray-casts the layer's alpha channel every frame without an explicit `shadowPath`.
|
|
120
|
+
12. **Synchronous JS bridge calls (RN old arch)** (5-15ms per crossing): JSON serialization saturates the bridge on high-frequency events like scroll position updates.
|
|
121
|
+
13. **Unbounded lists without recycling**: Using `ScrollView` with hundreds of children creates all views upfront. A list of 1000 moderate-complexity items can consume 200-500MB.
|
|
122
|
+
14. **Texture upload stalls** (2-10ms): Large textures uploaded on the render thread. Use compressed formats (ASTC, ETC2), pre-upload, and limit texture sizes.
|
|
123
|
+
15. **Animating layout properties**: Animating width/height/margin triggers full layout passes (5-15ms/frame). Animating translationX/scaleX/alpha requires draw only (<1ms with hardware layers).
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Optimization Patterns
|
|
128
|
+
|
|
129
|
+
### View Recycling and List Virtualization
|
|
130
|
+
|
|
131
|
+
**Android RecyclerView:**
|
|
132
|
+
```kotlin
|
|
133
|
+
recyclerView.apply {
|
|
134
|
+
setHasFixedSize(true) // Skip measure on data change
|
|
135
|
+
setItemViewCacheSize(20) // Cache 20 views for fast re-bind
|
|
136
|
+
recycledViewPool.setMaxRecycledViews(0, 30) // Pool 30 type-0 views
|
|
137
|
+
adapter = MyListAdapter(differ) // ListAdapter with DiffUtil
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
DiffUtil reduces rebind operations by 60-90% compared to `notifyDataSetChanged()`.
|
|
141
|
+
|
|
142
|
+
**Compose LazyColumn:** Use stable `key = { it.id }`, extract composables with narrow state scope, paginate data layer (Compose is lazy but the data layer is eager -- 10,000 items in memory defeats the purpose).
|
|
143
|
+
|
|
144
|
+
**iOS UICollectionView:** Cell reuse with `dequeueReusableCell`, prefetching via `UICollectionViewDataSourcePrefetching` (iOS 10+). iOS 15 improved prefetching to prepare the next cell in spare time after short commits. Cache cell heights for dynamic sizing to avoid recalculating during layout passes.
|
|
145
|
+
|
|
146
|
+
**SwiftUI:** `List` (backed by UICollectionView) outperforms `LazyVStack` for large datasets -- 5.53s vs 52.3s to scroll to bottom in benchmarks. As of iOS 18, both have good recycling but List edges ahead on stability with dynamically-sized content.
|
|
147
|
+
|
|
148
|
+
**React Native FlashList v2 (2025):** Complete rewrite by Shopify. Eliminates item size estimates, delivers pixel-perfect scrolling. Use `React.memo()` on list items. Set `windowSize` to 10-15 for optimal memory/performance balance.
|
|
149
|
+
|
|
150
|
+
### Flat View Hierarchies
|
|
151
|
+
|
|
152
|
+
Replace nested `LinearLayout` (12 levels, 3 measure passes) with `ConstraintLayout` (2 levels, 1 measure pass). **Impact:** 4-8ms saved per layout pass. In Compose, avoid deeply nested `Column`/`Row` with `weight`; use `Modifier.weight()` at a single level.
|
|
153
|
+
|
|
154
|
+
### Hardware Layers for Animation (Android)
|
|
155
|
+
|
|
156
|
+
```kotlin
|
|
157
|
+
// Enable hardware layer for duration of animation only
|
|
158
|
+
view.animate()
|
|
159
|
+
.translationX(300f)
|
|
160
|
+
.withLayer() // Manages hardware layer lifecycle automatically (API 16+)
|
|
161
|
+
.setDuration(300)
|
|
162
|
+
.start()
|
|
163
|
+
```
|
|
164
|
+
Caches view as GPU texture -- transform/alpha animations become nearly free (GPU just repositions the texture). **Saves 3-10ms/frame** on complex views. Critical caveat: calling `invalidate()` during animation forces re-rendering the layer cache, negating all benefit and adding overhead.
|
|
165
|
+
|
|
166
|
+
### Shadow Path Optimization (iOS)
|
|
167
|
+
|
|
168
|
+
```swift
|
|
169
|
+
// Explicit path: computed once, cached by Core Animation (<0.1ms/frame)
|
|
170
|
+
cell.layer.shadowPath = UIBezierPath(
|
|
171
|
+
roundedRect: cell.bounds, cornerRadius: 12
|
|
172
|
+
).cgPath
|
|
173
|
+
```
|
|
174
|
+
Without this, Core Animation ray-casts the alpha channel every frame (2-5ms per shadow). **Saves 20-50ms/frame** for a list with 10 visible cells with shadows.
|
|
175
|
+
|
|
176
|
+
### RepaintBoundary (Flutter)
|
|
177
|
+
|
|
178
|
+
Wrap static widgets adjacent to animated ones. Creates a separate GPU layer, isolating paint work. **Reduces paint time 40-80%** for complex static subtrees. Does NOT help with build or layout bottlenecks -- only painting. Overuse increases GPU memory consumption.
|
|
179
|
+
|
|
180
|
+
### Bitmap Optimization
|
|
181
|
+
|
|
182
|
+
Downsample before decode: a 4000x3000 ARGB_8888 image (48MB) at 4x downsample to RGB_565 becomes 500x375 at 366KB -- a **130x memory reduction**. Always decode on a background thread. Use image loading libraries (Glide, Coil, Kingfisher, Nuke, `cached_network_image`) that handle this automatically.
|
|
183
|
+
|
|
184
|
+
### Overdraw Reduction
|
|
185
|
+
|
|
186
|
+
Remove unnecessary backgrounds on intermediate containers. Remove the window default background when your layout covers the entire screen:
|
|
187
|
+
```kotlin
|
|
188
|
+
window.setBackgroundDrawable(null)
|
|
189
|
+
// Or in theme: <item name="android:windowBackground">@null</item>
|
|
190
|
+
```
|
|
191
|
+
**30-50% GPU fragment shader savings** reducing from 3x to 1x overdraw.
|
|
192
|
+
|
|
193
|
+
### Batching Property Updates (iOS)
|
|
194
|
+
|
|
195
|
+
```swift
|
|
196
|
+
CATransaction.begin()
|
|
197
|
+
CATransaction.setDisableActions(true) // Suppress implicit animations
|
|
198
|
+
layer.cornerRadius = 8
|
|
199
|
+
layer.shadowOpacity = 0.5
|
|
200
|
+
layer.backgroundColor = UIColor.white.cgColor
|
|
201
|
+
CATransaction.commit() // Single render pass for all changes
|
|
202
|
+
```
|
|
203
|
+
Reduces implicit animation overhead by ~20% CPU and batches GPU work.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Anti-Patterns
|
|
208
|
+
|
|
209
|
+
1. **Nested ScrollViews** -- defeats virtualization; a 500-item inner list creates all views upfront.
|
|
210
|
+
2. **Full-screen transparent overlays** -- adds 1x overdraw to every pixel on screen.
|
|
211
|
+
3. **Complex clip paths/masks** -- trigger off-screen rendering with per-layer framebuffer allocation.
|
|
212
|
+
4. **`notifyDataSetChanged()` on large lists** -- full rebind, no animation. Use DiffUtil for 60-80% improvement.
|
|
213
|
+
5. **Synchronous image loading in list items** -- blocks main thread 10-200ms per image.
|
|
214
|
+
6. **Reading scroll position at composition root** -- recomposes entire screen 60x/second during scroll. Use `derivedStateOf` and read at the narrowest possible scope.
|
|
215
|
+
7. **`shouldRasterize` on dynamic content (iOS)** -- re-rasterizes every frame, slower than no rasterization. Only use for static or rarely-changing complex layer trees.
|
|
216
|
+
8. **Missing `key` in lazy lists** -- causes unnecessary recomposition, state loss, and animation glitches when list order changes.
|
|
217
|
+
9. **Object allocation in `draw()`/`onDraw()`** -- runs 60-120x/second, triggers GC pauses visible as frame drops. Pre-allocate Paint objects and paths.
|
|
218
|
+
10. **`elevation` on every list item (Android)** -- 20 visible elevated items generate 20 shadow computations per frame. Use elevation sparingly; consider container-level shadows.
|
|
219
|
+
11. **Animating layout properties (width/height/margin)** -- triggers full layout pass (5-15ms/frame) vs transform animations (<1ms with hardware layers).
|
|
220
|
+
12. **Unbounded `Column`/`Row` for large data** -- creates all items at once; always use `LazyColumn`/`LazyRow`/`LazyVStack`.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Architecture-Level Decisions
|
|
225
|
+
|
|
226
|
+
### Declarative vs. Imperative UI
|
|
227
|
+
|
|
228
|
+
- **Declarative (Compose, SwiftUI, Flutter):** Automatic diffing, flat-by-design hierarchies, simplified state management. Recomposition/rebuild scope management is critical -- naive implementations are 20-40% slower than optimized imperative code. Compose skips unchanged composables; SwiftUI diffs the body; Flutter diffs the element tree.
|
|
229
|
+
- **Imperative (UIKit, Android Views):** Fine-grained control over exactly what updates. No diffing overhead. Manual invalidation management is error-prone -- forgetting to invalidate causes stale UI; over-invalidating causes jank.
|
|
230
|
+
|
|
231
|
+
### State Management Impact on Rendering
|
|
232
|
+
|
|
233
|
+
| Pattern | Rendering Impact |
|
|
234
|
+
|---------|-----------------|
|
|
235
|
+
| Global store (Redux-style) | Any state change can trigger full re-render without granular selectors |
|
|
236
|
+
| Scoped state (Provider, Riverpod) | Updates limited to the subtree that reads the state |
|
|
237
|
+
| Observable per-field (MobX, LiveData) | Most granular; only widgets reading the changed field update |
|
|
238
|
+
| Unidirectional data flow | Predictable but requires careful mapping to avoid cascading updates |
|
|
239
|
+
|
|
240
|
+
**Key principle:** Observation granularity determines minimum recomposition scope. Coarse observation (reading an entire model) causes wider rebuilds than fine observation (reading a single field).
|
|
241
|
+
|
|
242
|
+
### Rendering Thread Architecture
|
|
243
|
+
|
|
244
|
+
| Framework | Architecture | Implication |
|
|
245
|
+
|-----------|-------------|-------------|
|
|
246
|
+
| Android Views/Compose | UI Thread + RenderThread | Layout on UI thread; GPU commands on RenderThread. Heavy layout blocks input. |
|
|
247
|
+
| iOS UIKit | Main Thread only | All layout, drawing, and compositing on main thread. GPU work via Core Animation. |
|
|
248
|
+
| Flutter | UI Thread + Raster Thread | Widget build/layout on UI thread; Skia/Impeller rasterization on separate thread. |
|
|
249
|
+
| React Native (New Arch) | JS + UI + Render Thread | JSI removes bridge; Fabric renders on native threads. |
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Testing & Regression Prevention
|
|
254
|
+
|
|
255
|
+
### Automated Frame Rate Testing
|
|
256
|
+
|
|
257
|
+
**Android Macrobenchmark:**
|
|
258
|
+
```kotlin
|
|
259
|
+
@get:Rule val benchmarkRule = MacrobenchmarkRule()
|
|
260
|
+
|
|
261
|
+
@Test fun scrollPerformance() {
|
|
262
|
+
benchmarkRule.measureRepeated(
|
|
263
|
+
packageName = "com.example.app",
|
|
264
|
+
metrics = listOf(FrameTimingMetric()),
|
|
265
|
+
iterations = 5,
|
|
266
|
+
startupMode = StartupMode.WARM,
|
|
267
|
+
) {
|
|
268
|
+
val list = device.findObject(By.res("item_list"))
|
|
269
|
+
list.setGestureMargin(device.displayWidth / 5)
|
|
270
|
+
list.fling(Direction.DOWN)
|
|
271
|
+
device.waitForIdle()
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// Assert: P50 <12ms, P95 <16ms, P99 <32ms
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**iOS XCTest Performance Metrics:**
|
|
278
|
+
```swift
|
|
279
|
+
func testScrollPerformance() throws {
|
|
280
|
+
let app = XCUIApplication()
|
|
281
|
+
app.launch()
|
|
282
|
+
measure(metrics: [XCTOSSignpostMetric.scrollDecelerationMetric]) {
|
|
283
|
+
app.collectionViews.firstMatch.swipeUp(velocity: .fast)
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Flutter Integration Test:**
|
|
289
|
+
```dart
|
|
290
|
+
testWidgets('scroll performance', (tester) async {
|
|
291
|
+
await tester.pumpWidget(MyApp());
|
|
292
|
+
final timeline = await tester.traceAction(() async {
|
|
293
|
+
await tester.fling(find.byType(ListView), Offset(0, -500), 10000);
|
|
294
|
+
await tester.pumpAndSettle();
|
|
295
|
+
});
|
|
296
|
+
final summary = TimelineSummary.summarize(timeline);
|
|
297
|
+
expect(summary.computeMissedFrameBuildBudgetCount(), lessThan(5));
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### CI Strategy
|
|
302
|
+
|
|
303
|
+
1. **Baseline:** Run frame timing benchmarks on a reference device; record P50/P95/P99 frame times.
|
|
304
|
+
2. **Regression gate:** Fail the build if P95 regresses by >20% or jank rate exceeds 5%.
|
|
305
|
+
3. **Device matrix:** Test on at least one low-end device (Pixel 3a, Galaxy A13) and one flagship. Low-end devices expose bottlenecks that flagships mask with raw power.
|
|
306
|
+
4. **Thermal conditioning:** Run benchmarks after a 30-second warm-up period to capture thermally-throttled performance, which reflects real-world conditions.
|
|
307
|
+
|
|
308
|
+
### Production Monitoring
|
|
309
|
+
|
|
310
|
+
Deploy JankStats to production builds with sampling (10% of sessions):
|
|
311
|
+
```kotlin
|
|
312
|
+
val jankStats = JankStats.createAndTrack(window) { frameData ->
|
|
313
|
+
if (frameData.isJank) {
|
|
314
|
+
analytics.report(
|
|
315
|
+
frameDurationMs = frameData.frameDurationUiNanos / 1_000_000.0,
|
|
316
|
+
states = frameData.states // e.g., "Screen:ProductList", "Action:Scrolling"
|
|
317
|
+
)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
metricsState.putState("Screen", "ProductList")
|
|
321
|
+
metricsState.putState("Action", "Scrolling")
|
|
322
|
+
```
|
|
323
|
+
Correlate jank reports with screen names and user actions to prioritize optimization efforts.
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Decision Trees
|
|
328
|
+
|
|
329
|
+
### "My App Is Janky During Scroll"
|
|
330
|
+
|
|
331
|
+
```
|
|
332
|
+
START: Identify which thread is over budget
|
|
333
|
+
|
|
|
334
|
+
+-- Is UI/main thread over budget?
|
|
335
|
+
| +-- Layout >8ms?
|
|
336
|
+
| | --> Flatten hierarchy (ConstraintLayout / Compose / SwiftUI)
|
|
337
|
+
| +-- onBind / cellForRow expensive?
|
|
338
|
+
| | --> Move work off main thread; cache computed values
|
|
339
|
+
| +-- Synchronous image loading?
|
|
340
|
+
| | --> Use async library (Glide/Coil/Kingfisher/cached_network_image)
|
|
341
|
+
| +-- GC pauses visible in trace?
|
|
342
|
+
| | --> Eliminate allocations in draw/bind; pre-allocate objects
|
|
343
|
+
| +-- None of the above?
|
|
344
|
+
| --> Profile with Perfetto / Instruments for unexpected work
|
|
345
|
+
|
|
|
346
|
+
+-- Is GPU/raster thread over budget?
|
|
347
|
+
| +-- Overdraw >2x?
|
|
348
|
+
| | --> Remove unnecessary backgrounds; flatten hierarchy
|
|
349
|
+
| +-- Shadows without explicit path?
|
|
350
|
+
| | --> Add shadowPath (iOS) or reduce elevation count (Android)
|
|
351
|
+
| +-- Large bitmap uploads (purple bars)?
|
|
352
|
+
| | --> Downsample; use compressed textures (ASTC/ETC2); pre-upload
|
|
353
|
+
| +-- Off-screen rendering (yellow in Instruments)?
|
|
354
|
+
| --> Eliminate masks/complex clips; use optimized cornerRadius
|
|
355
|
+
|
|
|
356
|
+
+-- Both threads fine but still janky?
|
|
357
|
+
--> Check vsync alignment (Choreographer scheduling issues)
|
|
358
|
+
--> Check thermal throttling (run sustained-load benchmark)
|
|
359
|
+
--> Check background thread contention (lock contention on main thread)
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### "Should I Use a Hardware Layer?"
|
|
363
|
+
|
|
364
|
+
```
|
|
365
|
+
START: What property are you animating?
|
|
366
|
+
|
|
|
367
|
+
+-- Translation, Scale, Rotation, or Alpha?
|
|
368
|
+
| +-- Is the view complex (>20 child views or custom drawing)?
|
|
369
|
+
| | +-- Will view content change during animation (invalidate called)?
|
|
370
|
+
| | | --> NO: layer re-render negates caching benefit
|
|
371
|
+
| | | --> YES (content static): USE hardware layer (saves 3-10ms/frame)
|
|
372
|
+
| | +-- View is simple (<20 children)?
|
|
373
|
+
| | --> Benefit is <1ms; measure before adding
|
|
374
|
+
| |
|
|
375
|
+
| +-- Using ViewPropertyAnimator?
|
|
376
|
+
| --> Use .withLayer() for automatic lifecycle management
|
|
377
|
+
|
|
|
378
|
+
+-- Layout properties (width, height, margin, padding)?
|
|
379
|
+
--> CANNOT use hardware layer (layout change invalidates it)
|
|
380
|
+
--> Refactor: animate scaleX/scaleY or translationX/Y instead
|
|
381
|
+
--> If layout animation is truly required: keep view hierarchy minimal
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### "When to Use RepaintBoundary (Flutter)"
|
|
385
|
+
|
|
386
|
+
```
|
|
387
|
+
START: Is a subtree repainting unnecessarily?
|
|
388
|
+
|
|
|
389
|
+
+-- Widget is static while a sibling animates?
|
|
390
|
+
| +-- Static widget is expensive to paint (custom paint, many children)?
|
|
391
|
+
| | --> YES: Wrap with RepaintBoundary (saves 2-15ms/frame)
|
|
392
|
+
| +-- Static widget is cheap to paint?
|
|
393
|
+
| --> Benefit is marginal; measure with debugProfilePaintsEnabled first
|
|
394
|
+
|
|
|
395
|
+
+-- Widget animates independently?
|
|
396
|
+
| +-- Other widgets repainting because of this animation?
|
|
397
|
+
| | --> Wrap the ANIMATED widget with RepaintBoundary
|
|
398
|
+
| +-- Already isolated (no sibling repaints)?
|
|
399
|
+
| --> No benefit from RepaintBoundary
|
|
400
|
+
|
|
|
401
|
+
NOTE: RepaintBoundary only affects PAINT phase.
|
|
402
|
+
If build() or layout is the bottleneck, use const constructors,
|
|
403
|
+
stable keys, and narrower state scoping instead.
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## Code Examples
|
|
409
|
+
|
|
410
|
+
### 1. Overdraw Elimination (Android)
|
|
411
|
+
|
|
412
|
+
```xml
|
|
413
|
+
<!-- BEFORE: 4x overdraw, 22ms frame time on Pixel 4a -->
|
|
414
|
+
<FrameLayout android:background="@color/gray_bg"> <!-- Draw 1 -->
|
|
415
|
+
<CardView android:background="@color/white" <!-- Draw 2 -->
|
|
416
|
+
app:cardBackgroundColor="@color/white"> <!-- Draw 3 -->
|
|
417
|
+
<LinearLayout android:background="@color/white"> <!-- Draw 4 -->
|
|
418
|
+
<TextView android:text="Title" />
|
|
419
|
+
</LinearLayout>
|
|
420
|
+
</CardView>
|
|
421
|
+
</FrameLayout>
|
|
422
|
+
|
|
423
|
+
<!-- AFTER: 1x overdraw, 11ms frame time on Pixel 4a (50% improvement) -->
|
|
424
|
+
<CardView app:cardBackgroundColor="@color/white">
|
|
425
|
+
<TextView android:text="Title" />
|
|
426
|
+
</CardView>
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### 2. iOS Shadow Performance
|
|
430
|
+
|
|
431
|
+
```swift
|
|
432
|
+
// BEFORE: 38ms with 8 visible cells (per-frame ray-casting, no shadowPath)
|
|
433
|
+
cell.layer.shadowColor = UIColor.black.cgColor
|
|
434
|
+
cell.layer.shadowOffset = CGSize(width: 0, height: 2)
|
|
435
|
+
cell.layer.shadowOpacity = 0.15
|
|
436
|
+
cell.layer.shadowRadius = 8
|
|
437
|
+
// Core Animation computes shadow shape every frame: 4-5ms per cell
|
|
438
|
+
|
|
439
|
+
// AFTER: 9ms with 8 visible cells (76% improvement)
|
|
440
|
+
cell.layer.shadowColor = UIColor.black.cgColor
|
|
441
|
+
cell.layer.shadowOffset = CGSize(width: 0, height: 2)
|
|
442
|
+
cell.layer.shadowOpacity = 0.15
|
|
443
|
+
cell.layer.shadowRadius = 8
|
|
444
|
+
cell.layer.shadowPath = UIBezierPath(
|
|
445
|
+
roundedRect: cell.bounds, cornerRadius: 12
|
|
446
|
+
).cgPath // Computed once, cached: <0.1ms per cell
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### 3. Compose Recomposition Scoping
|
|
450
|
+
|
|
451
|
+
```kotlin
|
|
452
|
+
// BEFORE: 45ms frame time -- entire list recomposes on every timer tick
|
|
453
|
+
@Composable fun ProductScreen(vm: ProductViewModel) {
|
|
454
|
+
val countdown by vm.countdown.collectAsState() // Read at root scope
|
|
455
|
+
Column {
|
|
456
|
+
Text("Sale ends in: $countdown")
|
|
457
|
+
LazyColumn {
|
|
458
|
+
items(products, key = { it.id }) { ProductCard(it) } // ALL recompose
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// AFTER: 4ms frame time (91% improvement) -- only banner recomposes
|
|
464
|
+
@Composable fun ProductScreen(vm: ProductViewModel) {
|
|
465
|
+
Column {
|
|
466
|
+
CountdownBanner(vm) // Isolated recomposition scope
|
|
467
|
+
LazyColumn {
|
|
468
|
+
items(products, key = { it.id }) { ProductCard(it) } // Stable, skipped
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
@Composable private fun CountdownBanner(vm: ProductViewModel) {
|
|
474
|
+
val countdown by vm.countdown.collectAsState() // Only this scope recomposes
|
|
475
|
+
Text("Sale ends in: $countdown")
|
|
476
|
+
}
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### 4. Flutter RepaintBoundary + const Optimization
|
|
480
|
+
|
|
481
|
+
```dart
|
|
482
|
+
// BEFORE: 24ms frame time -- full repaint on scroll
|
|
483
|
+
ListView.builder(
|
|
484
|
+
itemCount: items.length,
|
|
485
|
+
itemBuilder: (ctx, i) => Card(
|
|
486
|
+
child: Column(children: [
|
|
487
|
+
Image.network(items[i].imageUrl), // Triggers repaint
|
|
488
|
+
Text(items[i].title),
|
|
489
|
+
Icon(Icons.arrow_forward), // Rebuilds every time
|
|
490
|
+
]),
|
|
491
|
+
),
|
|
492
|
+
)
|
|
493
|
+
|
|
494
|
+
// AFTER: 8ms frame time (67% improvement)
|
|
495
|
+
ListView.builder(
|
|
496
|
+
itemCount: items.length,
|
|
497
|
+
itemBuilder: (ctx, i) => RepaintBoundary(
|
|
498
|
+
child: Card(
|
|
499
|
+
child: Column(children: [
|
|
500
|
+
CachedNetworkImage(imageUrl: items[i].imageUrl), // Cached loading
|
|
501
|
+
Text(items[i].title),
|
|
502
|
+
const Icon(Icons.arrow_forward), // const = never rebuilds
|
|
503
|
+
]),
|
|
504
|
+
),
|
|
505
|
+
),
|
|
506
|
+
)
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### 5. React Native FlatList to FlashList v2 Migration
|
|
510
|
+
|
|
511
|
+
```typescript
|
|
512
|
+
// BEFORE: 18ms JS frame time with default FlatList
|
|
513
|
+
<FlatList
|
|
514
|
+
data={items}
|
|
515
|
+
renderItem={({ item }) => (
|
|
516
|
+
<View style={styles.card}>
|
|
517
|
+
<Image source={{ uri: item.image }} style={styles.image} />
|
|
518
|
+
<Text>{item.title}</Text>
|
|
519
|
+
</View>
|
|
520
|
+
)}
|
|
521
|
+
/>
|
|
522
|
+
|
|
523
|
+
// AFTER: 6ms JS frame time (67% improvement) with FlashList v2 + memoization
|
|
524
|
+
import { FlashList } from "@shopify/flash-list";
|
|
525
|
+
|
|
526
|
+
const MemoizedCard = React.memo(({ item }) => (
|
|
527
|
+
<View style={styles.card}>
|
|
528
|
+
<FastImage source={{ uri: item.image }} style={styles.image} />
|
|
529
|
+
<Text>{item.title}</Text>
|
|
530
|
+
</View>
|
|
531
|
+
));
|
|
532
|
+
|
|
533
|
+
<FlashList
|
|
534
|
+
data={items}
|
|
535
|
+
renderItem={({ item }) => <MemoizedCard item={item} />}
|
|
536
|
+
estimatedItemSize={100}
|
|
537
|
+
keyExtractor={(item) => item.id}
|
|
538
|
+
/>
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
### 6. Android Bitmap Optimization
|
|
542
|
+
|
|
543
|
+
```kotlin
|
|
544
|
+
// BEFORE: 48MB allocation, 150ms main-thread block for 12MP image
|
|
545
|
+
val bitmap = BitmapFactory.decodeFile(path) // Full resolution, main thread
|
|
546
|
+
|
|
547
|
+
// AFTER: 366KB allocation, 0ms main-thread block
|
|
548
|
+
withContext(Dispatchers.IO) {
|
|
549
|
+
val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
|
|
550
|
+
BitmapFactory.decodeFile(path, options)
|
|
551
|
+
options.inSampleSize = calculateInSampleSize(options, targetWidth = 400)
|
|
552
|
+
options.inJustDecodeBounds = false
|
|
553
|
+
options.inPreferredConfig = Bitmap.Config.RGB_565 // 2 bytes vs 4 bytes/pixel
|
|
554
|
+
val bitmap = BitmapFactory.decodeFile(path, options)
|
|
555
|
+
withContext(Dispatchers.Main) { imageView.setImageBitmap(bitmap) }
|
|
556
|
+
}
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
---
|
|
560
|
+
|
|
561
|
+
## Quick Reference
|
|
562
|
+
|
|
563
|
+
| Metric | Excellent | Good | Acceptable | Needs Work | Critical |
|
|
564
|
+
|--------|-----------|------|------------|------------|----------|
|
|
565
|
+
| P50 frame time (60fps) | <10ms | <12ms | <14ms | <16ms | >16ms |
|
|
566
|
+
| P95 frame time (60fps) | <14ms | <16ms | <20ms | <32ms | >32ms |
|
|
567
|
+
| P99 frame time (60fps) | <16ms | <24ms | <32ms | <50ms | >50ms |
|
|
568
|
+
| Jank rate | <1% | <3% | <5% | <10% | >10% |
|
|
569
|
+
| Frozen frames (>700ms) | 0% | <0.05% | <0.1% | <0.5% | >0.5% |
|
|
570
|
+
| GPU overdraw (avg) | 1.0x | 1.5x | 2.0x | 2.5x | >3.0x |
|
|
571
|
+
| View hierarchy depth | <5 | <8 | <10 | <12 | >15 |
|
|
572
|
+
|
|
573
|
+
### Platform Profiling Quick Reference
|
|
574
|
+
|
|
575
|
+
| Task | Android | iOS | Flutter | React Native |
|
|
576
|
+
|------|---------|-----|---------|--------------|
|
|
577
|
+
| Frame timing | Perfetto FrameTimeline | Core Animation Instrument | Performance Overlay | Perf Monitor |
|
|
578
|
+
| View hierarchy | Layout Inspector | View Debugger (3D) | Widget Inspector | Flipper Layout |
|
|
579
|
+
| GPU overdraw | Dev Options debug | Color Blended Layers | N/A (native layer) | N/A (native layer) |
|
|
580
|
+
| Memory | Android Profiler | Instruments Allocations | Observatory | Flipper + Hermes |
|
|
581
|
+
| Production | JankStats + Play Vitals | MetricKit + Organizer | Custom (Sentry) | Sentry / custom |
|
|
582
|
+
| Jank detection | JankStats / AppJankStats | MXSignpostMetric | Timeline janky frames | JS/UI FPS monitor |
|
|
583
|
+
|
|
584
|
+
### Optimization Priority Order
|
|
585
|
+
|
|
586
|
+
1. Remove main thread blocking (I/O, network, heavy computation) -- highest impact, easiest fix
|
|
587
|
+
2. Enable view recycling (RecyclerView, LazyColumn, UICollectionView, FlashList)
|
|
588
|
+
3. Flatten view hierarchy -- reduces layout time 40-70%
|
|
589
|
+
4. Eliminate overdraw -- reduces GPU work 30-50%
|
|
590
|
+
5. Add explicit shadow paths (iOS) -- eliminates off-screen rendering
|
|
591
|
+
6. Optimize images (async loading, downsampling, caching) -- prevents 10-200ms stalls
|
|
592
|
+
7. Scope state/recomposition -- prevents unnecessary UI rebuilds
|
|
593
|
+
8. Use hardware layers for animations (Android) -- saves 3-10ms/frame
|
|
594
|
+
9. Add RepaintBoundary (Flutter) / drawingGroup (SwiftUI) -- isolates paint work
|
|
595
|
+
10. Profile and optimize custom drawing -- last resort, highest expertise required
|
|
596
|
+
|
|
597
|
+
---
|
|
598
|
+
|
|
599
|
+
*Researched: 2026-03-08 | Sources: [Android -- Slow Rendering](https://developer.android.com/topic/performance/vitals/render), [Android -- Reduce Overdraw](https://developer.android.com/topic/performance/rendering/overdraw), [Android -- JankStats](https://developer.android.com/topic/performance/jankstats), [Android -- Hardware Acceleration](https://developer.android.com/develop/ui/views/graphics/hardware-accel), [Perfetto -- Vsync Mechanism](https://androidperformance.com/en/2025/08/05/Android-Perfetto-08-Vsync/), [Perfetto -- MainThread & RenderThread](https://androidperformance.com/en/2025/08/02/Android-Perfetto-07-MainThread-And-RenderThread/), [Perfetto -- FrameTimeline Jank Detection](https://perfetto.dev/docs/data-sources/frametimeline), [Apple -- Improving Animation Performance](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/ImprovingAnimationPerformance/ImprovingAnimationPerformance.html), [Apple -- Performant Scrollable Stacks](https://developer.apple.com/documentation/swiftui/creating-performant-scrollable-stacks), [Apple WWDC21 -- Blazing Fast Lists](https://developer.apple.com/videos/play/wwdc2021/10252/), [Flutter -- Performance Best Practices](https://docs.flutter.dev/perf/best-practices), [Flutter -- RepaintBoundary](https://api.flutter.dev/flutter/widgets/RepaintBoundary-class.html), [React Native -- FlatList Optimization](https://reactnative.dev/docs/optimizing-flatlist-configuration), [Shopify -- FlashList v2](https://shopify.engineering/flashlist-v2), [Dan Lew -- Hardware Layers](https://blog.danlew.net/2015/10/20/using-hardware-layers-to-improve-animation-performance/), [SwiftUI 120FPS Challenge](https://blog.jacobstechtavern.com/p/swiftui-scroll-performance-the-120fps), [iOS Off-Screen Rendering](https://github.com/seedante/OptimizationForOffscreenRender), [Amazon Latency Study](https://www.gigaspaces.com/blog/amazon-found-every-100ms-of-latency-cost-them-1-in-sales/), [Google -- Mobile Speed](https://blog.google/products/admanager/the-need-for-mobile-speed/), [XDA -- Thermal Throttling](https://www.xda-developers.com/silent-killer-of-your-phones-performance-thermal-throttling/), [Bitdrift -- JankStats Integration](https://blog.bitdrift.io/post/jank-stats-integration), [Play Console -- Android Vitals](https://support.google.com/googleplay/android-developer/answer/9844486)*
|