Динамические страницы Firebase с использованием облачных функций с Firestore медленны

У нас есть динамические страницы, которые обслуживаются облачными функциями Firebase, но TTFB очень медленный на этих страницах с TTFB 900ms - 2s, сначала мы просто предположили, что это проблема с cold start, но даже при постоянном трафике очень медленно TTFB 700 700ms - 1.2s.

Это немного проблематично для нашего проекта, поскольку он зависит от организации трафика, и Google Pagespeed потребует ответа сервера менее 200 200ms.

В любом случае, мы попытались проверить, что может вызвать проблему, и мы определили ее с помощью Firestore, когда Cloud Function обращается к Firestore, мы заметили, что есть некоторые задержки. Это базовый пример кода того, как мы реализуем Cloud Function и Firestore:

dynamicPages.get('/ph/test/:id', (req, res) => {

    var globalStartTime = Date.now();
    var period = [];

    db.collection("CollectionTest")
        .get()
        .then((querySnapshot) => {

            period.push(Date.now() - globalStartTime);

            console.log('1', period);

            return db.collection("CollectionTest")
                .get();

        })
        .then((querySnapshot) => {

            period.push(Date.now() - globalStartTime);

            console.log('2', period);

            res.status(200)
                .send('Period: ' + JSON.stringify(period));

            return true;

        })
        .catch((error) => {

            console.log(error);
            res.end();

            return false;

        });

});

Это работает на Firebase + Cloud Functions + NodeJS

CollectionTest очень мал, и внутри него всего 100 документов, причем каждый документ имеет следующие поля:

directorName: (string)
directorProfileUrl: (string)
duration: (string)
genre: (array)
posterUrl: (string)
rating: (string)
releaseDate: (string)
status: (int)
synopsis: (string)
title: (string)
trailerId: (string)
urlId: (string)

С помощью этого теста мы получим следующие результаты:

[467,762] 1.52s
[203,315] 1.09s
[203,502] 1.15s
[191,297] 1.00s
[206,319] 1.03s
[161,267] 1.03s
[115,222] 843ms
[192,301] 940ms
[201,308] 945ms
[208,312] 950ms

Эти данные являются [ Firestore Call 1 Exectution Time, Firestore Call 2 Exectution Time ] TTFB

Если мы проверим результаты теста, есть признаки того, что TTFB становится ниже, может быть, это когда облачная функция уже разогрелась? Но даже в этом случае Firestore едет до 200-300 мс в Облачной функции, основанной на результатах нашего второго звонка Firestore, и даже если Firestore заняло меньше времени для выполнения, TTFB все равно займет 600-800 мс, но это совсем другая история.

В любом случае, может ли кто-нибудь помочь, как улучшить производительность Firestore в наших Облачных функциях (или, если возможно, в производительности TTFB)? Может быть, мы делаем что-то явно неправильное, о чем мы не знаем?

Ответ 1

Я попытаюсь помочь, но, возможно, вам не хватает контекста о том, что вы загружаете, прежде чем возвращать dynamicPages но здесь есть некоторые подсказки:

Прежде всего, очевидная часть (я должен указать это так или иначе):

1 - Позаботьтесь о том, как вы измеряете TTFB:

Измерение TTFB дистанционно означает, что вы также измеряете задержку сети в то же время, что скрывает то, что TTFB фактически измеряет: насколько быстро веб-сервер может ответить на запрос.

2 - И из документации Google Developers о Understanding Resource Timing (здесь):

[...]. Или:

Bad network conditions between client and server, or
A slowly responding server application

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

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

Не так очевидны:

Вы можете посмотреть официальную документацию Google о производительности Cloud Functions Performance здесь: https://cloud.google.com/functions/docs/bestpractices/tips

Вам нужны были файлы раньше?

В соответствии с этим ответом из Firebase cloud functions is very slow: облачные функции Firebase очень медленные:

Похоже, что многие из этих проблем можно решить, используя скрытую переменную process.env.FUNCTION_NAME, как показано здесь: https://github.com/firebase/functions-samples/issues/170#issuecomment-323375462

Доступны ли эти динамические страницы для доступа к guest пользователю или logged пользователю? Потому что, возможно, первый запрос должен разобраться в деталях аутентификации, поэтому он известен медленнее...

Если ничего из этого не будет сделано, я рассмотрю общие проблемы с производительностью, такие как соединение с БД (здесь: Optimize Database Performance), улучшая конфигурацию сервера, кешируйте все, что вы можете, и позаботитесь о возможных перенаправлениях в вашем приложении...

Чтобы закончить чтение через Интернет, есть много проблем с вашей проблемой (низкая производительность при использовании простых функций облака). Как этот: https://github.com/GoogleCloudPlatform/google-cloud-node/issues/2374 && в SO: https://stackoverflow.com/search?q=%5Bgoogle-cloud-functions%5D+slow

С комментариями:

так как при использовании облачных функций штраф возникает при каждом вызове HTTP, накладные расходы по-прежнему очень высокие (т.е. 0,8 с на HTTP-вызов).

или же:

Имейте в виду, что как облачные функции, так и облачные Firestore находятся в бета-версии и не гарантируют производительности. Я уверен, что если вы сравните производительность с базой данных в реальном времени, вы увидите лучшие цифры.

Возможно, это все еще проблема.

Надеюсь, поможет!