阿里云主机折上折
  • 微信号
Current Site:Index > Techniques for analyzing build products

Techniques for analyzing build products

Author:Chuan Chen 阅读数:1500人阅读 分类: 构建工具

The Necessity of Build Artifact Analysis

Vite.js's build process generates a series of static resources. Understanding the structure and optimization methods of these artifacts directly impacts application performance. Build artifact analysis helps developers identify redundant code, unused dependencies, and potential optimization points. Through analysis tools and technical means, the output results can be precisely controlled, improving application loading speed and runtime efficiency.

Basic Structure of Build Artifacts

The default build artifacts of Vite.js typically include the following directory structure:

dist/
├── assets/
│   ├── index.[hash].js
│   ├── vendor.[hash].js
│   └── [name].[hash].css
├── index.html
└── vite-manifest.json

The assets directory stores hashed static resources, index.html is the entry file, and vite-manifest.json records resource mapping relationships. For example:

// vite-manifest.json
{
  "src/main.js": {
    "file": "assets/index.abc123.js",
    "src": "src/main.js",
    "isEntry": true
  }
}

Using rollup-plugin-visualizer for Analysis

Install the visualization plugin:

npm install --save-dev rollup-plugin-visualizer

Configure in vite.config.js:

import { visualizer } from 'rollup-plugin-visualizer'

export default defineConfig({
  plugins: [
    visualizer({
      open: true,
      gzipSize: true,
      brotliSize: true
    })
  ]
})

After building, an interactive chart will be generated, showing the volume proportion of each module. Red areas usually indicate key modules that need optimization.

Source Map Analysis

Enable source maps to precisely trace code origins:

// vite.config.js
export default defineConfig({
  build: {
    sourcemap: true
  }
})

In the Chrome DevTools Sources panel, the webpack-internal:// protocol can be used to view the mapping relationship between the original source code and the generated code.

Dependency Volume Optimization

Use @rollup/plugin-analyzer to analyze specific dependencies:

import analyze from '@rollup/plugin-analyzer'

export default defineConfig({
  plugins: [
    analyze({
      limit: 20, // Only show the top 20 largest modules
      filter: module => /node_modules/.test(module.id)
    })
  ]
})

The console will output results similar to:

src/components/HeavyComponent.vue: 45.21KB (12.3%)
node_modules/lodash-es: 38.75KB (10.5%)

Dynamic Import Splitting Strategy

Automatically split code chunks through dynamic imports:

// Before optimization
import HeavyComponent from './HeavyComponent.vue'

// After optimization
const HeavyComponent = () => import('./HeavyComponent.vue')

Configure the splitting strategy in vite.config.js:

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          lodash: ['lodash-es'],
          chartjs: ['chart.js']
        }
      }
    }
  }
})

CSS Code Analysis

Use the critters plugin to extract critical CSS:

import critters from 'vite-plugin-critters'

export default defineConfig({
  plugins: [
    critters({
      preload: 'swap',
      pruneSource: true
    })
  ]
})

Analyze CSS coverage:

  1. Record in the Chrome DevTools Coverage panel
  2. Refresh the page to view the proportion of unused CSS
  3. Red-marked rules indicate unused CSS

Pre-Build Dependency Inspection

Check pre-built dependencies:

// vite.config.js
export default defineConfig({
  optimizeDeps: {
    include: ['lodash-es/debounce'],
    exclude: ['jquery']
  }
})

View pre-build results in the node_modules/.vite directory, or run:

npx vite --force --debug

Build Time Analysis

Add a time measurement plugin:

export default defineConfig({
  plugins: [{
    name: 'timing',
    configResolved(config) {
      const start = Date.now()
      config.plugins.push({
        name: 'timing-end',
        closeBundle() {
          console.log(`Build time: ${Date.now() - start}ms`)
        }
      })
    }
  }]
})

Artifact Hashing Strategy Comparison

Impact of different hashing strategies on caching:

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        // File hashing strategy
        entryFileNames: `[name].[hash].js`,
        chunkFileNames: `[name].[hash].js`,
        assetFileNames: `[name].[hash].[ext]`
      }
    }
  }
})

Comparison experiment:

  1. Modify a single component file - Only the corresponding chunk hash changes
  2. Modify a dependency - The vendor hash changes
  3. Modify the configuration file - All entry hashes change

Tree-Shaking Effect Verification

Verify the actual effect of Tree-shaking:

// utils.js
export function used() { /*...*/ }
export function unused() { /*...*/ }

// main.js
import { used } from './utils'

After building, check if the unused function exists in the artifacts. Add /*#__PURE__*/ markers to assist tree-shaking optimization:

export const foo = /*#__PURE__*/ createComplexObject()

Server-Side Rendering Artifact Analysis

Special configuration for SSR builds:

export default defineConfig({
  build: {
    ssr: true,
    rollupOptions: {
      input: 'src/entry-server.js',
      output: {
        format: 'cjs'
      }
    }
  }
})

When analyzing SSR bundles, pay attention to:

  • Usage of Node.js native modules
  • Server-specific dependencies
  • Client-server code synchronization issues

Custom Analysis Report Generation

Write a custom analysis script:

// analyze.js
import fs from 'fs'
import { resolve } from 'path'

const stats = JSON.parse(
  fs.readFileSync(resolve('./dist/stats.json'))
)

function findLargeFiles(threshold = 1024 * 50) {
  return stats.assets
    .filter(asset => asset.size > threshold)
    .sort((a, b) => b.size - a.size)
}

console.log('Resources larger than 50KB:', findLargeFiles())

Add to package.json:

{
  "scripts": {
    "analyze": "vite build && node analyze.js"
  }
}

Build Cache Analysis

Check cache hit rate:

# Clear cache
rm -rf node_modules/.vite

# First build
time vite build

# Second build
time vite build

Compare the time differences between the two builds. Cache files are located in:

  • node_modules/.vite - Pre-build cache
  • node_modules/.cache - Other tool caches

Multi-Environment Build Comparison

Compare artifact differences across environments:

// vite.config.js
export default defineConfig(({ mode }) => {
  return {
    build: {
      minify: mode === 'production',
      sourcemap: mode !== 'production'
    }
  }
})

Generate a difference report:

diff -r dist-development dist-production | grep -vE '\.map$|\.html$'

Third-Party Plugin Impact Assessment

Evaluate the impact of plugins on the build:

  1. Benchmark a build without plugins
  2. Add plugins one by one and record:
    • Changes in build time
    • Changes in artifact volume
    • Changes in resource count
// Measure plugin impact
const withPlugins = [
  vue(),
  vueJsx(),
  legacy()
]

export default defineConfig(async () => {
  const configs = await Promise.all(
    withPlugins.map(async (plugin, i) => {
      const start = Date.now()
      await build({
        plugins: withPlugins.slice(0, i + 1)
      })
      return {
        plugin: plugin.name,
        time: Date.now() - start
      }
    })
  )
  console.table(configs)
})

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.