Node.js уже работает быстро благодаря своей управляемой событиями и асинхронной природе. Но в современном Интернете просто быть быстрым недостаточно. Если вы планируете разработать свое следующее веб-приложение с использованием Node.js, вы должны сделать все возможное, чтобы убедиться, что ваше приложение работает быстрее, чем обычно. В этой статье представлены 10 советов, которые, как известно, значительно ускоряют работу вашего веб-приложения на основе Node. Итак, давайте посмотрим на каждого из них по одному.
1. Параллельно
При создании веб-приложений иногда вам нужно будет сделать несколько внутренних вызовов API для извлечения различных данных. Например, подумайте о приборной панели пользователя. При отображении панели инструментов вы можете выполнить следующие гипотетические вызовы:
- Профиль пользователя —
getUserProfile()
- Недавняя активность —
getRecentActivity()
- Подписки —
getSubscriptions()
getNotifications()
- Уведомления —
function runInParallel() {
async.parallel([
getUserProfile,
getRecentActivity,
getSubscriptions,
getNotifications
], function(err, results) {
//This callback runs when all the functions complete
});
}
Чтобы получить эти данные, вы можете создать отдельное промежуточное программное обеспечение для каждой функции и присоединить его к маршруту панели мониторинга. Но проблема этого подхода в том, что одна функция должна ждать завершения предыдущей. Альтернативный вариант — выполнять эти вызовы параллельно.
Как мы все знаем, Node.js очень эффективен при параллельном запуске нескольких функций благодаря своей асинхронной природе. Мы должны воспользоваться этим. Поскольку функции, которые я упоминал выше, не зависят друг от друга, мы можем запускать их параллельно. Это сократит количество промежуточного программного обеспечения и значительно улучшит скорость.
Для распараллеливания вещей мы можем использовать async.js, модуль Node, который помогает приручить асинхронный JavaScript. Вот фрагмент, который показывает, как разные функции могут работать параллельно с использованием async.js:
// Asynchronous
fs.readFile('file.txt', function(err, buffer) {
var content = buffer.toString();
});
// Synchronous
var content = fs.readFileSync('file.txt').toString();
Если вы хотите узнать больше о async.js, обязательно посетите страницу GitHub проекта.
2. Асинхронный
По дизайну Node.js является однопоточным. Из-за этого синхронный код потенциально может заблокировать все приложение. Например, большинство API файловых систем имеют свои синхронные аналоги. Следующий фрагмент показывает, как операция чтения файла может выполняться как синхронно, так и асинхронно:
var router = express.Router();
router.route('/latestPosts').get(function(req, res) {
Post.getLatest(function(err, posts) {
if (err) {
throw err;
}
res.render('posts', { posts: posts });
});
});
Но если вы выполняете длительные и блокирующие операции, ваш основной поток будет заблокирован до завершения операции. Это резко снижает производительность вашего приложения. Поэтому убедитесь, что вы всегда используете асинхронные API в своем коде, по крайней мере, в критических разделах производительности. Также будьте осторожны при выборе сторонних модулей. Даже если вы примете все меры предосторожности, чтобы избежать синхронного кода, внешняя библиотека может сделать синхронный вызов, влияющий на производительность вашего приложения.
3. Используйте кеширование
Если вы выбираете некоторые данные, которые не часто меняются, вы можете кэшировать их для повышения производительности. Например, возьмем следующий фрагмент, который выбирает последние сообщения для отображения в представлении:
posts
Если вы не публикуете посты в блоге слишком часто, вы можете кэшировать массив redis
Например, мы можем использовать модуль node_redis
Для этого на вашем сервере должен быть установлен Redis. Затем вы можете использовать клиент с именем var redis = require('redis'),
client = redis.createClient(null, null, { detect_buffers: true }),
router = express.Router();
router.route('/latestPosts').get(function(req,res){
client.get('posts', function (err, posts) {
if (posts) {
return res.render('posts', { posts: JSON.parse(posts) });
}
Post.getLatest(function(err, posts) {
if (err) {
throw err;
}
client.set('posts', JSON.stringify(posts));
res.render('posts', { posts: posts });
});
});
}); для хранения пар ключ / значение. Следующий фрагмент показывает, как мы можем кэшировать сообщения:
posts
Итак, сначала мы проверим, существуют ли записи в кэше Redis. Если это так, мы доставляем массив express.static()
В противном случае мы извлекаем содержимое из БД, а затем кешируем его. Кроме того, через некоторое время мы можем очистить кэш Redis, чтобы можно было получать новый контент.
4. Используйте сжатие gzip
Включение сжатия gzip может сильно повлиять на производительность вашего веб-приложения. Когда браузер, совместимый с gzip, запрашивает какой-либо ресурс, сервер может сжать ответ перед отправкой в браузер. Если вы не используете gzip для сжатия статического ресурса, браузеру может потребоваться больше времени для его извлечения.
В приложении Express вы можете использовать встроенное промежуточное ПО compression
Кроме того, вы можете использовать промежуточное программное обеспечение для сжатия и передачи статического содержимого. Вот фрагмент, который показывает, как это сделать:
var compression = require('compression');
app.use(compression()); //use compression
app.use(express.static(path.join(__dirname, 'public')));
5. Используйте клиентскую визуализацию, когда это возможно
С появлением множества мощных клиентских сред MVC / MVVM, таких как AngularJS, Ember, Meteor и т. Д., Стало очень легко создавать одностраничные приложения. По сути, вместо рендеринга на стороне сервера вы просто выставляете API, которые отправляют JSON-ответы клиенту. На стороне клиента вы можете использовать инфраструктуру для использования JSON и отображения в пользовательском интерфейсе. Отправка JSON с сервера может сэкономить пропускную способность и, следовательно, повысить скорость, поскольку вы не отправляете разметку макета с каждым запросом. Скорее вы просто отправляете простой JSON, который затем отображается на стороне клиента.
Взгляните на мое руководство, в котором описано, как представить RESTful API с помощью Express 4. Я также написал другое руководство, в котором показано, как взаимодействовать с этими API с помощью AngularJS.
6. Не храните слишком много в сессиях
В типичном веб-приложении Express данные сеанса по умолчанию хранятся в памяти. Когда вы храните слишком много данных в сеансе, это добавляет значительную нагрузку на сервер. Таким образом, вы можете переключиться на другой тип хранилища, чтобы сохранить данные сеанса, или попытаться минимизировать объем данных, хранящихся в сеансе.
Например, когда пользователи входят в ваше приложение, вы можете просто сохранить свой id
Впоследствии при каждом запросе вы можете извлечь объект из id
Вы также можете использовать MongoDB или Redis для хранения данных сеанса.
7. Оптимизируйте свои запросы
Предположим, у вас есть приложение для ведения блога, которое отображает последние сообщения на главной странице. Вы можете написать что-то вроде этого, чтобы получить данные, используя Mongoose:
Post.find().limit(10).exec(function(err, posts) {
//send posts to client
});
Но проблема в том, что функция find()
Post
Например, comments
Поскольку мы не показываем комментарии, мы можем исключить их при получении. Это определенно улучшит скорость. Мы можем оптимизировать приведенный выше запрос примерно так:
Post.find().limit(10).exclude('comments').exec(function(err, posts) {
//send posts to client
});
8. Используйте стандартные функции V8
Различные операции с коллекциями, такими как map
reduce
forEach
Чтобы преодолеть проблемы совместимости браузера, мы использовали некоторые клиентские библиотеки на стороне клиента. Но с Node.js вы точно знаете, какие операции поддерживаются движком Google V8 JavaScript. Таким образом, вы можете напрямую использовать эти встроенные функции для управления коллекциями на стороне сервера.
9. Используйте nginx перед Node
Nginx — это небольшой и легкий веб-сервер, который можно использовать для снижения нагрузки на ваш сервер Node.js. Вместо того, чтобы обслуживать статические файлы из Node, вы можете настроить nginx для обслуживания статического содержимого. Вы также можете настроить nginx для сжатия ответа с помощью gzip, чтобы общий размер ответа был небольшим. Итак, если вы работаете с производственным приложением, вы можете использовать nginx для повышения скорости.
10. Сократить и объединить JavaScript
Наконец, скорость вашего веб-приложения может быть значительно увеличена путем минимизации и объединения нескольких файлов JS в один. Когда браузер обнаруживает элемент <script>
async
Например, если ваша страница содержит пять файлов JavaScript, браузер сделает пять отдельных HTTP-запросов для их получения. Общая производительность может быть значительно улучшена путем минимизации и объединения этих пяти файлов в один. То же самое относится и к файлам CSS. Вы можете использовать инструмент сборки, такой как Grunt / Gulp, чтобы минимизировать и объединить ваши файлы активов.
Вывод
Эти 10 советов, несомненно, могут повысить скорость вашего веб-приложения. Но я знаю, что еще есть возможности для улучшений и оптимизации. Дайте нам знать в комментариях, если у вас есть такие советы по улучшению производительности.
Спасибо за прочтение!