All skills
asyrafhussin avatar

/seo-best-practices

@46bae0b

SEO patterns, conventions, and audit for web applications. Use when implementing meta tags, structured data, Core Web Vitals, sitemaps, Open Graph, auditing SEO, or optimizing pages for search engines. Triggers on "audit SEO", "check SEO", "review SEO", or tasks involving search optimization, schema markup, or social sharing meta tags.

Use this Skill: https://skilld.dev/gh/asyrafhussin/agent-skills/seo-best-practices

This session only. Nothing lands on disk.

rulescwv-inp.md

≈1.1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Interaction to Next Paint Optimization

Impact: CRITICAL (Must be under 200ms (replaced FID in March 2024))

INP measures the latency of every click, tap, and keyboard interaction throughout a page visit, reporting the worst interaction. Since March 2024, INP replaced First Input Delay as a Core Web Vital ranking signal, making responsive interactions essential for SEO.

Incorrect

// ❌ Bad: synchronous heavy computation blocks the main thread on click
export default function ProductFilter({ products }: { products: Product[] }) {
  const handleFilter = (category: string) => {
    // Long-running synchronous task blocks UI for 500ms+
    const filtered = products.filter((product) => {
      // Expensive computation per item
      const score = calculateRelevanceScore(product, category);
      const normalized = normalizeAcrossDataset(score, products);
      return normalized > 0.5;
    });

    // DOM update only happens after entire computation finishes
    setFilteredProducts(filtered);
    updateURL(category);
    trackAnalytics("filter", category);
  };

  return (
    <button onClick={() => handleFilter("electronics")}>
      Filter Electronics
    </button>
  );
}

Problems:

  • The entire filtering, normalization, and DOM update runs synchronously, blocking the main thread
  • The browser cannot paint the next frame until the handler completes, causing visible lag
  • Analytics and URL updates further extend the blocking time after the critical render

Correct

// ✅ Good: break work into chunks and yield to the main thread
export default function ProductFilter({ products }: { products: Product[] }) {
  const [isPending, startTransition] = useTransition();

  const handleFilter = async (category: string) => {
    // Immediately update UI to show pending state
    startTransition(() => {
      setCategory(category);
    });

    // Offload heavy computation to a Web Worker
    const filtered = await new Promise<Product[]>((resolve) => {
      filterWorker.onmessage = (e) => resolve(e.data);
      filterWorker.postMessage({ products, category });
    });

    startTransition(() => {
      setFilteredProducts(filtered);
    });

    // Defer non-critical work
    requestIdleCallback(() => {
      updateURL(category);
      trackAnalytics("filter", category);
    });
  };

  return (
    <button
      onClick={() => handleFilter("electronics")}
      disabled={isPending}
    >
      {isPending ? "Filtering..." : "Filter Electronics"}
    </button>
  );
}
// ✅ Web Worker: filter-worker.ts — runs off the main thread
self.onmessage = (event: MessageEvent) => {
  const { products, category } = event.data;

  const filtered = products.filter((product: Product) => {
    const score = calculateRelevanceScore(product, category);
    const normalized = normalizeAcrossDataset(score, products);
    return normalized > 0.5;
  });

  self.postMessage(filtered);
};
// ✅ Alternative: yield to main thread using scheduler.yield()
async function processInChunks<T>(
  items: T[],
  callback: (item: T) => boolean,
  chunkSize = 100
): Promise<T[]> {
  const results: T[] = [];

  for (let i = 0; i < items.length; i += chunkSize) {
    const chunk = items.slice(i, i + chunkSize);
    results.push(...chunk.filter(callback));

    // Yield to the main thread between chunks
    if ("scheduler" in globalThis) {
      await (globalThis as any).scheduler.yield();
    } else {
      await new Promise((resolve) => setTimeout(resolve, 0));
    }
  }

  return results;
}

Benefits:

  • useTransition provides immediate visual feedback while deferring the expensive re-render
  • Web Workers move heavy computation off the main thread entirely, keeping INP near zero
  • requestIdleCallback defers analytics and URL updates until the browser is idle
  • Chunked processing with yielding prevents any single task from blocking the main thread beyond 50ms

Reference: Optimize Interaction to Next Paint

Source: SKILL.md on GitHub

1 warning16d4 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill is a comprehensive SEO reference and audit tool for React and Laravel applications. It provides detailed patterns for optimizing Core Web Vitals, technical SEO, and structured data. No malicious code, obfuscation, or data exfiltration patterns were identified. The skill is designed to analyze project code and provide structural feedback based on a predefined checklist.

  • Socket16d

    5 alerts: gptAnomaly

  • Snyk16d

    Risk: LOW · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 46bae0b. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 6 months ago
metadata
{
  "author": "agent-skills",
  "version": "1.2.0"
}

README badge

README badge for asyrafhussin/agent-skills/seo-best-practices