阿里云主机折上折
  • 微信号
Current Site:Index > Optimization of media resources such as images

Optimization of media resources such as images

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

The Necessity of Optimizing Media Resources Like Images

Modern web applications heavily use media resources such as images and videos, which often account for the majority of page load time. Unoptimized media resources can lead to slow first-screen loading, wasted bandwidth, and degraded user experience. Vite, as a next-generation frontend build tool, provides various out-of-the-box optimization methods.

Vite's Built-in Image Processing Capabilities

Vite natively supports importing image resources without additional configuration, allowing direct references in code:

import logo from './assets/logo.png'

function Header() {
  return <img src={logo} alt="Logo" />
}

Vite automatically handles these resources:

  • Images smaller than 4KB are converted to base64 and inlined
  • Larger images are given hashed filenames and copied to the output directory
  • Provides public path resolution for images

Image Format Selection and Conversion

Advantages of WebP Format

WebP is typically 25-35% smaller than PNG/JPG and supports transparency and animation. Vite can automate conversion via plugins:

npm install vite-plugin-webp -D

Configure vite.config.js:

import { defineConfig } from 'vite'
import webp from 'vite-plugin-webp'

export default defineConfig({
  plugins: [
    webp({
      quality: 80,
      // Only convert images larger than 10KB
      filter: (filePath, fileBuffer) => fileBuffer.length > 10240
    })
  ]
})

Advanced Optimization with AVIF Format

AVIF is 20-30% smaller than WebP but takes longer to encode. Ideal for performance-critical scenarios:

// vite.config.js
import avif from 'vite-plugin-avif'

export default defineConfig({
  plugins: [
    avif({
      quality: 50,
      speed: 5  // 1-9, higher values mean faster encoding but lower compression
    })
  ]
})

Responsive Image Processing

Viewport-Based Dynamic Loading

Use vite-plugin-responsive-loader to generate multiple sizes:

// vite.config.js
import responsive from 'vite-plugin-responsive-loader'

export default defineConfig({
  plugins: [
    responsive({
      sizes: [320, 640, 1024, 1600],
      formats: ['webp', 'original']
    })
  ]
})

Usage in components:

const sources = [
  { srcset: '/assets/hero-320.webp 320w', type: 'image/webp' },
  { srcset: '/assets/hero-640.webp 640w', type: 'image/webp' },
  { srcset: '/assets/hero-1024.webp 1024w', type: 'image/webp' }
]

function HeroImage() {
  return (
    <picture>
      {sources.map((src, i) => (
        <source key={i} {...src} />
      ))}
      <img src="/assets/hero-1024.jpg" alt="Hero" />
    </picture>
  )
}

Lazy Loading Implementation

Native loading Attribute

Simplest lazy loading approach:

<img src="image.jpg" loading="lazy" alt="Lazy loaded" />

Intersection Observer API

More precise control:

// lazy.js
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target
      img.src = img.dataset.src
      observer.unobserve(img)
    }
  })
}, {
  rootMargin: '200px'
})

document.querySelectorAll('[data-src]').forEach(img => {
  observer.observe(img)
})

Component usage:

<img data-src="/large-image.jpg" alt="Lazy" class="lazy" />

Sprite Sheet Optimization

Use vite-plugin-sprite to merge small icons:

npm install vite-plugin-sprite -D

Configuration example:

// vite.config.js
import sprite from 'vite-plugin-sprite'

export default defineConfig({
  plugins: [
    sprite({
      // Match SVGs in icons directory
      include: 'src/assets/icons/*.svg',
      output: 'public/sprites'
    })
  ]
})

Using generated sprite sheets:

.icon {
  background-image: url('/sprites/sprite.svg');
}
.icon-home {
  width: 24px;
  height: 24px;
  background-position: 0 0;
}

Video Resource Optimization Strategies

Video Format Selection

Prefer WebM over MP4:

<video width="640" height="360" controls>
  <source src="video.webm" type="video/webm">
  <source src="video.mp4" type="video/mp4">
</video>

Video Preloading Strategies

Dynamic loading based on network conditions:

function loadVideo() {
  const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection
  const video = document.getElementById('hero-video')
  
  if (connection) {
    const effectiveType = connection.effectiveType
    video.src = effectiveType === '4g' ? 'hd.webm' : 'sd.webm'
  } else {
    video.src = 'sd.webm'
  }
}

CDN Acceleration for Media Resources

Configure Vite's base path to point to CDN:

// vite.config.js
export default defineConfig({
  base: process.env.NODE_ENV === 'production' 
    ? 'https://cdn.yourdomain.com/assets/' 
    : '/'
})

Combine with content hashing for cache validity:

// vite.config.js
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        assetFileNames: 'assets/[name]-[hash][extname]'
      }
    }
  }
})

On-Demand Loading of Media Resources

Dynamic import for large resources:

function loadHeroImage() {
  import('./assets/hero-image.webp').then(module => {
    document.getElementById('hero').style.backgroundImage = `url(${module.default})`
  })
}

// Trigger when needed
window.addEventListener('scroll', loadHeroImage, { once: true })

Best Practices for Caching Strategies

Configure strong and conditional caching:

# Nginx configuration example
location ~* \.(jpg|jpeg|png|gif|ico|webp|svg|mp4|webm)$ {
  expires 1y;
  add_header Cache-Control "public, immutable";
  access_log off;
}

For frequently updated resources:

location ~* \.(js|css)$ {
  expires 7d;
  add_header Cache-Control "public, must-revalidate";
}

Performance Monitoring and Tuning

Use Chrome DevTools' Coverage tool to analyze unused resources:

// Run directly in console
console.table(performance.getEntriesByType('resource')
  .filter(r => r.initiatorType === 'img')
  .map(r => ({
    name: r.name,
    duration: `${r.duration.toFixed(2)}ms`,
    size: `${(r.transferSize / 1024).toFixed(2)}KB`
  }))
)

Implement resource loading monitoring:

const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach(entry => {
    console.log(`[${entry.initiatorType}] ${entry.name}: 
      ${entry.duration.toFixed(2)}ms`)
  })
})

observer.observe({ entryTypes: ['resource'] })

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

如果侵犯了你的权益请来信告知我们删除。邮箱: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 ☕.