В этой статье мы рассмотрим, как повысить скорость загрузки страницы и повысить производительность.

Недавно мы работали над оптимизацией нашего SPA, созданного с помощью React. Мы смогли набрать 90+ баллов как на настольных компьютерах, так и на мобильных устройствах. Вы также можете проверить результаты самостоятельно.

После оптимизации

Для измерения скорости и производительности страницы используются следующие инструменты: Google Page Speed ​​Insights и GTMetrix.

Перед оптимизацией

Огромная разница !!! Посмотрим, как мы это сделали.

Прежде чем мы начнем, я упомяну термины, на которые мы будем ссылаться в этой статье:
* SPA → одностраничное приложение
* CRA → Create-React-App
* CSR → Отрисовка на стороне клиента
* SSR → Отрисовка на стороне сервера
Также у вас должно быть промежуточное знание Reactjs, Node и npm.

Приложения, созданные с использованием CRA, имеют множество преимуществ, таких как меньше хлопот разработчика, автоматизированные среды разработки и отсутствие конфигураций. Для меня создание приложения для реагирования не является большой проблемой, но настройка среды разработки меня действительно отталкивает. Это одна из причин, по которой facebook выпустил CRA. Но иногда проблематично иметь меньший контроль или отсутствие контроля над тем, как вы настраиваете свое приложение. Рассмотрите возможность разделения кода, использования less или sass. Для достижения этих двух замечательных функций вам может потребоваться извлечь CRA, а затем изменить конфигурацию веб-пакета (что не рекомендуется - после извлечения ваши инструменты сборки никогда не будут обновлены), и без извлечения вы не сможете получить доступ к webpack.conf.
Причина упоминания CRA выше заключается в том, что когда мы создаем приложение, response создает большой отдельный файл для css main.css и аналогичным образом для javascript main.js. Файл JS - это, по сути, все приложение для реагирования, поэтому вы можете представить себе размер приложения от среднего до большого.
Когда страница загружается в браузере, оба файла css и js слишком велики по размеру, они блокируют рендеринг, и пользователи придется долго ждать, чтобы увидеть первое представление на целевой странице (в нашем случае более 10 секунд).
Первым делом мы подумали разделить код js, но не смогли из-за CRA и отсутствия доступа в webpack.conf.

Приложения React - это CSR. Поскольку целевая страница нашего приложения была в основном статическим контентом, мы решили отделить ее и обслуживать от сервера узла (создавая нашу целевую страницу SSR). Под разделением я подразумеваю, что мы помещаем домашнюю страницу html, css, js в папку домашней страницы, а содержимое реакции находится в папке сборки).

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

  1. Установите пакет npm express с помощью команды npm install express.
  2. Установите пакет путь, используя npm install --save path.
  3. Мы также установим пакет express-minify-html с использованием npm i express-minify-html, чтобы мы могли обслуживать минимизированный html и уменьшить размер html-документа.

В файле server.js

const express = require('express');
const path = require('path');
var minifyHTML = require('express-minify-html');
//included the express, path and express-minify-html package
const app = express();
//This creates a new app using express
app.set('views', './homepage/views'); 
// Views directory for static landing page is specified, in my case its homepage/views
app.use(
    minifyHTML({
        override: true,
        exception_url: false,
        htmlMinifier: {
        removeComments: true,
        collapseWhitespace: true,
        collapseBooleanAttributes: true,
        removeAttributeQuotes: true,
        removeEmptyAttributes: true,
        minifyJS: true,
        },
    })
);
//Above piece of code will simply minify my html before serving in the browser, removing comments,white spaces,empty attributes and minifying js also.

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

app.use(express.static(path.join(__dirname, ‘homepage’)));
//This will use static files from homepage folder in base directory. e.g the path formed in my case will be “my-react-application/homepage”
app.get("/", function(req, res) {
    res.render("index");
});

Вышеупомянутая функция будет отображать индексный файл из каталога представлений, как указано выше в функции app.use, всякий раз, когда в браузере посещается URL-адрес /. В моем случае теперь он указывает на homepage/views/index файл, который содержит html для целевой страницы.

Теперь мы определяем маршруты для нашего приложения-реакции после приведенного выше кода.

app.use(express.static(path.join(__dirname, 'build')));
//This will use files from the build folder in base directory. e.g the path formed in my case will be “my-react-application/build”.
app.get('/*', function(req, res) {
    res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

Этот блок кода обслуживает файл index.html из папки ./build (содержит файлы приложения-реакции) для любого URL-адреса, кроме /.
И, наконец, мы запускаем наше приложение, используя app.listen на нашем сервере узла, где развернуто наше приложение.

Наш последний server.js файл выглядит так:

Преимущество этого подхода в том, что теперь наша целевая страница теперь SSR, и мы можем кэшировать содержимое нашего приложения для реагирования. В моем случае main.css и main.js, я предварительно загрузил эти оба файла в свой статический HTML-код целевой страницы, используя следующее:

<link rel='prefetch' href='path/to/my-react-application/main.css' />
<link rel='prefetch' href='path/to/my-react-application/main.js' />

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

Это все ! Дайте мне знать в комментариях о ваших взглядах и мнениях по этому поводу. Кстати, это моя первая статья на Medium!
Спасибо, что прочитали! :)