Как работает JavaScript: 8 советов по оптимизации

От автора: как мы знаем, JavaScript — популярный язык, который используется в клиентских, серверных, мобильных и настольных приложениях. Вот почему создание высокопроизводительных приложений на JavaScript имеет решающее значение. Из-за высокого спроса на создание корпоративных приложений и т.п. оптимизация JavaScript стала горячей темой.

В этой статье обсуждаются типичные ошибки, которые снижают производительность в целом, и несколько советов по оптимизации, которые помогут ускорить выполнение кода JavaScript. Эти небольшие изменения могут быть применены к существующим приложениям и могут избавить вас от больших проблем.

Распространенные ошибки

Вот несколько ошибок, которые замедляют работу приложения. Они оказывают заметное влияние на производительность JavaScript.

1. Слишком много сторонних библиотек и скриптов

По мере роста нашего приложения существует большая вероятность наличия слишком большого количества зависимостей, плагинов или даже скриптов, которые негативно повлияют на производительность приложения. Поможет удаление ненужных зависимостей.

2. Отсутствие CDN

Отличный способ повысить производительность вашего приложения, если в нем много веб-содержимого — это использовать Content Delivery Network (CDN). CDN доставляет ваш статический контент с ближайшего к вам сервера, который будет иметь высокую скорость загрузки.

3. Слишком много HTTP-запросов.

Ваш сайт связывается с сервером через HTTP-запросы для отображения информации. Это означает, что чем больше запросов он выполняет, тем дольше загружается ваша страница. Если ваш сайт загружает много скриптов и ресурсов, это будет проблемой для производительности. Поскольку браузер может загружать другие ресурсы, необходимые для загрузки страницы, то анализ и выполнение JavaScript откладывается.

4. Не сокращенный JavaScript код

Сокращение файла JavaScript приведет к удалению комментариев, сокращению имен переменных, удалению пробелов, а также удалению неиспользуемого кода. Выполнение всего вышеперечисленного не влияет на функциональность приложения, но обеспечивает более быстрое выполнение, поскольку размер файла теперь уменьшен. Есть много инструментов минификации, которые вы можете использовать.

Советы по оптимизации

Здесь мы обсудим несколько способов оптимизации нашего кода JavaScript для повышения производительности.

1. Используйте Promise.all вместо await

Это похоже на то, что мы не должны ждать выполнения, а объединять наши вызовы и неразрешенные промисы в массив. Например, если мы хотим сделать два обращения к нашей базе данных, мы обычно ждем каждого трудоемкого вызова:

const getUsers = async () => { const customers = await findAllCustomers(); const admins = await findAllAdmins(); return { customers, admins }
}

Лучшее, что мы можем сделать, — это запустить оба вызова параллельно и получить результаты примерно за половину времени:

const getUsers = async () => { const customers = findAllCustomers(); const admins = findAllAdmins(); return Promise.all([customers, admins]);
}

Это потому, что нам не нужно ждать каждого выполнения, ибо мы позволяем им работать параллельно.

2. Наличие эффективных циклов

Один из лучших способов оптимизировать ваше приложение JavaScript — использовать корректный оператор цикла. Кроме того, в зависимости от вашего приложения или того, что вы обрабатываете, вы можете использовать императивный подход для циклического перебора ваших данных. Императивный подход — это цикл for или while, в то время как декларативным является map, reduce, filter и другие.

Давайте посмотрим, как мы будем перебирать данные с помощью map, filter и reduce:

// Imagine we had a thousand software engineers data to loop from const result = allSoftwareEngineers
.map(engineer => engineer.salary)
.filter(salary => salary > 100000)
.reduce((prev, next) => prev + next, 0);

Как работает JavaScript: 8 советов по оптимизации

Я не говорю, что map, reduce и все остальное — это плохо, но это зависит от объема данных, и узкое место производительности становится проблемой, если обрабатываемых данных много. Взгляните на этот анализ производительности, в котором сравниваются императивные и декларативные циклы.

Итак, давайте изменим наш код выше, чтобы использовать цикл for:

let results = 0; for (engineer of allSoftwareEngineers) { // Check if salary is above 100000 if (engineer.salary > 100000) results += engineer.salary;
}

Как работает JavaScript: 8 советов по оптимизации

Это в 3 раза быстрее, чем предыдущий подход.

3. Запускайте ваше приложение в кластере.

В Node.js мы можем использовать модуль Cluster для запуска дочернего процесса, который будет работать одновременно с родительским процессом. Каждый из этих дочерних кластеров или процессов, которые мы создаем, запускается в своем V8, цикле событий и памяти. Причина в том, чтобы распределить нагрузку и задачи для каждого процесса.

Как работает JavaScript: 8 советов по оптимизации

Создание кластера в Node.js работает так:

const express = require('express');
const app = express();
const port = 5000;
const cluster = require('cluster');
const numberOfCPUs = require('os').cpus().length; if (cluster.isMaster) { console.log(`Number of CPUs is ${numberOfCPUs}`); console.log(`Master ${process.pid} running`); // Fork workers - create a child process. for (let i = 0; i < numberOfCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); console.log("Let's fork another worker!"); cluster.fork(); }); } else { console.log(`Worker ${process.pid} started`); app.get('/', (req, res) => { res.send('Hello Worker'); }) app.listen(port, () => { console.log(`Listening on port ${port}`); })
}

Мы создаем кластер процессов Node.js для обработки нагрузки.

4. Кэшируйте ответы, если у вас много пользователей.

Мы также можем захотеть кэшировать ответы из базы данных, чтобы пользователям не приходилось ждать тех же данных в конкретный период времени. Наши данные редко изменяются в этот конкретный период, поэтому вместо того, чтобы снова запрашивать из базы данных и выполнять некоторые операции с запрошенными данными, мы получаем их напрямую из кэша.

Как работает JavaScript: 8 советов по оптимизации

5. Используйте диспетчер процессов.

Во время разработки вы запускаете свое приложение с помощью командной строки с помощью node app.js, и в случае сбоя мы снова запускаем ту же команду. В производственной среде это становится проблемой, когда ваше приложение вылетает из-за того, что вы не можете его перезапустить. Для этого рекомендуется использовать диспетчер процессов, например PM2 или Forever. Помимо этого, они по-прежнему предоставляют более подробную информацию и понимание производительности вашего приложения.

6. Используйте потоки чтения Node.js вместо fs.readFile.

Использование fs.readFile было основным решением для чтения содержимого из файла. Функция считывает весь файл и помещает его в память, и если бы нам приходилось обрабатывать большие наборы данных, мы бы увеличили использование памяти или ЦП, что замедлило бы обработку. Лучше использовать потоки чтения Node.js, которые читают прямо с диска и отправляют данные в ответ. Используя поток:

const fs = require("fs");
const data = ''; const readerStream = fs.createReadStream('file.txt'); // Create a readable stream readerStream.setEncoding('UTF8'); // Set the encoding to be utf8. // Handle stream events = data, end, and error
readerStream.on('data', function(chunk) { data += chunk;
}); readerStream.on('end',function() { console.log(data);
}); readerStream.on('error', function(err) { console.log(err.stack);
}); console.log("File Read");

7. Асинхронные функции вместо синхронных

Node.js является однопоточным. Если вы выполняете операции, которые собираются заблокировать процесс/поток, такие как чтение из базы данных /файловой системы или выполнение работы с интенсивным использованием процессора, вы должны использовать асинхронную функцию, чтобы не блокировать поток.

8. Используйте HTTP/2

HTTP/2 – это обновленная версия протокола передачи данных HTTP. Одним из его преимуществ является мультиплексирование, которое позволяет использовать одно и то же TCP-соединение для одновременного приема параллельных запросов и ответов. Эта обновленная версия намного лучше HTTP/1 с точки зрения производительности, поскольку она имеет тенденцию передавать несколько ресурсов одновременно клиенту, получая ответы на ходу. Вот анализ реальных тестов производительности.

Заключение

В этой статье мы обсудили несколько распространенных ошибок, снижающих производительность, и что делать, чтобы их исправить. Важно помнить, что небольшие изменения могут иметь огромное значение с точки зрения производительности.

Крайне важно иметь надлежащий мониторинг и наблюдать за тем, как ваше приложение взаимодействует с пользователями. Иногда простые числа могут быть довольно неоднозначными, поскольку могут показаться вполне нормальными, но на самом деле пользователи могут быть разочарованы.

Вот почему помимо стандартных инструментов мониторинга неплохо иметь такое решение, как SessionStack. SessionStack позволяет воспроизводить сеансы пользователей в виде видео, позволяя точно увидеть, что произошло во время их работы. Вы четко увидите, смущены ли они или разочарованы, когда ваше приложение не работает в соответствии с их ожиданиями, что позволит вам внести необходимые улучшения в ваш продукт. Существует бесплатная пробная версия, если вы хотите попробовать SessionStack.

Как работает JavaScript: 8 советов по оптимизации

Автор: Victor Jonah

Источник: blog.sessionstack.com

Редакция: Команда webformyself.

Читайте нас в Telegram, VK, Яндекс.Дзен