feat: Complete fleet — 94 skills across 10+ domains
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>
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
---
|
||||
title: Use Class Selectors in Scoped CSS for Performance
|
||||
impact: MEDIUM
|
||||
impactDescription: Element selectors in scoped CSS are slower because browsers must check both the element type and data attribute
|
||||
type: efficiency
|
||||
tags: [vue3, sfc, scoped-css, performance, css-selectors]
|
||||
---
|
||||
|
||||
# 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:**
|
||||
```vue
|
||||
<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:**
|
||||
```vue
|
||||
<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:
|
||||
|
||||
```css
|
||||
/* 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]`:
|
||||
1. Find all `<p>` elements (element lookup)
|
||||
2. Check each for the `data-v-xxx` attribute (attribute check)
|
||||
|
||||
Browser CSS matching for `.text[data-v-xxx]`:
|
||||
1. Find all elements with class `text` (class lookup - optimized)
|
||||
2. Check each for the `data-v-xxx` attribute
|
||||
|
||||
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
|
||||
|
||||
```vue
|
||||
<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:
|
||||
|
||||
```vue
|
||||
<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:
|
||||
|
||||
```vue
|
||||
<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>
|
||||
```
|
||||
|
||||
## Reference
|
||||
- [Vue Loader Scoped CSS](https://vue-loader.vuejs.org/guide/scoped-css.html#child-component-root-elements)
|
||||
- [CSS Selector Performance](https://csswizardry.com/2011/09/writing-efficient-css-selectors/)
|
||||
Reference in New Issue
Block a user