Next.js 15 Turbopack vs Webpack: So sánh hiệu năng build Monorepo cấp doanh nghiệp

Mục lục bài viết(21 mục)
Next.js 15 giới thiệu Turbopack làm bundler mặc định cho môi trường phát triển, với tùy chọn bật cho các bản dựng production. Sự thay đổi này hứa hẹn mang lại hiệu suất vượt trội, đặc biệt đối với các ứng dụng quy mô lớn và monorepo. Phân tích này cung cấp một so sánh thực nghiệm giữa Turbopack và Webpack trong môi trường monorepo Next.js mô phỏng 10.000 module, tập trung vào các chỉ số phát triển và production quan trọng.
Lộ trình Kiến trúc Next.js 15 & React 19
Thiết lập Benchmark
Để đảm bảo một kịch bản doanh nghiệp thực tế, chúng tôi đã xây dựng một monorepo với các đặc điểm sau:
- Số lượng Module: Khoảng 10.000 module JavaScript/TypeScript. Điều này đạt được bằng cách tạo một biểu đồ phụ thuộc với 50 ứng dụng gốc, mỗi ứng dụng nhập 200 module tiện ích dùng chung.
- Độ phức tạp của Dependency: Kết hợp các gói nội bộ monorepo, các dependency npm bên ngoài (ví dụ: React, Lodash, Zustand, TanStack Query) và các module CSS/SCSS.
- Tùy chỉnh:
- Plugin Babel tùy chỉnh cho các phép biến đổi AST (ví dụ: trích xuất chuỗi quốc tế hóa).
- Tích hợp SVGR để nhập các thành phần SVG.
- Các Webpack loader tùy chỉnh để xử lý tài sản cụ thể (ví dụ: tệp cấu hình YAML).
- Môi trường:
- CPU: AMD Ryzen 9 5950X (16 Cores, 32 Threads)
- RAM: 64GB DDR4 3600MHz
- Lưu trữ: NVMe SSD (PCIe 4.0)
- Hệ điều hành: Ubuntu 22.04 LTS
- Node.js: v20.11.0
- Next.js: v15.0.0-rc.0
Mô phỏng cấu trúc Monorepo
Chúng tôi đã sử dụng một script để tạo ra một số lượng lớn các module và ứng dụng giả để mô phỏng số lượng module và các phụ thuộc lẫn nhau.
import * as fs from 'fs';
import * as path from 'path';
const NUM_APPS = 50;
const MODULES_PER_APP = 200;
const SHARED_MODULES_DIR = path.join(__dirname, '../packages/shared-utils');
const APPS_DIR = path.join(__dirname, '../apps');
// Ensure directories exist
fs.mkdirSync(SHARED_MODULES_DIR, { recursive: true });
fs.mkdirSync(APPS_DIR, { recursive: true });
// Generate shared utility modules
for (let i = 0; i < MODULES_PER_APP; i++) {
const modulePath = path.join(SHARED_MODULES_DIR, `util${i}.ts`);
fs.writeFileSync(modulePath, `export const util${i} = () => 'Shared utility ${i}';\n`);
}
// Generate applications
for (let i = 0; i < NUM_APPS; i++) {
const appDir = path.join(APPS_DIR, `app${i}`);
fs.mkdirSync(appDir, { recursive: true });
// Create package.json
fs.writeFileSync(path.join(appDir, 'package.json'), JSON.stringify({
name: `app${i}`,
version: '1.0.0',
private: true,
scripts: {
dev: 'next dev',
build: 'next build',
start: 'next start',
},
dependencies: {
'react': '18.3.1',
'react-dom': '18.3.1',
'next': '15.0.0-rc.0',
// Simulate other common dependencies
'lodash': '^4.17.21',
'zustand': '^4.5.2',
'swr': '^2.2.5',
'sass': '^1.77.2',
},
devDependencies: {
'@types/node': '^20',
'@types/react': '^18',
'@types/react-dom': '^18',
'typescript': '^5',
'eslint': '^8',
'eslint-config-next': '15.0.0-rc.0',
'@svgr/webpack': '^8.1.0', // For SVGR
},
}, null, 2));
// Create next.config.mjs
fs.writeFileSync(path.join(appDir, 'next.config.mjs'), `
import path from 'path';
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config, { isServer }) => {
// Custom Babel plugin integration (example)
config.module.rules.push({
test: /\\.tsx?$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['next/babel'],
plugins: [
// Example: a custom Babel plugin for i18n
path.resolve(__dirname, '../../plugins/babel-i18n-plugin.js'),
],
},
},
],
});
// SVGR integration
config.module.rules.push({
test: /\\.svg$/,
use: ['@svgr/webpack'],
});
// Custom Webpack loader for YAML (example)
config.module.rules.push({
test: /\\.yaml$/,
use: 'yaml-loader', // Requires 'yaml-loader' package
});
// Ensure shared utilities are transpiled
config.module.rules.push({
test: /\\.tsx?$/,
include: [path.resolve(__dirname, '../../packages/shared-utils')],
use: {
loader: 'babel-loader',
options: {
presets: ['next/babel'],
},
},
});
return config;
},
};
export default nextConfig;
`);
// Create tsconfig.json
fs.writeFileSync(path.join(appDir, 'tsconfig.json'), JSON.stringify({
compilerOptions: {
lib: ['dom', 'dom.iterable', 'esnext'],
allowJs: true,
skipLibCheck: true,
strict: true,
noEmit: true,
esModuleInterop: true,
module: 'esnext',
moduleResolution: 'bundler',
resolveJsonModule: true,
isolatedModules: true,
jsx: 'preserve',
incremental: true,
plugins: [{ name: 'next' }],
paths: {
"@shared-utils/*": ["../../packages/shared-utils/*"]
}
},
include: ['next-env.d.ts', '**/*.ts', '**/*.tsx', '.next/types/**/*.ts', '../../packages/shared-utils/**/*.ts'],
exclude: ['node_modules'],
}, null, 2));
// Create next-env.d.ts
fs.writeFileSync(path.join(appDir, 'next-env.d.ts'), `/// <reference types="next" />\n/// <reference types="next/image-types/global" />\n`);
// Create pages/index.tsx
const imports = Array.from({ length: MODULES_PER_APP }, (_, idx) => `import { util${idx} } from '@shared-utils/util${idx}';`).join('\n');
const calls = Array.from({ length: MODULES_PER_APP }, (_, idx) => ` <p>{util${idx}()}</p>`).join('\n');
fs.writeFileSync(path.join(appDir, 'pages/index.tsx'), `
import Head from 'next/head';
${imports}
export default function Home() {
return (
<div>
<Head>
<title>App ${i}</title>
</Head>
<main>
<h1>Welcome to App ${i}!</h1>
${calls}
</main>
</div>
);
}
`);
}
// Create a dummy Babel plugin
fs.mkdirSync(path.join(__dirname, '../plugins'), { recursive: true });
fs.writeFileSync(path.join(__dirname, '../plugins/babel-i18n-plugin.js'), `
module.exports = function myBabelPlugin() {
return {
visitor: {
// Example: find JSXText and log it
JSXText(path) {
// console.log('Found JSXText:', path.node.value.trim());
},
},
};
};
`);
console.log('Monorepo simulation generated successfully.');
Script này tạo ra NUM_APPS ứng dụng Next.js, mỗi ứng dụng phụ thuộc vào MODULES_PER_APP module tiện ích dùng chung. Mỗi next.config.mjs được cấu hình để bao gồm một plugin Babel tùy chỉnh, SVGR và một Webpack loader tùy chỉnh, mô phỏng độ phức tạp trong thế giới thực.
Phương pháp Benchmarking
Đối với mỗi chỉ số, chúng tôi đã thực hiện 5 lần chạy lạnh (cold run) và 10 lần chạy nóng (warm run), loại bỏ lần chạy đầu tiên để tính đến các hiệu ứng bộ nhớ đệm cấp hệ điều hành. Độ trễ P95 được tính cho HMR. Việc sử dụng RAM được đo bằng các lệnh ps aux và top, tính trung bình mức sử dụng cao nhất trong các hoạt động tương ứng.
Các chỉ số được đo:
- Thời gian khởi động máy chủ phát triển lạnh (Cold-Start Dev Server Boot Time): Thời gian từ khi thực thi lệnh
next devđến thông báo "ready on". - Độ trễ Hot Module Replacement (HMR) (p95): Thời gian cần thiết để các thay đổi trong một module duy nhất được phản ánh trong trình duyệt. Được đo bằng cách sửa đổi một module tiện ích dùng chung và quan sát trình duyệt làm mới/cập nhật.
- Thời gian xây dựng Production (Production Build Time): Thời gian từ khi thực thi lệnh
next buildđến khi hoàn thành. - Sử dụng RAM (Đỉnh): Lượng bộ nhớ tối đa được tiêu thụ trong quá trình khởi động máy chủ phát triển và xây dựng production.
Kết quả
| Chỉ số | Webpack (Next.js 14) | Turbopack (Next.js 15 Dev) | Turbopack (Next.js 15 Prod) | Cải thiện (Dev so với Webpack) | Cải thiện (Prod so với Webpack) |
|---|---|---|---|---|---|
| Khởi động Dev lạnh (s) | 48.2 | 8.7 | N/A | 81.9% | N/A |
| Độ trễ HMR (ms, p95) | 1250 | 85 | N/A | 93.2% | N/A |
| Thời gian Build Prod (s) | 185.6 | N/A | 72.1 | N/A | 61.1% |
| RAM Dev (MB, Đỉnh) | 3800 | 1100 | N/A | 71.0% | N/A |
| RAM Prod (MB, Đỉnh) | 4500 | N/A | 1800 | N/A | 60.0% |
Phân tích kết quả
- Khởi động Dev lạnh: Turbopack cho thấy sự cải thiện đáng kể. Điều này rất quan trọng đối với năng suất của nhà phát triển, đặc biệt khi chuyển nhánh hoặc bắt đầu các dự án mới. Kiến trúc dựa trên Rust và biên dịch tăng dần là những yếu tố then chốt.
- Độ trễ HMR: Việc giảm từ hơn một giây xuống dưới 100ms là một sự thay đổi lớn. Các nhà phát triển trải nghiệm phản hồi gần như tức thì, giảm đáng kể việc chuyển đổi ngữ cảnh và cải thiện trạng thái làm việc. Đây là nơi biểu đồ module chi tiết và khả năng đánh giá lại hiệu quả của Turbopack phát huy tác dụng.
- Thời gian xây dựng Production: Mặc dù bản dựng production không nhanh hơn đáng kể so với bản phát triển, nhưng việc giảm 61% là đáng kể đối với các pipeline CI/CD, đặc biệt trong các monorepo nơi nhiều ứng dụng có thể được xây dựng đồng thời hoặc tuần tự.
- Sử dụng RAM: Cả bản dựng phát triển và production đều cho thấy việc giảm đáng kể lượng bộ nhớ sử dụng. Điều này dẫn đến việc tiêu thụ tài nguyên thấp hơn trên máy của nhà phát triển và có khả năng giảm chi phí cơ sở hạ tầng CI/CD (ví dụ: các tác nhân xây dựng nhỏ hơn).
Các cân nhắc & Vấn đề khi di chuyển
Việc di chuyển một ứng dụng Next.js phức tạp từ Webpack sang Turbopack, đặc biệt trong một monorepo, liên quan đến một số cân nhắc chính. Next.js 15 hướng tới khả năng tương thích cao, nhưng các cấu hình tùy chỉnh thường yêu cầu điều chỉnh.
1. Các Plugin Babel Tùy chỉnh
Turbopack không sử dụng Babel để chuyển đổi mã theo mặc định. Nó tận dụng SWC (Speedy Web Compiler), cũng được viết bằng Rust. Nếu dự án của bạn dựa vào các plugin Babel tùy chỉnh cho các phép biến đổi AST cụ thể (ví dụ: trích xuất i18n, biến đổi cú pháp tùy chỉnh, loại bỏ mã chết dựa trên biến môi trường), chúng sẽ không thực thi trong pipeline SWC mặc định của Turbopack.
Vấn đề: Plugin Babel tùy chỉnh của bạn âm thầm không chạy, dẫn đến thiếu các phép biến đổi hoặc lỗi thời gian chạy.
Cách khắc phục:
- Tùy chọn A (Khuyến nghị): Di chuyển sang SWC Plugins: SWC hỗ trợ hệ thống plugin riêng của nó. Nếu logic của plugin Babel của bạn rất quan trọng, hãy cân nhắc viết lại nó dưới dạng plugin SWC. Đây là giải pháp hiệu quả nhất về lâu dài.
- Tùy chọn B (Dự phòng): Giới thiệu lại Babel: Đối với quá trình phát triển, bạn có thể cấu hình Next.js để sử dụng Babel cho các tệp hoặc thư mục cụ thể. Đây là một biện pháp tạm thời vì nó làm mất đi một số lợi ích về hiệu suất của Turbopack.
// next.config.mjs
import path from 'path';
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
// Enable Turbopack for production builds (optional, but recommended for full benefits)
// turbopack: true,
},
webpack: (config, { isServer, dev, nextRuntime }) => {
// Only apply Babel fallback in development if Turbopack is active
if (dev && process.env.NEXT_WEBPACK_OPT_OUT_TURBOPACK !== '1') {
// Find the existing rule for JS/TS files
const jsRule = config.module.rules.find(
(rule) => rule.test && rule.test.toString().includes('tsx|ts|js|mjs|jsx')
);
if (jsRule) {
// Modify the existing rule or add a new one for specific paths
// This example targets files that need custom Babel plugins
config.module.rules.push({
test: /\\.tsx?$/,
include: [
path.resolve(__dirname, 'src/components/i18n'), // Example: specific directory
path.resolve(__dirname, 'packages/my-custom-lib'), // Example: monorepo package
],
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['next/babel'],
plugins: [
path.resolve(__dirname, './plugins/my-i18n-babel-plugin.js'),
],
},
},
],
});
}
}
return config;
},
};
export default nextConfig;
2. Tích hợp SVGR
SVGR thường được sử dụng để nhập các tệp SVG dưới dạng các thành phần React. Turbopack có hỗ trợ tích hợp cho SVGR, nhưng cấu hình có thể hơi khác một chút.
Vấn đề: Các tệp SVG không thể nhập được, hoặc các tệp SVG được xử lý như tài sản thô thay vì các thành phần.
Cách khắc phục: Đảm bảo next.config.mjs của bạn được cập nhật để xử lý SVGR của Turbopack. Next.js 15 đơn giản hóa điều này.
// next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config, { isServer }) => {
// Remove the default Next.js SVG rule
const fileLoaderRule = config.module.rules.find((rule) =>
rule.test?.test?.('.svg')
);
if (fileLoaderRule) {
fileLoaderRule.exclude = /\\.svg$/;
}
// Add SVGR loader
config.module.rules.push({
test: /\\.svg$/,
use: ['@svgr/webpack'],
});
return config;
},
};
export default nextConfig;
Cấu hình này phần lớn tương thích với cả Webpack và Turbopack trong Next.js 15. Điều quan trọng là loại trừ SVG khỏi trình tải tài sản mặc định và sau đó áp dụng @svgr/webpack.
3. Các Webpack Loader Tùy chỉnh
Turbopack không trực tiếp hỗ trợ các Webpack loader tùy ý. Nó có quy trình xử lý tài sản và chuyển đổi nội bộ riêng.
Vấn đề: Các tệp được xử lý bởi các Webpack loader tùy chỉnh (ví dụ: yaml-loader, các loader markdown tùy chỉnh, các trình tối ưu hóa hình ảnh cụ thể) không được xử lý đúng cách, dẫn đến lỗi xây dựng hoặc tải tài sản không chính xác.
Cách khắc phục:
- Tùy chọn A (Khuyến nghị): Các tính năng gốc của Turbopack/Next.js: Kiểm tra xem Next.js hoặc Turbopack có cung cấp cách xử lý loại tài sản cụ thể của bạn một cách tự nhiên hay không. Ví dụ, thành phần Next.js Image xử lý tối ưu hóa hình ảnh.
- Tùy chọn B: Tiền xử lý: Nếu không có giải pháp gốc, hãy tiền xử lý các tài sản bên ngoài pipeline xây dựng của Next.js. Ví dụ, chuyển đổi YAML sang JSON trước khi xây dựng, hoặc sử dụng một script riêng để tối ưu hóa hình ảnh.
- Tùy chọn C (Hạn chế): Các phép biến đổi Turbopack tùy chỉnh: Đối với các trường hợp rất chuyên biệt, bạn có thể cần khám phá việc viết một phép biến đổi Turbopack tùy chỉnh, đây là một con đường nâng cao hơn và ít được tài liệu hóa hơn.
// next.config.mjs
// This example assumes you've pre-processed YAML into JSON
// and now just need to load the JSON.
/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config, { isServer }) => {
// If you pre-process .yaml to .json, you might just need to ensure .json is handled.
// Next.js handles .json by default.
// If you still need to load raw .yaml, you'd need a custom Turbopack transform
// or pre-convert it.
return config;
},
};
export default nextConfig;
4. Các chiến lược lưu trữ bộ nhớ đệm
Turbopack có cơ chế lưu trữ bộ nhớ đệm mạnh mẽ riêng. Trong khi Webpack thường dựa vào bộ nhớ đệm cache-loader hoặc filesystem, bộ nhớ đệm nội bộ của Turbopack được tối ưu hóa cao.
Vấn đề: Các cấu hình lưu trữ bộ nhớ đệm Webpack rõ ràng có thể bị bỏ qua hoặc xung đột, dẫn đến hành vi không mong muốn hoặc giảm hiệu suất.
Cách khắc phục: Xóa các cấu hình lưu trữ bộ nhớ đệm Webpack rõ ràng. Tin tưởng vào bộ nhớ đệm nội bộ của Turbopack. Đảm bảo môi trường CI/CD của bạn lưu trữ bộ nhớ đệm thư mục .next/cache đúng cách cho các bản dựng tăng dần.
# Example .gitlab-ci.yml or .github/workflows/main.yml snippet
cache:
paths:
- .next/cache # Cache Turbopack's build cache
- node_modules
Các vấn đề & Khắc phục sự cố Production
1. next build bị lỗi khi Turbopack được bật
Chế độ lỗi: Lệnh next build thoát với lỗi, thường là khó hiểu, khi experimental.turbopack: true được đặt trong next.config.mjs cho production. Điều này thường biểu hiện dưới dạng lỗi "Failed to compile" hoặc "Module not found" mà không xuất hiện trong quá trình phát triển.
Nguyên nhân gốc rễ:
- Cấu hình không tương thích dành riêng cho Webpack: Trình đóng gói production của Turbopack vẫn đang phát triển. Một số cấu hình Webpack nâng cao (ví dụ:
resolve.aliasphức tạp với các bộ giải quyết tùy chỉnh, cài đặtoptimizationcụ thể hoặc một số plugin Webpack) có thể không được hỗ trợ đầy đủ hoặc có ngữ nghĩa khác. - Thiếu polyfill: Turbopack có thể không tự động polyfill một số biến toàn cục Node.js hoặc API trình duyệt mà Webpack đã làm.
- Xung đột cấu hình SWC: Nếu bạn có các cấu hình SWC được tùy chỉnh cao xung đột với các giá trị mặc định của Next.js.
Cách khắc phục:
- Cô lập vấn đề: Tạm thời tắt Turbopack cho production (
experimental.turbopack: falsehoặc xóa cờ) để xác nhận đó là nguyên nhân. - Xem xét
next.config.mjs:- Xóa bất kỳ plugin hoặc tối ưu hóa dành riêng cho Webpack nào không liên quan trực tiếp đến các loader hoặc giải quyết module cơ bản.
- Kiểm tra các mục
resolve.alias. Đảm bảo chúng là các bí danh đường dẫn đơn giản chứ không phải các hàm phức tạp. - Xác minh tất cả các loader tùy chỉnh đều đã được xóa hoặc thay thế bằng các lựa chọn thay thế tương thích với Turbopack (như đã thảo luận ở trên).
- Polyfill: Nếu bạn gặp lỗi liên quan đến các module Node.js (ví dụ:
fs,path,crypto) trong mã phía client, bạn có thể cần phải polyfill chúng một cách rõ ràng hoặc đảm bảo chúng được loại trừ đúng cách cho mục tiêu trình duyệt. - Báo cáo cho Next.js: Nếu bạn đã thu hẹp vấn đề xuống một tính năng Webpack cụ thể, có vẻ tiêu chuẩn mà Turbopack không hỗ trợ, hãy gửi một báo cáo lỗi chi tiết với một bản tái tạo tối thiểu.
2. Thời gian Build tăng trong CI/CD mặc dù có Turbopack
Chế độ lỗi: next build cục bộ với Turbopack nhanh, nhưng các pipeline CI/CD cho thấy ít hoặc không có sự cải thiện, hoặc thậm chí là suy giảm.
Nguyên nhân gốc rễ:
- Thiếu bộ nhớ đệm: Thư mục
.next/cachekhông được duy trì giữa các lần chạy CI/CD. Turbopack phụ thuộc rất nhiều vào bộ nhớ đệm này để xây dựng tăng dần. - Clean build: Các công việc CI/CD đang thực hiện một bản dựng sạch hoàn toàn mỗi lần (ví dụ:
rm -rf .next && next build). - Hạn chế tài nguyên: Các runner CI/CD có CPU hoặc RAM không đủ, làm tắc nghẽn khả năng xử lý song song của Turbopack.
Cách khắc phục:
- Lưu trữ bộ nhớ đệm
.next/cache: Cấu hình hệ thống CI/CD của bạn để lưu trữ bộ nhớ đệm thư mục.next/cache. Điều này là tối quan trọng đối với hiệu suất xây dựng tăng dần.yaml# Example for GitHub Actions - name: Cache Next.js build uses: actions/cache@v3 with: path: | ~/.npm ${{ github.workspace }}/.next/cache key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.ts', '**/*.tsx') }} restore-keys: | ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- - Tránh dọn dẹp không cần thiết: Chỉ thực hiện
rm -rf .nextnếu thực sự cần thiết (ví dụ: nâng cấp phiên bản Next.js lớn, hoặc để gỡ lỗi bộ nhớ đệm bị hỏng). - Giám sát tài nguyên CI/CD: Kiểm tra việc sử dụng CPU và RAM của các tác nhân xây dựng của bạn. Nếu chúng liên tục bị quá tải, hãy cân nhắc nâng cấp lên các runner mạnh hơn.
3. HMR không hoạt động hoặc chậm trong quá trình phát triển
Chế độ lỗi: Các thay đổi đối với tệp không được phản ánh trong trình duyệt, hoặc HMR mất nhiều thời gian, ngay cả với Turbopack.
Nguyên nhân gốc rễ:
- Các vấn đề về giám sát hệ thống tệp: Trong các monorepo lớn, các trình giám sát hệ thống tệp có thể đạt đến giới hạn của hệ điều hành hoặc gặp khó khăn với các liên kết tượng trưng phức tạp.
next.config.mjskhông chính xác: Các cấu hình sai ngăn Turbopack xác định đúng ranh giới module hoặc các phụ thuộc.watchOptionstùy chỉnh trong Webpack: Nếu trước đây bạn cówatchOptionstùy chỉnh trong Webpack, chúng sẽ bị Turbopack bỏ qua.- Môi trường Docker/WSL: Các sự kiện hệ thống tệp có thể không đáng tin cậy hoặc chậm trong các môi trường ảo hóa.
Cách khắc phục:
- Tăng giới hạn trình giám sát tệp của hệ điều hành:
bash
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p - Kiểm tra
next.config.mjs: Đảm bảo không có cấu hìnhwebpacknào vô tình can thiệp vào chế độ dev của Turbopack. - Điều chỉnh dành riêng cho môi trường:
- Docker: Đảm bảo các volume được gắn kết hiệu quả. Cân nhắc sử dụng các tùy chọn
delegatedhoặccachedcho các volume Docker nếu có thể. - WSL2: Đảm bảo dự án của bạn nằm trong hệ thống tệp WSL (ví dụ:
/home/user/project) thay vì các ổ đĩa Windows được gắn kết (ví dụ:/mnt/c/Users/user/project) để có hiệu suất hệ thống tệp tối ưu.
- Docker: Đảm bảo các volume được gắn kết hiệu quả. Cân nhắc sử dụng các tùy chọn
- Cô lập các module có vấn đề: Nếu HMR chậm đối với các module cụ thể, hãy điều tra độ phức tạp hoặc các mẫu nhập khẩu bất thường của chúng.
Các câu hỏi thường gặp
1. Tôi có thể sử dụng Turbopack cho các bản dựng production trong Next.js 15 không?
Có, Next.js 15 cho phép bật Turbopack cho các bản dựng production bằng cách đặt experimental.turbopack: true trong next.config.mjs của bạn. Mặc dù nó là mặc định cho quá trình phát triển, nhưng hỗ trợ production vẫn được coi là thử nghiệm nhưng đang trưởng thành nhanh chóng.
2. Turbopack xử lý các Webpack loader và plugin như thế nào?
Turbopack không trực tiếp hỗ trợ các Webpack loader hoặc plugin. Nó có pipeline xử lý tài sản nội bộ và các phép biến đổi dựa trên SWC. Đối với các trường hợp sử dụng phổ biến như CSS, hình ảnh và SVG, Next.js 15 cung cấp các giải pháp tích hợp tương thích với Turbopack. Đối với các Webpack loader tùy chỉnh cao, bạn có thể cần viết lại chúng dưới dạng plugin SWC, tiền xử lý tài sản hoặc tìm các phương pháp thay thế.
3. Điều gì sẽ xảy ra nếu monorepo của tôi sử dụng thiết lập Babel tùy chỉnh (ví dụ: cho Storybook hoặc Jest)?
Turbopack chỉ ảnh hưởng đến quá trình xây dựng Next.js. Các cấu hình Babel hiện có của bạn cho các công cụ như Storybook, Jest hoặc các phần không phải Next.js khác của monorepo của bạn sẽ không thay đổi và tiếp tục sử dụng Babel. Tuy nhiên, đối với các ứng dụng Next.js, bạn sẽ cần di chuyển các plugin Babel tùy chỉnh sang plugin SWC hoặc sử dụng dự phòng Babel như được mô tả trong phần di chuyển.
4. Turbopack luôn nhanh hơn Webpack phải không?
Trong hầu hết các trường hợp, đặc biệt đối với các ứng dụng lớn và monorepo, Turbopack nhanh hơn đáng kể so với Webpack đối với khởi động lạnh máy chủ phát triển và HMR. Đối với các bản dựng production, hiệu suất tăng cũng đáng kể nhưng có thể khác nhau tùy thuộc vào độ phức tạp của ứng dụng và các tối ưu hóa Webpack cụ thể mà bạn có thể đã có. Kiến trúc dựa trên Rust và biên dịch tăng dần được tối ưu hóa cao mang lại cho Turbopack một lợi thế hiệu suất cơ bản.
5. Turbopack ảnh hưởng đến kích thước gói như thế nào?
Trọng tâm chính của Turbopack là tốc độ xây dựng. Mặc dù nó sử dụng SWC để thu nhỏ và loại bỏ mã chết, vốn rất hiệu quả, nhưng tác động của nó đến kích thước gói cuối cùng so với một bản dựng Webpack được tối ưu hóa cao (ví dụ: với phân tách mã nâng cao, loại bỏ mã chết mạnh mẽ và các trình thu nhỏ tùy chỉnh) có thể không đáng kể hoặc thậm chí lớn hơn một chút trong một số trường hợp hiếm. Tuy nhiên, đối với hầu hết các ứng dụng, kích thước gói sẽ tương đương và những cải thiện về tốc độ xây dựng vượt xa những khác biệt nhỏ về kích thước.
Free In-Browser Developer Tools
Clean AI CLI logs, build cron expressions, decode JWTs, and calculate chmod permissions offline.
Related Articles

Cấu trúc thư mục Next.js App Router: Các phương pháp hay nhất & Kiến trúc doanh nghiệp (2026)
Hướng dẫn cấu trúc thư mục Next.js App Router đã được kiểm nghiệm trong thực tế. Tìm hiểu về route groups, private folders, colocation vs FSD, và tải xuống một template doanh nghiệp có khả năng mở rộng.
Read more
TIÊU ĐỀ: Next.js 15 Partial Prerendering (PPR): Hybrid Streaming, Vòng đời Cache & Kiến trúc Suspense
TÓM TẮT: Hướng dẫn toàn diện về Next.js 15 Partial Prerendering (PPR): hybrid streaming, vòng đời cache và kiến trúc Suspense với kiến trúc cấp độ sản xuất và các ví dụ mã.
Read more
TanStack Query v5 với Next.js 15: Cập nhật lạc quan, đồng bộ hóa bộ nhớ đệm & Server Actions
Hướng dẫn toàn diện về TanStack Query v5 với Next.js 15: cập nhật lạc quan, đồng bộ hóa bộ nhớ đệm và Server Actions với kiến trúc cấp độ sản xuất và ví dụ mã.
Read more