阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 长缓存优化方案

长缓存优化方案

作者:陈川 阅读数:49769人阅读 分类: 构建工具

长缓存优化方案

长缓存优化是Webpack构建中提升应用加载性能的关键手段。通过合理配置文件名哈希、代码拆分和模块标识,可以确保用户浏览器缓存尽可能多的静态资源,减少重复下载。

哈希策略选择

Webpack提供三种哈希生成方式:

  • [hash]:整个项目构建的哈希值
  • [chunkhash]:根据入口文件生成的哈希
  • [contenthash]:根据文件内容生成的哈希

推荐使用[contenthash],它只在文件内容变化时才会改变:

output: {
  filename: '[name].[contenthash:8].js',
  chunkFilename: '[name].[contenthash:8].chunk.js'
}

模块标识固化

Webpack默认使用数字ID作为模块标识,这会导致无关修改影响所有chunk的hash。解决方案是使用HashedModuleIdsPlugin

plugins: [
  new webpack.HashedModuleIdsPlugin({
    hashFunction: 'sha256',
    hashDigest: 'hex',
    hashDigestLength: 8
  })
]

运行时代码分离

将运行时代码提取到单独文件,避免业务代码修改影响运行时缓存:

optimization: {
  runtimeChunk: {
    name: entrypoint => `runtime-${entrypoint.name}`
  }
}

第三方库缓存策略

对稳定不变的第三方库使用单独chunk:

splitChunks: {
  cacheGroups: {
    vendor: {
      test: /[\\/]node_modules[\\/]/,
      name: 'vendors',
      chunks: 'all'
    }
  }
}

动态导入优化

使用魔法注释为动态导入的模块命名,保持缓存稳定性:

import(/* webpackChunkName: "lodash" */ 'lodash').then(({ default: _ }) => {
  // 使用lodash
})

清单文件处理

确保正确生成和引用manifest文件:

new WebpackManifestPlugin({
  fileName: 'asset-manifest.json',
  publicPath: '/',
  generate: (seed, files) => ({
    files: files.reduce((manifest, file) => {
      manifest[file.name] = file.path
      return manifest
    }, seed)
  })
})

内容安全策略集成

配置合适的Cache-Control头和服务端缓存策略:

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
  expires 1y;
  add_header Cache-Control "public, immutable";
}

版本文件自动管理

创建版本标记文件帮助客户端检测更新:

const { GitRevisionPlugin } = require('git-revision-webpack-plugin')
plugins: [
  new GitRevisionPlugin({
    versionCommand: 'describe --always --tags --dirty'
  }),
  new webpack.DefinePlugin({
    'process.env.BUILD_VERSION': JSON.stringify(
      new GitRevisionPlugin().version()
    )
  })
]

预加载关键资源

使用preloadprefetch优化资源加载:

import(/* webpackPrefetch: true */ './path/to/Component')

模块依赖分析

利用webpack-bundle-analyzer识别优化机会:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
plugins: [
  new BundleAnalyzerPlugin({
    analyzerMode: 'static',
    reportFilename: 'bundle-report.html',
    openAnalyzer: false
  })
]

持久化缓存配置

启用文件系统缓存提升构建性能:

cache: {
  type: 'filesystem',
  buildDependencies: {
    config: [__filename]
  }
}

哈希长度优化

平衡哈希长度与碰撞概率:

output: {
  filename: '[name].[contenthash:8].js',
  chunkFilename: '[name].[contenthash:8].chunk.js',
  assetModuleFilename: '[name].[hash:8][ext][query]'
}

服务端渲染兼容

处理SSR环境下的资源引用:

const assets = require('./asset-manifest.json')
function renderHtml() {
  return `
    <!DOCTYPE html>
    <html>
      <head>
        <link href="${assets['main.css']}" rel="stylesheet">
      </head>
      <body>
        <script src="${assets['main.js']}"></script>
      </body>
    </html>
  `
}

资源预加载策略

基于使用分析配置资源预加载:

plugins: [
  new PreloadWebpackPlugin({
    rel: 'preload',
    include: 'initial',
    fileBlacklist: [/\.map$/, /hot-update\.js$/]
  })
]

多环境配置处理

区分开发和生产环境的缓存策略:

const isProduction = process.env.NODE_ENV === 'production'
output: {
  filename: isProduction 
    ? '[name].[contenthash:8].js'
    : '[name].js'
}

资源指纹校验

确保资源完整性:

<script 
  src="app.8a7b3c.js" 
  integrity="sha384-5N5S5Q5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5S5"
  crossorigin="anonymous">
</script>

构建信息注入

将构建信息嵌入应用便于调试:

const { DefinePlugin } = require('webpack')
const buildDate = new Date().toISOString()
plugins: [
  new DefinePlugin({
    __BUILD_DATE__: JSON.stringify(buildDate),
    __GIT_HASH__: JSON.stringify(require('child_process')
      .execSync('git rev-parse HEAD')
      .toString().trim())
  })
]

资源加载监控

实现资源加载性能监控:

window.addEventListener('load', () => {
  const entries = performance.getEntriesByType('resource')
  const jsResources = entries.filter(
    e => e.initiatorType === 'script'
  )
  // 上报资源加载耗时
})

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

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

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌