Les services workers à la rescousse de nos monolithes

Kévin Jean

Architecte développeur

@kevinj_50886

KevinJean17

Miniplop

LE PREMIER CHARGEMENT

LE SECOND CHARGEMENT

S U A

Single

USAGE

APPLICATION

.

.

  • UNe machine de production qui  tombe à chaque requête

  • UN TTFB > 1 MIN

LA STACK TECHNIQUE

HTML Response

1 min

GET js / Css / images

30 s

Assets Responses
GET /

POURQUOI UN TTFB > 1 Min

HTML Response

1 min

GET js / Css / images

30 s

Assets Responses
GET /

POURQUOI ça crash ?


/**
* Homepage action for serving / routes
*/
public function homepageAction(Request $request)
{
    // Get data from DB for filter bar
    $dataForFilterBar = $this->getDataForFilterBar();

    // Get data from DB for every graph
    $dataForGraph1 = $this->getDataForGraph1();
    $dataForGraph2 = $this->getDataForGraph2();
    $dataForGraph3 = $this->getDataForGraph3();
    $dataForGraph4 = $this->getDataForGraph4();
    $dataForGraph5 = $this->getDataForGraph5();

    // Render the page with all the data
    return $this->render('homepage.twig.html', [
     'dataForFilterBar' => $dataForFilterBar,
     'dataForGraph1' => $dataForGraph1,
     'dataForGraph2' => $dataForGraph2,
     'dataForGraph3' => $dataForGraph3,
     'dataForGraph4' => $dataForGraph4,
     'dataForGraph5' => $dataForGraph5,
    ]);
}


/**
* Homepage action for serving / routes
*/
public function homepageAction(Request $request)
{
    // Get data from DB for filter bar
    $dataForFilterBar = $this->getDataForFilterBar();

    // Get data from DB for every graph
    $dataForGraph1 = $this->getDataForGraph1();
    $dataForGraph2 = $this->getDataForGraph2();
    $dataForGraph3 = $this->getDataForGraph3();
    $dataForGraph4 = $this->getDataForGraph4();
    $dataForGraph5 = $this->getDataForGraph5();

    // Render the page with all the data
    return $this->render('homepage.twig.html', [
     'dataForFilterBar' => $dataForFilterBar,
     'dataForGraph1' => $dataForGraph1,
     'dataForGraph2' => $dataForGraph2,
     'dataForGraph3' => $dataForGraph3,
     'dataForGraph4' => $dataForGraph4,
     'dataForGraph5' => $dataForGraph5,
    ]);
}

Extraire LA COQUILLE HTML

EXtraire lA COQUILLE HTML

homepage.html.twig

<!DOCTYPE html>
<html>
    <body>
        <nav>...</nav>
        <main>...</main>
        <footer>...</footer>
    </body>
</html>
<!DOCTYPE html>
<html>
    <body>
        <nav>...</nav>
        <main>Loading...</main>
        <footer>...</footer>
    </body>
</html>
<!DOCTYPE html>
<main>...</main>

homepage.html.twig

data.html.twig

EXtraire lA COQUILLE HTML


/**
* Homepage action for serving "/" route
*/
public function homepageAction(Request $request)
{
    // Render the page with all the data
    return $this->render('homepage.twig.html');
}

/**
* Homepage action for serving "/data" route
*/
public function dataAction(Request $request)
{
    // Get data from DB for filter bar
    $dataForFilterBar = $this->getDataForFilterBar();

    // Get data from DB for every graph
    $dataForGraph1 = $this->getDataForGraph1();
    $dataForGraph2 = $this->getDataForGraph2();
    $dataForGraph3 = $this->getDataForGraph3();
    $dataForGraph4 = $this->getDataForGraph4();
    $dataForGraph5 = $this->getDataForGraph5();

    // Render the page with all the data
    return $this->render('data.twig.html', [
     'dataForFilterBar' => $dataForFilterBar,
     'dataForGraph1' => $dataForGraph1,
     'dataForGraph2' => $dataForGraph2,
     'dataForGraph3' => $dataForGraph3,
     'dataForGraph4' => $dataForGraph4,
     'dataForGraph5' => $dataForGraph5,
    ]);
}


EXtraire lA COQUILLE HTML

1 s

GET /data
HTML Response

1 min

GET /
GET js / Css / images
Assets Responses

10 s

EXtraire lA COQUILLE HTML

1 s

GET /data
HTML Response

1 min

GET /
GET js / Css / images
Assets Responses

10 s

EXtraire lA COQUILLE HTML

data.html.twig

<main>
    <div class="filter-bar">...</div>
    <div class="graph1">...</div>
    <div class="graph2">...</div>
    <div class="graph3">...</div>
    <div class="graph4">...</div>
    <div class="graph5">...</div>
</main>
<main>
    <div class="filter-bar">
        <p>Loading ...</p>
    </div>
    <div class="graph1">...</div>
    <div class="graph2">...</div>
    <div class="graph3">...</div>
    <div class="graph4">...</div>
    <div class="graph5">...</div>
</main>
<div>...</div>

data.html.twig

filterbar.html.twig

RECUPerer en asynchrone la barre des filtres


/**
* Homepage action for serving "/filter" route
*/
public function filterAction(Request $request)
{
    $dataForFilterBar = $this->getDataForFilterBar();

    // Render the page with all the data
    return $this->render('filter.twig.html', [
     'dataForFilterBar' => $dataForFilterBar,
    ]);
}

/**
* Homepage action for serving "/data" route
*/
public function dataAction(Request $request)
{
    // Get data from DB for every graph
    $dataForGraph1 = $this->getDataForGraph1();
    $dataForGraph2 = $this->getDataForGraph2();
    $dataForGraph3 = $this->getDataForGraph3();
    $dataForGraph4 = $this->getDataForGraph4();
    $dataForGraph5 = $this->getDataForGraph5();

    // Render the page with all the data
    return $this->render('data.twig.html', [
     'dataForGraph1' => $dataForGraph1,
     'dataForGraph2' => $dataForGraph2,
     'dataForGraph3' => $dataForGraph3,
     'dataForGraph4' => $dataForGraph4,
     'dataForGraph5' => $dataForGraph5,
    ]);
}


RECUPerer en asynchrone la barre des filtres

11s

GET /filterBar
HTML Response

50 s

GET /data
HTML Response

10 s

RECUPerer en asynchrone la barre des filtres

...

50 s

Découper les calls APIs

20 s

2 Threads sur le serveur

70 s

30 S

Le Service WORKER

Mise EN PLACE D'un SErvice Worker

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
        navigator.serviceWorker.register('/sw.js').then(function(registration) {
            // Registration was successful
            console.log('ServiceWorker registration successful with scope: ', registration.scope);
        }, function(err) {
            // registration failed :(
            console.log('ServiceWorker registration failed: ', err);
        });
    });
}

OFFLINE-FIRST

(CACHE FALLING BACK TO NETWORK)

1
2
3
4

Mise EN PLACE D'un SErvice Worker


self.addEventListener('fetch', function(event) {
    var requestURL = new URL(event.request.url);
    event.respondWith(
        caches.open('cache').then(function(cache) {
            return cache.match(event.request).then(function (response) {
                 return response || fetch(event.request).then(function(response) {
                        cache.put(event.request, response.clone());
                        return response;
                 });
            });
        })
    );
});

2 s

  • UNe machine de production qui  tombe à chaque requete

  • UN TTFB > 1 MIN 

  • UN TTFB DE 1S

  • UNe machine de production qui  EST PLUS PETITE

GESTION DE La CACHE API


self.addEventListener('fetch', function(event) {
    var requestURL = new URL(event.request.url);

    var urlsWhichResetCache = [
        /\/reset\//,
        /\/search/,
        /\/drilldown/
    ];

    // Reset all the stored cache
    if (pathNameMatchInExpression(requestURL.pathname, urlsWhichResetCache)) {
        caches.keys().then(function(cacheNames) {
            return Promise.all(
                cacheNames.map(function(cacheName) {
                    return caches.delete(cacheName);
                })
            );
        })
    }
});
  • DESSINER LE PROBLEME

  • Utiliser les différents outils du webs (réseau, outil front)

  • Utiliser les services workers :)

MERCI

.businessChallengeContainer {
  display:flex;
  flex-direction: row;

  @include isDesktop() {
    margin-bottom: 48px;
  }

  @include isMobile() {
    flex-direction: column;
  }
}
.businessChallengeContainer {
  display: flex;
  flex-direction: row;
  margin-bottom: 48px;
}
.businessChallengeContainer {
  display:flex;
  flex-direction: row;
  margin-bottom: 48px;

  @include isMobile() {
    flex-direction: column;
  }
}
.businessChallengeContainer {
  display:flex;
  flex-direction: row;

  @include isDesktop() {
    margin-bottom: 48px;
  }

  @include isMobile() {
    flex-direction: column-reverse;
  }
}
.businessChallengeContainer {
  display:flex;
  flex-direction: row;
  margin-bottom: 48px;
}
.businessChallengeContainer {
  display:flex;

  @include isDesktop() {
    flex-direction: row;
    margin-bottom: 48px;
  }

  @include isMobile() {
    flex-direction: column-reverse;
  }
}

Les services workers à la rescousse de nos monolithes

By miniplop

Les services workers à la rescousse de nos monolithes

  • 868