Angular Server Side Rendering та Prerendering
Angular Server Side Rendering та Prerendering

Angular Server Side Rendering та Prerendering

Front-end 03.09.2023 5 min read

Що таке SSR і для чого?

Існує дві причини чому ми можемо і хочемо використовувати SSR: одна з них це швидкість завантаження, а інша SEO. В цьому розділі ми коротко поговоримо про кожну з них, а далі розглянемо як ми можемо це все реалізувати.

Швидке завантаження першої сторінки є важливою частиною будь-якої веб-програми. Звичайні програми Angular завантажуються лише тоді, коли завантажуються необхідні файли: main.js, vendor.js, pollyfills.js і runtime.js, а зі збільшенням розміру main.js час початкового завантаження також збільшується. Згідно з дослідженням Google у 2018 році, 53% користувачів мобільних пристроїв залишають сайт, який завантажується більше трьох секунд. Ми можемо оптимізувати початковий час завантаження програми angular за допомогою angular universal (візуалізація на стороні сервера).

Angular Universal — технологія, яка рендерить програми Angular на сервері. Server side rendering (SSR) генерує повний HTML для сторінки на сервері у відповідь на навігацію, що дозволяє уникнути додаткових запитів для отримання даних і шаблонів на клієнті, оскільки вони обробляються до того, як браузер отримає відповідь.

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

Візуалізація на стороні сервера також допомагає в SEO (оптимізації пошукових систем), віддаючи сканерам вже готовий HTML з доданими атрибутами, і покращує продуктивність на мобільних та малопотужних пристроях.

Реалізація Angular SSR однією командою

У випуску Angular v9 команда Angular Universal додала нову команду ng add для реалізації SSR у додатку angular:

ng add @nguniversal/express-engine

Implement Angular Server Side Rendering : ng add @nguniversal/express-engine

Ця команда додасть і оновить усі необхідні файли для реалізації рендерингу на стороні сервера в додатку angular:

  • src/main.server.ts *
  • src/app/app.server.module.ts *
  • tsconfig.server.json *
  • server.ts *
  • angular.json
  • package.json
  • src/main.ts
  • src/app/app.module.ts

Файли з * будуть створені, а інші оновлені.

@nguniversal/express-engine дозволить додати конструктори CLI, щоб почати рендеринг на стороні сервера в локальній системі та створити робочу збірку за допомогою SSR.

package.json повинен містити такі оновлення:

"dev:ssr": "ng run [project_name]:serve-ssr",
"serve:ssr": "node dist/[project_name]/server/main.js",
"build:ssr": "ng build --prod && ng run [project_name]:server:production",
"prerender": "ng run [project_name]:prerender"

Використовуючи наступну команду, ми можемо почати рендеринг нашого додатка за допомогою Universal у локальній системі:

npm run dev:ssr

Тепер на localhost:4200 ви зможете побачити свій додаток.

Що таке Prerendering і чим він відрізняється від SSR?

Якщо пояснювати коротко, то:

SSR — це відтворення клієнтської або універсальної програми в HTML на сервері.
Prerendering — це запуск програми на стороні клієнта під час збірки для запису її початкового стану як статичного HTML.

В обох методах візуалізації ми створюємо статичні HTML-сторінки, які сканери (crawlers) можуть легко сканувати. Основною відмінністю є місце, де створюються HTML-сторінки.

У техніці візуалізації на стороні сервера, коли користувач переходить до URL, наприклад /about, сервер компілює програму (рендеринг відбувається саме на сервері) і надсилає згенеровану HTML-сторінку назад клієнту.

Під час використання техніки попереднього відтворення (prerendering) всі маршрути програми компілюються під час збирання та зберігаються як статичні HTML-сторінки у файловій системі, які можна надавати клієнту за допомогою CDN. Таким чином щоразу, коли користувач переходить до будь-якого маршруту, він отримуватиме попередньо відрендерені HTML-сторінки.

Перевага prerendering полягає в тому, що він може обслуговувати запити дуже швидко, тому що нічого не потрібно генерувати на льоту. Також SSR задає додаткові витрати на компіляцію на сервері і додаткове навантаження на розробників з точки зору імплементації для складних по логіці сайтів.

Але з іншого боку техніка Prerendering також має свої недоліки

  • Нам потрібно створити HTML для кожного можливого маршруту під час створення, що теж дає додаткове навантаження
  • Попереднє відтворення не працює для сторінок, де ми показуємо вміст динамічно на основі ролі користувача або певної логіки, оскільки роль користувача буде доступна під час виконання.
  • Коли вміст сторінки змінюється, нам потрібно перебудувати програму та зберегти згенеровані файли у файловій системі.

Тому в ситуації, коли нам потрібно часто змінювати вміст сторінки або генерувати контент динамічно для багатьох сторінок — можна задуматися про SSR. Angular Universal дає нам можливість реалізувати обидві техніки візуалізації.

Реалізація SSR та Prerendering за допомогою Angular

Ми продовжимо нашу розробку і додамо Prerendering за допомогою Angular Universal. Після виконання цієї команди (в блоці по налаштуванню SSR) відбулися зміни у окремих файлах для налаштування SSR:

ng add @nguniversal/express-engine

Наступним кроком додамо скріпт для SSR та prerendering у необхідні файли. Для package.json це буде:

"scripts":{
      ...
      "dev:ssr": "ng run got-prerender-demo:serve-ssr",
      "serve:ssr": "node dist/got-prerender-demo/server/main.js",
      "build:ssr": "ng build --prod && ng run got-prerender-demo:server:production",
      "prerender": "ng run got-prerender-demo:prerender"
    }

Для angular.json:

"scripts":{
    ...
    "newProjectRoot": "projects",
    "projects": {
       ...
      "prerender-demo": {
        "architect": {
            ...
            "serve-ssr": {
                "builder": "@nguniversal/builders:ssr-dev-server",
                "options": {
                "browserTarget": "prerender-demo:build",
                "serverTarget": "prerender-demo:server"
                },
                "configurations": {
                "production": {
                    "browserTarget": "prerender-demo:build:production",
                    "serverTarget": "prerender-demo:server:production"
                }
                }
            },
            "prerender": {
                "builder": "@nguniversal/builders:prerender",
                "options": {
                "browserTarget": "prerender-demo:build:production",
                "serverTarget": "prerender-demo:server:production",
                "routes": [
                    "/"
                ]
                },
                "configurations": {
                "production": {}
                }
            }
        }
      }},
    "defaultProject": "prerender-demo"
  }

Створіть додаток SSR і запустити serve для нього можна таким чином:

npm run build:ssr && npm run serve:ssrr

Щоб попередньо відобразити статичні маршрути, нам просто потрібно виконати наступну команду, за допомогою якої Angular шукатиме всі статичні маршрути і попередньо відтворюватиме їх:

npm run prerender

Prerendering : npm run prerender

Тепер в папці dist ви зможете побачити згенеровані html файли для кожного маршруту, наприклад dist/about/index.html.

Коли користувач переходить до будь-якого маршруту (наприклад, /about), сервер або CDN дізнається, звідки йому потрібно дати відповідь: з /about/index.html або з маршруту програми angular. Коли ми переходимо до маршруту, наприклад /about, якщо CDN знаходить папку, подібну до /about/index.html, він візуалізує цю попередньо відрендерену сторінку, інакше шукатиме маршрут у додатку Angular.

Prerendering динамічних маршрутів

Пошук маршрутів, який використовує prerendering з легкістю може виявити статичні маршрути, але не динамічні, такі як /product/:id. Щоб вирішити цю проблему, ми можемо піти двома шляхами:

Опція 1: Ми можемо вручну задати маршрути за допомогою прапорця --routes для кожного маршруту в терміналі:

ng run got-prerender-demo:prerender --routes "/product/583" --routes "/product/584"

або налаштування кожен маршрут у властивості маршрутів angular.json попередньої збірки

"prerender": {
  "builder": "@nguniversal/builders:prerender",
  "options": {
    "browserTarget": "prerender-demo:build:production",
    "serverTarget": "prerender-demo:server:production",
    "routes": [
      "/product/583",
      "/product/584"
    ]
  },
  "configurations": {
    "production": {}
  }
}

Опція 2: Якщо у нас є велика кількість маршрутів, ми можемо записати кожен маршрут в окремому файлі та вказати файл в конфігурації за допомогою прапорця --routesFile або параметра routesFile конструктора попередньої візуалізації, як показано нижче.

Наприклад, створимо dynamic-routes.txt у папці src і додамо усі необхідні додаткові маршрути.

/product/1
/product/2
/product/3

Тепер ми можемо використовувати цей файл маршрутів, призначивши йому прапорець --routesFile:

ng run prerender --routesFile 'dynamic-routes.txt'

Або додати цей файл вручну для конфігурації в angular.json:

"prerender": {
  "builder": "@nguniversal/builders:prerender",
  "options": {
    "browserTarget": "prerender-demo:build:production",
    "serverTarget": "prerender-demo:server:production",
    "routesFile": "./dynamic-routes.txt"
  },
  "configurations": {
    "production": {}
  }
}

В даному прикладі ми бачимо як аргуляр генерує маршрути за допомогою guessRoutes та додаємо файл з додатковою конфігурацією, але якщо ми хочемо визначати маршрути, які мають пререндеритися власноруч, без автоматичної роботи ангуляр, нам потрібно поставити guessRoutes в false (доступно з Angular v11.1).

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

Джерела: angular.io, ngdevelop.tech

Поширити

, , , , , , , , , , , , , , , , , , , ,

guest
0 коментарів
Міжтекстові Відгуки
Переглянути всі коментарі