PWA => détail ou contenu complet ?

Discussion dans 'Développement d'un site Web ou d'une appli mobile' créé par ortolojf, 4 Mai 2021.

  1. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 400
    J'aime reçus:
    25
    Bonjour

    C'est pour une PWA.

    Quelle est la façon la plus optimisée de programmer une PWA ?

    1) Dans le détail : Identifier les pavés de la page et les remplir,

    2) Pour la page entière, convertir le JSON en HTML en une seule fois ?

    Merci beaucoup pour votre aide.
     
  2. spout
    spout WRInaute accro
    Inscrit:
    14 Mai 2003
    Messages:
    9 159
    J'aime reçus:
    326
    Faire un site/app en HTML/CSS/JS classique.
    Mettre en cache les ressources via le Service Worker. Pour rendre le site/app utilisable ou partiellement utilisable en hors ligne.

    Convertir le JSON en HTML ? o_O 100% USELESS.

    Revois les bases:
    Source: https://fr.semrush.com/blog/progressive-web-app/
     
  3. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 400
    J'aime reçus:
    25
    Bonjour

    Dans l'optique de faire une PWA.

    A supposer que je fasse des affichages de page par portions/pavés, quelle serait la meilleure structure de data source => cible pour représenter le format d'une page ?

    Une page ayant 2 dimensions, comment formater la source décrivant le format d'une page ?

    Ou bien, sans se casser la tête, programmer la page statique et la remplir avec du contenu dynamique, sans vouloir trop automatiser le processus ?

    Dans ce cas, j'aurais à me coltiner chaque page à la main. Dur, dur...

    Ou bien aussi, mettre des tokens dans le contenu statique pour automatiser le remplissage ?

    Merci beaucoup de votre aide.
     
  4. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 400
    J'aime reçus:
    25
    Voilà voilà.

    Mieux vaut tard que jamais.

    Associer à chaque "id" de page, l'url de contenu de son pavé.

    J'ai fait le format de index.php de mon site.

    5 pavés.

    Comment profiter des avantages de HTTP/2 en chargeant les différentes urls en même temps ?

    Merci.
     
  5. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 400
    J'aime reçus:
    25
    Un petit détail.

    Comment signaler ( pour le cache ), qu'une url a été modifiée ?

    Est-il possible de mettre le filemtime() ou équivalent, dans le header HTTP ?

    Sinon, quels délais prenez-vous, avant effacement du cache des fichiers ?

    Merci beaucoup.

    Pour ce qui est des associations "id" => url, comment procédez-vous ?

    Mettez-vous l'url en commentaire dans le source ?

    Merci beaucoup de votre aide.

    Amicalement.
     
  6. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 400
    J'aime reçus:
    25
    Rebond.

    Je met le header : "Last-Modified" dans le header, et je le lis en Javasript.

    Code:
      var LastModified = response.headers.get("last-modified");
    
    Mais quel délai ?

    Newbie en PWA...
     
  7. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 400
    J'aime reçus:
    25
    Last but not least...

    Quel algorithme de cache basé sur le timestamp ?

    1) Timestamp constant en cache, si trop ancien refaire cache et timestamp,

    2) Autres.

    Merci beaucoup.
     
  8. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 400
    J'aime reçus:
    25
    Pardon

    Si je tenais compte à la fois de l'"ETag" ( hashcode ) et du "Last-Modified" ( timestamp ), quel serait l'algorithme idéal pour des lectures cache/directes ?

    Si l'Etag lu dans le header séparément ne correspondait pas à celui dans le cache, on refait le cache, sinon non.

    Y a-t-il besoin du "Last-Modified" ( timestamp ) dans cette occurrence ?

    Merci.
     
  9. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 400
    J'aime reçus:
    25
    Rebond

    J'ai commis cette petite api de cache, en fonction des headers : ETag et LastModified.

    Pas encore testé, merci de me dire s'il y a des fautes.



    Code:
    
    const SEP = 'XXYXXX';
    
    function inArray(needle, haystack) {
            var type = typeof haystack;
            if(( type == 'number' ) || ( type == 'string' )) {
                    if(needle == haystack) {
                            return true;
                    }
                    return false;
            }
            var i = haystack.length - 1;
            while(i >= 0){
                    if(needle == haystack[i]){
                            return true;
                    }
                    i--;
            }
            return false;
    }
    
    /**********************************/
    /** CETTE FONCTON REND JSON/TEXT **/
    /**       SUIVANT LE CONTENT-TYPE    **/
    /**            DE LA REPONSE.        **/
    /**********************************/
    const textJson = function(response) {
            return new Promise(function(resolve, reject) {
                    if(response) {
                            var Resp = response.clone();
                            if(Resp.ok) {
                                    if (Resp.headers.get("content-type").match('application/json')) {
                                            Resp.json().then(function(json) {
                                                    resolve(JSON.stringify(json));
                                            }, function(error) {
                                                    reject('1 Error while fetching file : ' + error.message);
                                            })
                                    } else {
                                            Resp.text().then(function(text) {
                                                    resolve(text);
                                            }, function(error) {
                                                    reject('2 Error while fetching file : ' + error.message);
                                            })
                                    }
                            } else {
                                    reject('Error with response Status : ' + Resp.status + ' : ' + Resp.statusText);
                            }
                    } else {
                            reject('Response undefined');
                    }
            });
    };
    
    // Small library to improve on fetch() usage
    const api = function(method, url, data, headers = {}){
            return fetch(url, {
                    method: method.toUpperCase(),
                    body: data,                                            // send it as stringified json
                    credentials: api.credentials,                        // to keep the session on the request
                    headers: Object.assign({}, api.headers, headers)    // extend the headers
            }).then(res => res.ok ? Promise.resolve(res) : Promise.reject(res));
    };
    
    // Defaults that can be globally overwritten
    api.credentials = 'include';
    api.headers = {
            //        'csrf-token': window.csrf || '',     // only if globally set, otherwise ignored
            'mode': 'cors'
            //        'Accept': 'text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8',    // receive text/html
            //        'Content-Type': 'text/html; charset=utf-8'    // send text/html
    };
    // Convenient methods
    ['get', 'post', 'put', 'delete', 'head'].forEach(method => {
            api[method] = api.bind(null, method);
    });
    
    /*****************************************/
    /** ON CHARGE LES HEADERS MIS EN CACHE.    **/
    /*****************************************/
    function getStoredHeaders(request, cache) {
            var Request = request.clone();
            var url = new URL(Request.url, location.href);
            var file = 'Headers_' + url.pathname;
                                                  
            cache.match(file).then(function(response) {
                    if (response) {
                            Response = response.clone();
                            console.log('Response cache = ' + Response);
                            textJson(Response).then(function(text) {
                                    console.log('Succeded while fetching file headers : ' + file + ' with : ' + text);
                                    var index = text.indexOf(SEP);
                                    if(index !== -1) {
                                            var lastModified = text.substring(0, index)
                                            var    etags = text.substring(index + strlen(SEP)));
                                            return new Array(lastModified, etags);
                                    }
                                    return null;
                            }, function(error) {
                                    reject('headers not in cache : ' + file + '  , with error : ' + error.message);
                                    return null;
                            })
                    } else {
                            reject('headers not in cache : ' + file);
                            return null;
                    }
            }, function(error) {
                    reject('headers not in cache : ' + file + '  , with error : ' + error.message);
                    return null;
            })
                                  
            return null;
    }
    
    /*****************************************/
    /**     ON MET EN CACHE LES HEADERS.    **/
    /*****************************************/
    function storedHeaders(request, cache, lastModified, etags) {
            var Request = request.clone();
            var url = new URL(Request.url, location.href);
            var file = 'Headers_' + url.pathname;
            var tmp_value = lastModified + SEP + etags;
            /*************************/
            /**      ON MET EN CACHE    **/
            /**        LE FICHIER        **/
            /*************************/
            cache.put(file, tmp_value).then(function(result) {
                    console.log('file : ' + file + ' set to the cache.');
                    return true;
            }, function(error) {
                    console.log('file : ' + file + ' not set in the cache, with error : ' + error.message);
            })
            return false;
    }
    
    function isNotModified(request, cache)
    {
            var Request        = request.clone();
            var Request1    = request.clone();
            var Request2    = request.clone();
            var Request3    = request.clone();
            /*************************/
            /**    D'APRES LES HEADERS    **/
            /*************************/
            var lastModified    = Request1.headers.get('Last-Modified');
            var etags            = Request2.headers.get('ETag');
            /*************************/
            /**    D'APRES LES ENREG    **/
            /*************************/
            var result = new Array();
            result = getStoredHeaders(Request, cache);
            if(result === null) {
                    return false;
            }
            var LastModified        = result[0];
            var Etag                = result[1];
            var notModified = false;
            if (etags) {
                    notModified = (inArray(Etag, etags) || inArray('*', etags)) && (!lastModified || LastModified == lastModified);
            } elseif (lastModified) {
                    notModified = lastModified == LastModified;
            }
            if (notModified) {
                    /*********************/
                    /** FROM THE CACHE    **/
                    /*********************/
                    this->setNotModified();
            } else {
                    /*********************/
                    /** NOT THE CACHE    **/
                    /*********************/
                    storedHeaders(Request3, cache, lastModified, etags);
            }
            return notModified;
    }
    
    
     
    #9 ortolojf, 6 Mai 2021
    Dernière édition: 6 Mai 2021
  10. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 400
    J'aime reçus:
    25
    Bon

    J'ai un problème pour le ETag.

    Il devrait ne dépendre que du contenu html interprété.

    Ou bien, ce serait un identificateur précisément de ce contenu html.

    J'ai le choix entre le produire en PHP, ou laisser le serveur web le faire.

    La deuxième solution est viable ou non ?

    Merci beaucoup.
     
  11. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 400
    J'aime reçus:
    25
    Voilà c'est fait.

    Super utile la classe de cache de noren.

    Maintenant il y a :

    etag: hash('sha256', $html)

    et :

    last_modified: UTC_Date lors de la mise à jour du cache.

    Testez si voulez : https://www.pronostics-courses.fr

    Cà marche sur toutes les pages, seul le code de class_cache.inc.php est changé.

    Je ne sais pas comment Last-Modified pourrait contenir la date plutôt que le timestamp.

    Enjoy.
     
Chargement...
Similar Threads - PWA détail contenu Forum Date
Quel framework pour une PWA? Développement d'un site Web ou d'une appli mobile 21 Mai 2021
Comment éviter les no-cors sur une PWA ? Développement d'un site Web ou d'une appli mobile 8 Mai 2021
Comment gérer les pages obsolètes d'une PWA ? Développement d'un site Web ou d'une appli mobile 13 Janvier 2021
Question pour une PWA. Développement d'un site Web ou d'une appli mobile 22 Février 2020
PWA => GTM & gestion cookies ? Développement d'un site Web ou d'une appli mobile 20 Janvier 2020
Retour d'expérience sur une PWA Développement d'un site Web ou d'une appli mobile 20 Décembre 2019
Retour expérience PWA Développement d'un site Web ou d'une appli mobile 30 Septembre 2018
Retour d'expérience PWA et SEO? Référencement Google 6 Mars 2018
Où trouver le trafic incorrect Adsense détaillé par jour ? AdSense 5 Mai 2020
Site de petites annonces avec Vidéo pour détailler le bien en vente Demandes d'avis et de conseils sur vos sites 1 Février 2017