---
name: report-shopify-performance
description: Measure Shopify page weight, TTFB, FCP, LCP, CLS, INP, asset count and script count across representative routes and viewports. Use for performance baselines and comparisons; create Issues only for target-proven causes. Read-only.
---

# Instructions

Measure storefront performance across representative routes and viewports. Provide a storefront or reachable preview URL and optional routes. Follow the [performance workflow](references/workflows/performance.md) before collecting evidence.

Use available browser and measurement tools; retain supported metrics when another method or metric is unavailable. A repository, shell or integration is not required. Preview setup belongs to `$preview-shopify-theme`; do not install packages, generate data or start servers during reporting. Record simulation identity and limits from its `references/tools/local-storefront.md#evidence-and-report-use`.

Return the eight declared metrics with route, viewport, method, sample details and exact blockers. Keep field and lab evidence distinct; local timings cannot establish production or field performance. Neutral measurements are Data. Create an Issue only for a directly supported cause and comparable retest. Keep the report read-only.

Follow [Glue JSON output](references/core/glue-output.md): save, validate and read back the complete `report.json`, then link it with a readable summary of every Issue. Use the bundled schema unless the host supplies one. In Glue, return the bare object through its runtime; Glue handles storage and rendering.

## Host integration

```glue-review-setup
{
  "schemaVersion": 2,
  "goal": "Create a repeatable Shopify storefront performance baseline and identify only target-proven causes that warrant action.",
  "context": [
    { "id": "target_url", "label": "Storefront URL", "type": "url", "required": true },
    { "id": "routes", "label": "Pages to test", "type": "route_list", "required": false, "description": "(Optional) Enter one path per line, or leave blank to test the homepage and first available collection and product." }
  ],
  "integrations": [],
  "categories": [],
  "batches": [
    { "id": "measure", "label": "Measure storefront performance", "categoryIds": [] }
  ],
  "reporting": {
    "allowedResultTypes": ["data", "issue"],
    "data": [
      { "key": "page-size", "label": "Page size", "unit": "bytes", "precision": 0, "direction": "lower_is_better", "dimensions": ["route", "viewport", "method"] },
      { "key": "time-to-first-byte", "label": "Time to First Byte", "unit": "milliseconds", "precision": 0, "direction": "lower_is_better", "dimensions": ["route", "viewport", "method"] },
      { "key": "first-contentful-paint", "label": "First Contentful Paint", "unit": "milliseconds", "precision": 0, "direction": "lower_is_better", "dimensions": ["route", "viewport", "method"] },
      { "key": "largest-contentful-paint", "label": "Largest Contentful Paint", "unit": "milliseconds", "precision": 0, "direction": "lower_is_better", "dimensions": ["route", "viewport", "method"] },
      { "key": "cumulative-layout-shift", "label": "Cumulative Layout Shift", "unit": "score", "precision": 3, "direction": "lower_is_better", "dimensions": ["route", "viewport", "method"] },
      { "key": "interaction-to-next-paint", "label": "Interaction to Next Paint", "unit": "milliseconds", "precision": 0, "direction": "lower_is_better", "dimensions": ["route", "viewport", "method"] },
      { "key": "asset-count", "label": "Asset count", "unit": "count", "precision": 0, "direction": "lower_is_better", "dimensions": ["route", "viewport", "method"] },
      { "key": "script-count", "label": "Script count", "unit": "count", "precision": 0, "direction": "lower_is_better", "dimensions": ["route", "viewport", "method"] }
    ]
  },
  "completionRules": [
    "Every selected Check reaches exactly one terminal outcome.",
    "Return every safely measurable Data item for each selected route and required viewport without substituting one metric for another.",
    "Create an Issue only when target-bound evidence supports a concrete cause, owner, recommendation, and comparable retest."
  ],
  "safetyRules": [
    "Measure with read-only requests and browser interactions.",
    "Never edit, upload, publish, purchase, message, create an account, enter payment, or change repository, customer, or store data."
  ]
}
```

```glue-review-catalog
[
  { "id": "performance.page-size", "title": "Measure page size", "preferredOutput": "data", "dataKey": "page-size", "evidence": ["text"], "version": 1 },
  { "id": "performance.time-to-first-byte", "title": "Measure Time to First Byte", "preferredOutput": "data", "dataKey": "time-to-first-byte", "evidence": ["text"], "version": 1 },
  { "id": "performance.first-contentful-paint", "title": "Measure First Contentful Paint", "preferredOutput": "data", "dataKey": "first-contentful-paint", "evidence": ["text"], "version": 1 },
  { "id": "performance.largest-contentful-paint", "title": "Measure Largest Contentful Paint", "preferredOutput": "data", "dataKey": "largest-contentful-paint", "evidence": ["text"], "version": 1 },
  { "id": "performance.cumulative-layout-shift", "title": "Measure Cumulative Layout Shift", "preferredOutput": "data", "dataKey": "cumulative-layout-shift", "evidence": ["text"], "version": 1 },
  { "id": "performance.interaction-to-next-paint", "title": "Measure Interaction to Next Paint", "preferredOutput": "data", "dataKey": "interaction-to-next-paint", "evidence": ["text"], "version": 1 },
  { "id": "performance.asset-count", "title": "Count transferred assets", "preferredOutput": "data", "dataKey": "asset-count", "evidence": ["text"], "version": 1 },
  { "id": "performance.script-count", "title": "Count loaded scripts", "preferredOutput": "data", "dataKey": "script-count", "evidence": ["text"], "version": 1 }
]
```
