All skills
asyrafhussin avatar

/react-vite-best-practices

@b2dc58c

React and Vite performance optimization guidelines. Use when writing, reviewing, or optimizing React components built with Vite. Triggers on tasks involving Vite configuration, build optimization, code splitting, lazy loading, HMR, bundle size, or React performance.

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

This session only. Nothing lands on disk.

rulessplit-dynamic-imports.md

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

Use Dynamic Imports for Heavy Components

Impact: CRITICAL (30-50% reduction in initial bundle)

Heavy components like charts, editors, and complex forms should not be loaded until needed. Dynamic imports allow loading code on-demand, reducing initial bundle size.

Incorrect

// ❌ Bad: All heavy libraries loaded upfront
import { Chart } from 'chart.js'
import ReactQuill from 'react-quill'
import { PDFViewer } from '@react-pdf/renderer'
import MonacoEditor from '@monaco-editor/react'

function Dashboard() {
  const [showChart, setShowChart] = useState(false)

  return (
    <div>
      <button onClick={() => setShowChart(true)}>Show Chart</button>
      {showChart && <Chart data={data} />}
    </div>
  )
}

Problems:

  • Chart.js, React Quill, PDF renderer, and Monaco are all loaded even if never used
  • Initial bundle bloated with hundreds of KBs of library code
  • Slower Time to Interactive for all users regardless of feature usage
  • Heavy parsing blocks the main thread on mobile devices

Correct

// ✅ Good: Lazy load heavy components
import { lazy, Suspense, useState } from 'react'

const Chart = lazy(() => import('./components/Chart'))
const Editor = lazy(() => import('./components/Editor'))
const PDFViewer = lazy(() => import('./components/PDFViewer'))

function Dashboard() {
  const [showChart, setShowChart] = useState(false)
  const [showEditor, setShowEditor] = useState(false)

  return (
    <div>
      <button onClick={() => setShowChart(true)}>Show Chart</button>
      <button onClick={() => setShowEditor(true)}>Show Editor</button>

      {showChart && (
        <Suspense fallback={<ChartSkeleton />}>
          <Chart data={data} />
        </Suspense>
      )}

      {showEditor && (
        <Suspense fallback={<EditorSkeleton />}>
          <Editor />
        </Suspense>
      )}
    </div>
  )
}
// ✅ Good: Conditional dynamic import for libraries
async function exportToPDF() {
  const { PDFDocument } = await import('pdf-lib')
  const pdfDoc = await PDFDocument.create()
  // ... generate PDF
}

function ExportButton() {
  const [loading, setLoading] = useState(false)

  const handleExport = async () => {
    setLoading(true)
    await exportToPDF()
    setLoading(false)
  }

  return (
    <button onClick={handleExport} disabled={loading}>
      {loading ? 'Generating...' : 'Export PDF'}
    </button>
  )
}
// ✅ Good: Preload on interaction intent
const HeavyModal = lazy(() => import('./HeavyModal'))

function ModalTrigger() {
  const [isOpen, setIsOpen] = useState(false)

  const preload = () => {
    import('./HeavyModal')
  }

  return (
    <>
      <button
        onClick={() => setIsOpen(true)}
        onMouseEnter={preload}
        onFocus={preload}
      >
        Open Settings
      </button>

      {isOpen && (
        <Suspense fallback={<ModalSkeleton />}>
          <HeavyModal onClose={() => setIsOpen(false)} />
        </Suspense>
      )}
    </>
  )
}
// ✅ Good: Feature flag based loading
function App({ user }) {
  const AdminPanel = user.isAdmin
    ? lazy(() => import('./AdminPanel'))
    : null

  return (
    <div>
      <MainContent />
      {AdminPanel && (
        <Suspense fallback={<Loading />}>
          <AdminPanel />
        </Suspense>
      )}
    </div>
  )
}

Benefits:

  • Initial bundle can be 50%+ smaller by deferring heavy libraries
  • Faster Time to Interactive since only critical code is parsed upfront
  • Better user experience on slow connections and mobile devices
  • Preloading on hover makes subsequent loads feel instant
  • Feature-flag loading avoids shipping admin code to regular users

Libraries that should typically be dynamically imported:

  • Chart libraries (Chart.js, Recharts, D3)
  • Rich text editors (React Quill, TipTap, Slate)
  • Code editors (Monaco, CodeMirror)
  • PDF libraries (react-pdf, pdf-lib)
  • Date pickers with locales
  • Map libraries (Mapbox, Google Maps)
  • Markdown renderers

Reference: Vite Dynamic Import | React lazy

Source: SKILL.md on GitHub

1 alert17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    The skill is a comprehensive performance optimization guide for React and Vite applications. It contains instructional content and code examples for build optimization, code splitting, and asset handling. The skill explicitly promotes security best practices, such as preventing the exposure of sensitive environment variables in client-side code, and no malicious patterns were detected.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer6mo

    4/29 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at b2dc58c. 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 7 months ago
metadata
{
  "author": "agent-skills",
  "version": "2.0.0"
}

README badge

README badge for asyrafhussin/agent-skills/react-vite-best-practices