Webpack Cache

  • Mỗi khi ta thay đổi đoạn code nào đó, nó sẽ được thực hiện cập nhật trên server, sau đó sẽ được tải lại ở phía client (phía máy khách của người dùng), việc này rõ ràng là không hiệu quả, vì phải nạp lại nhiều lần thông qua giao thức mạng, khiến làm chậm tốc độ tải trang. Đây là lý do tại sao trình duyệt cache (lưu trữ) lại tài nguyên tĩnh.
  • Trình duyệt sẽ cache tất cả các file đã được tải (dựa theo tên file), và sẽ cập nhật thay đổi trong khoảng thời gian cố định, điều này có nghĩa, nếu ta có thay đổi file, ví dụ như file javascript, thì trình duyệt cũng không thể cập nhật thay đổi ngay được, mà cần khoảng thời gian mới cập nhật được.
  • Để giải quyết vấn đề này, Webpack cho phép tách file,

Chuẩn bị

  • Nhằm giúp dễ hiểu nội dung Cache, ta sẽ xóa bớt một số file và giữ cấu trúc như sau:
  • node_modules

    • ...
  • package.json package.json
  • package.json webpack.config.js
  • package-lock.json package-lock.json
  • dist

    • package.json index.html
  • src

    • package.json index.js

Chỉnh gọn lại nội dung file webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      title: 'Caching'
    })
  ],
  output: {
    filename: '[name].[contenthash].js',
    path: path.resolve(__dirname, 'dist')
  }
};
  • '[name].[contenthash].js': thay vì output trả về tên file cố định dạng bundle thì sẽ trả về một chuỗi hash.

Chỉnh lại nội dung file /dist/index.html:

Thật ra không cần chỉnh cũng được, vì khi thực thi npm run build thì nội dung này sẽ được plugin HtmlWebpackPlugin tự động dọn dẹp lại.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Output Management</title>
  </head>
  <body>
  </body>
</html>
  • Tiến hành chạy lệnh npm để thực thi nội dung trên:
npm run build

Kết quả

Webpack Cache

  • Ta thấy Webpack đã tự động tạo một file bên trong thư mục dist dưới dạng main.b652e9ed931a588004a4.js, file này được tự động thêm vào file /dist/index.html, để khi click chạy trang thì sẽ hiển thị nội dung của file /src/index.js.
  • Vấn đề là mỗi khi ta thay đổi nội dung file /src/index.js, thì chuỗi hash của tên file main.b652e9ed931a588004a4.js sẽ bị thay đổi. Điều này có nghĩa là mỗi lần thay đổi thì trình duyệt sẽ load lại file main.b652e9ed931a588004a4.js, việc này tất nhiên không tốt, vì sẽ ảnh hưởng tới tốc độ load trang.
  • Để giải quyết vấn đề này, Webpack cung cấp một tính năng tối ưu hóa để phân chia mã thời gian chạy thành một đoạn riêng, ta thực hiện như sau:

Chỉnh gọn lại nội dung file webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      title: 'Caching'
    })
  ],
  output: {
    filename: '[name].[contenthash].js',
    path: path.resolve(__dirname, 'dist')
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all'
        }
      }
    }
  }
};
  • Tiến hành chạy lệnh npm để thực thi nội dung trên:
npm run build

Kết quả

Webpack Cache

  • Ta thấy bên trong thư mục dist, Webpack đã tự động tạo 2 file là: main.b3210033491860d853f2.jsvendors.ffea3832764e4de5644c.js.
  • 2 file này tự động liên kết với file /dist/index.html

Nội dung file /dist/index.html khi này:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Caching</title>
  </head>
  <body>
  <script type="text/javascript" src="vendors.ffea3832764e4de5644c.js"></script><script type="text/javascript" src="main.9f854a5033dbb821f468.js"></script></body>
</html>
  • Khi thử thay đổi file /src/index.js, thực thi lại lệnh npm, thì ta sẽ thấy tên file main.b3210033491860d853f2.js thay đổi, tuy nhiên tên file vendors.ffea3832764e4de5644c.js thì không, ta phân tích như sau:
    • Tên file vendors.ffea3832764e4de5644c.js không thay đổi có nghĩa là trình duyệt sẽ Cache lại nội dung của file này, điều quan trọng là file này chứa thông tin source code của bên thứ ba (như jQuery, React, lodash, ...), nội dung này ít thay đổi, do đó việc Cache lại sẽ giúp tốc độ trang được cải thiện rất nhiều.
    • Dung lượng file vendors.ffea3832764e4de5644c.js đạt 70 KiB, cũng có nghĩa là sau khi được Cache, lần load kế tiếp sẽ không cần loại lại file với dung lượng này nữa.
    • Tên file main.b3210033491860d853f2.js thay đổi sẽ giúp cho trình duyệt sẽ cập nhật được nội dung của của file này mỗi khi nội dung /src/index.js thay đổi (đây là nội dung source code của chúng ta), điều này sẽ giảm tải việc load trang rất nhiều, vì dung lượng file này bây giờ chỉ còn 1.64 KiB.
  • Tới đây có lẽ bạn đã hình dung được cách Webpack thực hiện tối ưu hóa việc tải trang như thế nào rồi he ^^.

Các lệnh chính đã sử dụng trong toàn bộ bài học

Bài học Lệnh đã dùng
Cài đặt Webpack
cd Webpack-project
npm init -y
npm install --save-dev webpack
npm install --save-dev webpack-cli
Webpack bundle
npx webpack
Cấu hình Webpack
npx webpack --config webpack.config.js
npm run build
Webpack quản lý output
npm run build
Webpack code splitting
npm install --save lodash
npm run build
npm run build
Cài đặt và setting HtmlWebpackPlugin
npm install --save-dev html-webpack-plugin
npm run build
Cài đặt và setting CleanWebpackPlugin
npm install --save-dev clean-webpack-plugin
npm run build
Webpack Cache
npm run build
npm run build