阿里云主机折上折
  • 微信号
Current Site:Index > Optimization of image/font resources

Optimization of image/font resources

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

Image Resource Optimization

Images are typically the largest static resources in front-end projects, and optimizing them can significantly improve page loading speed. Webpack provides various loaders and plugins for handling images, helping us achieve automated optimization.

Image Compression
Using image-webpack-loader can automatically compress images during the build phase:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: [
          'file-loader',
          {
            loader: 'image-webpack-loader',
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },
              optipng: {
                enabled: false
              },
              pngquant: {
                quality: [0.65, 0.90],
                speed: 4
              },
              gifsicle: {
                interlaced: false
              },
              webp: {
                quality: 75
              }
            }
          }
        ]
      }
    ]
  }
}

Base64 Encoding for Small Images
For images smaller than a specific size, they can be converted to Base64 and inlined into the code:

{
  test: /\.(png|jpg|gif)$/i,
  use: [
    {
      loader: 'url-loader',
      options: {
        limit: 8192, // Images under 8KB are converted to base64
        name: 'images/[name].[hash:8].[ext]'
      }
    }
  ]
}

Responsive Image Handling
Use responsive-loader to generate multiple sizes of images:

{
  test: /\.(jpe?g|png|webp)$/i,
  use: [
    {
      loader: 'responsive-loader',
      options: {
        adapter: require('responsive-loader/sharp'),
        sizes: [300, 600, 1200, 2000],
        placeholder: true,
        placeholderSize: 50
      }
    }
  ]
}

Font Resource Optimization

Font files are also a significant factor affecting page performance, especially Chinese font files, which are typically large in size.

Font Subsetting
Use the fontmin-webpack plugin to extract only the characters actually used:

const FontminPlugin = require('fontmin-webpack');

module.exports = {
  plugins: [
    new FontminPlugin({
      autodetect: true, // Automatically extracts used characters
      glyphs: ['Additional characters needed'], // Manually add characters
      allowedFilesRegex: null, // Regex for font files to process
      skippedFilesRegex: null // Regex for files to skip
    })
  ]
}

WOFF2 Format Priority
Modern browsers support the WOFF2 format, which has better compression than WOFF:

{
  test: /\.(woff|woff2|eot|ttf|otf)$/,
  use: [
    {
      loader: 'file-loader',
      options: {
        name: 'fonts/[name].[hash:8].[ext]',
        publicPath: '../fonts/'
      }
    }
  ]
}

Font Loading Strategy
Use fontfaceobserver to control Flash of Unstyled Text (FOUT):

// Define fonts in CSS
@font-face {
  font-family: 'MyFont';
  src: url('myfont.woff2') format('woff2');
  font-display: swap;
}

// Control loading in JavaScript
const font = new FontFaceObserver('MyFont');
font.load().then(() => {
  document.documentElement.classList.add('fonts-loaded');
});

Sprite Sheet Generation

Combining small icons into a sprite sheet can reduce HTTP requests:

const SpritesmithPlugin = require('webpack-spritesmith');

module.exports = {
  plugins: [
    new SpritesmithPlugin({
      src: {
        cwd: path.resolve(__dirname, 'src/icons'),
        glob: '*.png'
      },
      target: {
        image: path.resolve(__dirname, 'src/assets/sprite.png'),
        css: path.resolve(__dirname, 'src/assets/sprite.css')
      },
      apiOptions: {
        cssImageRef: '../assets/sprite.png'
      }
    })
  ]
}

SVG Optimization

SVGs, as vector graphics, can be optimized in various ways:

SVG Compression
Use svgo-loader to automatically optimize SVGs:

{
  test: /\.svg$/,
  use: [
    {
      loader: 'svg-url-loader',
      options: {
        limit: 8192,
        encoding: 'base64'
      }
    },
    'svgo-loader'
  ]
}

SVG Sprite
Combine multiple SVGs into a single sprite:

const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/,
        use: [
          {
            loader: 'svg-sprite-loader',
            options: {
              extract: true,
              spriteFilename: 'sprite.svg'
            }
          }
        ]
      }
    ]
  },
  plugins: [
    new SpriteLoaderPlugin()
  ]
}

Resource Caching Strategy

Leverage Webpack's hash mechanism for long-term caching:

module.exports = {
  output: {
    filename: '[name].[contenthash:8].js',
    chunkFilename: '[name].[contenthash:8].chunk.js'
  },
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[name].[contenthash:8].[ext]'
            }
          }
        ]
      }
    ]
  }
}

On-Demand Loading for Non-Critical Resources

Use Webpack's dynamic imports to lazily load non-critical resources:

// Lazy loading for images
const lazyImage = document.createElement('img');
import(/* webpackPrefetch: true */ './images/hero.jpg').then(src => {
  lazyImage.src = src;
});

// Delayed font loading
window.addEventListener('load', () => {
  import(/* webpackPreload: true */ './fonts/noto-sans-sc.woff2');
});

Resource Preloading Hints

Use preload-webpack-plugin to add resource preloading hints:

const PreloadWebpackPlugin = require('preload-webpack-plugin');

module.exports = {
  plugins: [
    new PreloadWebpackPlugin({
      rel: 'preload',
      include: 'allAssets',
      fileWhitelist: [/\.woff2/],
      as(entry) {
        if (/\.woff2$/.test(entry)) return 'font';
      }
    })
  ]
}

Modern Format Support

Use next-generation image formats like WebP:

const ImageminWebpWebpackPlugin = require('imagemin-webp-webpack-plugin');

module.exports = {
  plugins: [
    new ImageminWebpWebpackPlugin({
      config: [{
        test: /\.(jpe?g|png)/,
        options: {
          quality: 75
        }
      }],
      overrideExtension: true,
      detailedLogs: true
    })
  ]
}

Resource Inlining Decisions

Make informed choices about which resources to inline:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const InlineSourceWebpackPlugin = require('inline-source-webpack-plugin');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin(),
    new InlineSourceWebpackPlugin({
      compress: true,
      rootpath: './src',
      test: [/\.(js|css)$/, /critical\.(css|js)$/]
    })
  ]
}

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

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