什么是CDN

CDN 全称是 Content Delivery Network ,即内容分发网络,是由分布在不同区域的边缘节点服务器群组成的分布式网络。简单的说,CDN 就是将源站的资源缓存到位于全球各地的 CDN 节点上,用户请求资源时,返回最近节点上缓存的资源,而不需要每个用户的请求都从源站获取,从而避免网络拥塞、缓解源站压力,保证用户访问资源的速度和体验。

Webpack性能优化之CDN加速 - 图1

CND加速主要是加速静态资源,如网站上面上传的图片、音视频、流媒体等,以及引入的一些Js、css等文件。

Webpack 中实现CDN

在 Webpack 中接入CDN,需要实现以下几点:

  • 导入静态资源的 URL 需要变成指向 CDN 服务器的绝对路径的 URL
  • 静态资源的文件名称需要带上有文件内容算出来的 Hash 值,以防止被缓存
  • 不同类型的资源放到不同域名的 CDN 服务上去,以防止资源的并行加载被阻塞

下面是实现以上要求的Webpack配置:

  1. const path = require('path');
  2. const ExtractTextPlugin = require('extract-text-webpack-plugin');
  3. const {WebPlugin} = require('web-webpack-plugin');
  4. module.exports = {
  5. // 省略 entry 配置...
  6. output: {
  7. // 给输出的 JavaScript 文件名称加上 Hash 值
  8. filename: '[name]_[chunkhash:8].js',
  9. path: path.resolve(__dirname, './dist'),
  10. // 指定存放 JavaScript 文件的 CDN 目录 URL
  11. publicPath: 'http://js.cdn.com/[hash]/',
  12. },
  13. module: {
  14. rules: [
  15. {
  16. // 增加对 CSS 文件的支持
  17. test: /\.css$/,
  18. // 提取出 Chunk 中的 CSS 代码到单独的文件中
  19. use: ExtractTextPlugin.extract({
  20. // 压缩 CSS 代码
  21. use: ['css-loader?minimize'],
  22. // 指定存放 CSS 中导入的资源(例如图片)的 CDN 目录 URL
  23. publicPath: '//img.cdn.com/id/'
  24. }),
  25. },
  26. {
  27. // 增加对 PNG 文件的支持
  28. test: /\.png$/,
  29. // 给输出的 PNG 文件名称加上 Hash 值
  30. use: ['file-loader?name=[name]_[hash:8].[ext]'],
  31. },
  32. // 省略其它 Loader 配置...
  33. ]
  34. },
  35. plugins: [
  36. // 使用 WebPlugin 自动生成 HTML
  37. new WebPlugin({
  38. // HTML 模版文件所在的文件路径
  39. template: './template.html',
  40. // 输出的 HTML 的文件名称
  41. filename: 'index.html',
  42. // 指定存放 CSS 文件的 CDN 目录 URL
  43. stylePublicPath: '//css.cdn.com/id/',
  44. }),
  45. new ExtractTextPlugin({
  46. // 给输出的 CSS 文件名称加上 Hash 值
  47. filename: `[name]_[contenthash:8].css`,
  48. }),
  49. // 省略代码压缩插件配置...
  50. ],
  51. };

在上面的代码中,通过 publicPath 参数设置存放静态资源的 CDN 目录 URL, 为了让不同类型的资源输出到不同的 CDN,需要分别在:

  • output.publicPath 中设置 JavaScript 的地址
  • css-loader.publicPath 中设置被 CSS 导入的资源的的地址
  • WebPlugin.stylePublicPath 中设置 CSS 文件的地址