Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.4 KiB
4.4 KiB
title, impact, impactDescription, type, tags
| title | impact | impactDescription | type | tags | |||||
|---|---|---|---|---|---|---|---|---|---|
| Use Class Selectors in Scoped CSS for Performance | MEDIUM | Element selectors in scoped CSS are slower because browsers must check both the element type and data attribute | efficiency |
|
Use Class Selectors in Scoped CSS for Performance
Impact: MEDIUM - When Vue compiles scoped CSS, it adds attribute selectors to every rule. Element selectors combined with attribute selectors (e.g., p[data-v-xxx]) are significantly slower for browsers to match than class selectors with attributes (e.g., .text[data-v-xxx]).
Task Checklist
- Prefer class selectors over element selectors in scoped styles
- Avoid deeply nested element selectors in scoped CSS
- Use BEM or similar naming conventions to ensure unique class names
- For heavy styling, consider CSS modules or utility-first approaches
Problematic Code:
<template>
<article>
<header>
<h1>{{ title }}</h1>
<p>{{ subtitle }}</p>
</header>
<section>
<p>{{ content }}</p>
<ul>
<li v-for="item in items" :key="item">{{ item }}</li>
</ul>
</section>
</article>
</template>
<style scoped>
/* BAD: Element selectors are slower when scoped */
article {
max-width: 800px;
}
header {
margin-bottom: 2rem;
}
h1 {
font-size: 2rem;
}
p {
line-height: 1.6;
}
ul {
padding-left: 1.5rem;
}
li {
margin-bottom: 0.5rem;
}
</style>
Correct Code:
<template>
<article class="article">
<header class="article-header">
<h1 class="article-title">{{ title }}</h1>
<p class="article-subtitle">{{ subtitle }}</p>
</header>
<section class="article-content">
<p class="article-text">{{ content }}</p>
<ul class="article-list">
<li v-for="item in items" :key="item" class="article-list-item">
{{ item }}
</li>
</ul>
</section>
</article>
</template>
<style scoped>
/* GOOD: Class selectors are faster */
.article {
max-width: 800px;
}
.article-header {
margin-bottom: 2rem;
}
.article-title {
font-size: 2rem;
}
.article-subtitle,
.article-text {
line-height: 1.6;
}
.article-list {
padding-left: 1.5rem;
}
.article-list-item {
margin-bottom: 0.5rem;
}
</style>
How Scoped CSS Compiles
Vue transforms scoped CSS by adding data attributes:
/* What you write */
p { color: red; }
.text { color: blue; }
/* What Vue generates */
p[data-v-7ba5bd90] { color: red; }
.text[data-v-7ba5bd90] { color: blue; }
Browser CSS matching for p[data-v-xxx]:
- Find all
<p>elements (element lookup) - Check each for the
data-v-xxxattribute (attribute check)
Browser CSS matching for .text[data-v-xxx]:
- Find all elements with class
text(class lookup - optimized) - Check each for the
data-v-xxxattribute
Class lookups are highly optimized in modern browsers, making option 2 faster.
When Performance Matters
This optimization matters most when:
- Rendering large lists (100+ items)
- Complex component trees
- Animation-heavy interfaces
- Mobile devices with limited CPU
<template>
<!-- 1000 items - performance difference is noticeable -->
<ul class="list">
<li v-for="item in items" :key="item.id" class="list-item">
<span class="item-name">{{ item.name }}</span>
<span class="item-price">{{ item.price }}</span>
</li>
</ul>
</template>
<style scoped>
/* Fast selectors for large lists */
.list { ... }
.list-item { ... }
.item-name { ... }
.item-price { ... }
</style>
Acceptable Element Selectors
For small components with few elements, element selectors are fine:
<template>
<button class="btn">
<span>{{ label }}</span>
</button>
</template>
<style scoped>
/* OK for small, simple components */
.btn {
padding: 0.5rem 1rem;
}
span {
font-weight: bold;
}
</style>
CSS Modules Alternative
For performance-critical components, CSS modules avoid the attribute selector entirely:
<template>
<p :class="$style.text">Content</p>
</template>
<style module>
/* Generates unique class names without attribute selectors */
.text {
color: red;
}
/* Compiles to something like: .text_abc123 { color: red; } */
</style>