Як обслуговувати статичні файли та покращити продуктивність в Express.js?
Статичні файли та продуктивність в Express.js
Ефективна подача статичних файлів (HTML, CSS, JS, зображення) та стиснення відповідей є основою продуктивності Express.js.
Подача статичних файлів
express.static() — вбудоване проміжне програмне забезпечення Express для подачі статичних активів:
const express = require('express');
const path = require('path');
const app = express();
// Подача всього з папки 'public'
app.use(express.static('public'));
// З абсолютним шляхом (рекомендується)
app.use(express.static(path.join(__dirname, 'public')));
// З префіксом URL
app.use('/static', express.static(path.join(__dirname, 'public')));
// → http://localhost:3000/static/style.csspublic/
index.html → GET /
style.css → GET /style.css
js/app.js → GET /js/app.js
images/logo.png → GET /images/logo.pngОпції статичного проміжного програмного забезпечення
app.use(express.static('public', {
maxAge: '1d', // кешувати на 1 день (кешування браузера)
etag: true, // увімкнути ETag для валідації кешу
lastModified: true, // увімкнути заголовок Last-Modified
index: 'index.html', // файл за замовчуванням для каталогів
dotfiles: 'ignore', // приховати .env, .git файли
extensions: ['html'], // спробувати додати розширення .html
}));Стиснення відповідей
npm install compressionconst compression = require('compression');
// Стиснути всі відповіді (gzip / deflate)
app.use(compression());
// З опціями
app.use(compression({
level: 6, // рівень стиснення 1-9 (6 за замовчуванням)
threshold: 1024, // стиснути тільки відповіді > 1KB
filter: (req, res) => {
// Не стиснути, якщо клієнт не запитує стиснення
if (req.headers['x-no-compression']) return false;
return compression.filter(req, res);
}
}));Заголовки Cache-Control
// Незмінні активи (хешовані імена файлів, такі як app.abc123.js)
app.use('/static', express.static('public', {
maxAge: '1y', // кешувати на 1 рік
immutable: true // повідомити браузеру, що файл ніколи не зміниться
}));
// Динамічний HTML — ніколи не кешувати
app.use((req, res, next) => {
if (req.path.endsWith('.html')) {
res.set('Cache-Control', 'no-cache, no-store, must-revalidate');
}
next();
});Подача збірки React/Vue
// Подача збірки React/Vue з Express
app.use(express.static(path.join(__dirname, 'client/build')));
// Для React Router — надсилати index.html для всіх не-API маршрутів
app.get('*', (req, res) => {
if (!req.path.startsWith('/api')) {
res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
}
});Кілька статичних каталогів
// Express перевіряє каталоги в порядку
app.use(express.static('public'));
app.use(express.static('uploads'));
app.use(express.static('node_modules/bootstrap/dist'));Поради щодо продуктивності
| Техніка | Вплив |
|---|---|
Увімкніть compression | Зменшити розмір відповіді на 60-80% |
Встановіть заголовки Cache-Control | Зменшити повторні запити |
| Використовуйте CDN для активів | Глобальна доставка з низькою затримкою |
| Подавайте з nginx | Значно швидше, ніж Node.js для статичних файлів |
| Використовуйте HTTP/2 | Мультиплексування, стиснення заголовків |
| Пакуйте та мінімізуйте активи | Менше і менші запити |
Виробництво: Використовуйте nginx
У виробництві подавайте статичні файли з nginx перед Express:
# nginx.conf
location /static/ {
root /var/www/myapp/public;
expires 1y;
add_header Cache-Control "public, immutable";
}
location / {
proxy_pass http://localhost:3000;
}Це повністю знімає навантаження з подачі статичних файлів з Node.js.
Резюме
Використовуйте express.static() для подачі файлів та додавайте проміжне програмне забезпечення compression для стиснення відповідей. Встановіть відповідні заголовки Cache-Control для активів з тривалим терміном служби. У виробництві зніміть навантаження з статичних файлів на nginx або CDN для максимальної продуктивності.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.