Partage
  • Partager sur Facebook
  • Partager sur Twitter

Aider moi a optimiser mon code svp

Sujet résolu
    23 mai 2022 à 13:29:34

    Bonjour, j'aimerai optimiser mon code notamment les boucles , j'avoue que je sèche un peut si vous avez des idées je suis preneur.

    // -----------------------------------------------------DECLARATION DES VARIABLES GLOBAL---------------------------------------------------------------------------------
    let a = 0;
    let b = 0;
    let basket;
    let idproduct;
    let colorproduct;
    let quantityproduct
    let element;
    let addquantity;
    let input;
    let totalQuantity;
    let totalPrice;
    // let firstNameText
    // let lastNameText
    // let addressText
    // let cityText
    // let emailText
    let err = 0
    // ---------------------------------------------------------------FONCTIONS--------------------------------------------------------------------------------------
    function viewBasket(data, element) {
        // getNumberProduct(data)
        // On va chercher des elements dans le DOM
        const section = document.getElementById('cart__items')
        totalQuantity = document.getElementById('totalQuantity')
        totalPrice = document.getElementById('totalPrice')
        // Creation de l'elements
        const article = document.createElement('article')
        const cartItemImg = document.createElement('div')
        let img = document.createElement('img')
        const cardItemContent = document.createElement('div')
        const cardItemContentDescription = document.createElement('div')
        let name = document.createElement('h2')
        let color = document.createElement('p')
        let price = document.createElement('p')
        const cardItemContentSettings = document.createElement('div')
        const cartItemcontentSettingsQuantity = document.createElement('div')
        let quantity = document.createElement('p')
        input = document.createElement('input')
        const CartItemContentSettingsDelete = document.createElement('div')
        const deleteItem = document.createElement('p')
        // Création des attributs des éléments
        article.className = 'cart__item'
        cartItemImg.className = 'cart__item__img'
        cardItemContent.className = 'cart__item__content'
        cardItemContentDescription.className = 'cart__item__content__description'
        cardItemContentSettings.className = 'cart__item__content__settings'
        cartItemcontentSettingsQuantity.className = 'cart__item__content__settings__quantity'
        input.type = 'number'
        input.className = 'itemQuantity'
        input.name = "itemQuantity"
        input.min = 1
        input.max = 100
        input.value = quantity
        CartItemContentSettingsDelete.className = 'cart__item__content__settings__delete'
        deleteItem.textContent = 'Supprimer'
        deleteItem.className = 'deleteItem'
        // Création des attributs des éléments
        name.textContent = data.name
        price.textContent = data.price + '€'
        img.src = data.imageUrl
        img.alt = data.altTxt
        colorproduct = element.color
        quantityproduct = element.quantity
        color.textContent = colorproduct
        quantity.textContent = 'Qté :  '
        input.value = quantityproduct
        // Injection JS en HTML
        section.appendChild(article)
        article.appendChild(cartItemImg)
        cartItemImg.appendChild(img)
        article.appendChild(cardItemContent)
        cardItemContent.appendChild(cardItemContentDescription)
        cardItemContentDescription.appendChild(name)
        cardItemContentDescription.appendChild(color)
        cardItemContentDescription.appendChild(price)
        article.appendChild(cardItemContentSettings)
        cardItemContentSettings.appendChild(cartItemcontentSettingsQuantity)
        cartItemcontentSettingsQuantity.appendChild(quantity)
        cartItemcontentSettingsQuantity.appendChild(input)
        article.appendChild(CartItemContentSettingsDelete)
        CartItemContentSettingsDelete.appendChild(deleteItem)
        // Evenement qui change la qte des articles dans le panier 
        input.addEventListener('input', (e) => {
            basket = JSON.parse(localStorage.getItem('Basket'));
            addquantity = Number(e.target.value)
            let addprice = 0
            basket.forEach(product => {
                if (product._id === element._id && product.color === element.color) {
                    product.quantity = addquantity
                    saveBasket(basket)
                    getNumberProduct(element)
                }
            })
        })
    
        // Evenement qui supprime un article 
        deleteItem.addEventListener('click', (e) => {
    
            basket = JSON.parse(localStorage.getItem('Basket'));
            for (let i = 0; i < basket.length; i++) {
                if (basket[i]._id === element._id) {
                    let del = basket.splice(i, 1)
                    article.remove(cartItemImg)
                    cardItemContentDescription.remove(name)
                    cardItemContentDescription.remove(color)
                    cardItemContentDescription.remove(price)
                    cartItemImg.remove(img)
                    cartItemcontentSettingsQuantity.remove(quantity)
                    cartItemcontentSettingsQuantity.remove(input)
                    CartItemContentSettingsDelete.remove(deleteItem)
                    saveBasket(basket)
                    getNumberProduct(element)
    
                }
            }
        })
    }
    // Fonction qui fait une requet au local storage et a l'api 
    function getBasket() {
        basket = JSON.parse(localStorage.getItem('Basket'));
        basket.forEach(element => {
            idproduct = element._id
            fetch(`http://localhost:3000/api/products/${idproduct}`)
                .then((rep) => rep.json())
                .then((data) => {
                    viewBasket(data, element)
                })
                .catch((error) => console.log(error));
        });
        getNumberProduct()
    }
    // Fonction qui sauvegarde la panier dans le local storage
    function saveBasket(basket) {
        localStorage.setItem("Basket", JSON.stringify(basket));
    }
    // Fonction qui effectue le calcul de la quantite et du montant 
    function getNumberProduct() {
        a = 0
        b = 0
        fetch(`http://localhost:3000/api/products`)
            .then((rep) => rep.json())
            .then((data) => {
                for (let p = 0; p < basket.length; p++) {
                    let s = 0
                    a += Number(basket[p].quantity)
                    while (data[s]._id != basket[p]._id) {
                        s++
                    }
                    b += Number(basket[p].quantity) * Number(data[s].price)
                }
                document.getElementById('totalQuantity').innerHTML = a;
                document.getElementById('totalPrice').innerHTML = b;
            })
            .catch((error) => console.log(error));
    
    }
    getBasket()
    // On va chercher des elements dans le DOM
    let firstName = document.getElementById("firstName");
    let lastName = document.getElementById("lastName");
    let address = document.getElementById("address");
    let city = document.getElementById("city");
    let email = document.getElementById("email");
    const firstNameErrorMsg = document.getElementById("firstNameErrorMsg");
    const lastNameErrorMsg = document.getElementById("lastNameErrorMsg");
    const addressErrorMsg = document.getElementById("addressErrorMsg");
    const cityErrorMsg = document.getElementById("cityErrorMsg");
    const emailErrorMsg = document.getElementById("emailErrorMsg");
    const order = document.getElementById("order");
    // on cree des variables contenant nos regex afin de controler les information saiais par l'utilisateur 
    const searchIdentity = /[a-zA-Z]]/g;
    const searchAdresse = /[a-zA-Z]{1,20}/g;
    const searchCity = /[A-Z]+[A-Z]?\-?[0-9]{1,2} ?[0-9]{3}/g;
    const searchMail = /[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([_\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})/g;
    // on cree des evenement pour recuperer les donnees saisis par l'utilisateur 
    firstName.addEventListener('change', (e) => {
        firstName = e.target.value;
        console.log(firstName)
    });
    
    lastName.addEventListener('change', (e) => {
        lastName = e.target.value;
    });
    
    address.addEventListener('change', (e) => {
        address = e.target.value
    });
    
    city.addEventListener('change', (e) => {
        city = e.target.value;
    });
    
    email.addEventListener('change', (e) => {
        email = e.target.value
    });
    
    // On cree l'evenement qui ecoute le click sur le bouton commander
    order.addEventListener('submit', (e) => {
        e.preventDefault()
        // on verifie le panier
        if (basket.length === 0) {
            alert('Votre Panier est vide !')
            // on verifie les informations entree par l'utilisateur
        } else if (searchIdentity.test(firstName) === false) {
            firstNameErrorMsg.textContent = 'Veuillez renseigner votre prenom';
        } else if (firstName.trim() == "") {
            alert('Le champs prenom est requis')
        }
        else if (searchIdentity.test(lastName) === false) {
            lastNameErrorMsg.textContent = 'Veuillez renseignez votre nom'
        } else if (lastName.trim() == "") {
            alert('Le champs nom est requis')
        } else if (searchAdresse.test(address) === false) {
            addressErrorMsg.textContent = 'Veuillez renseignez votre adresse'
        } else if (address.trim() == "") {
            alert('Le champs adresse est requis')
        } else if (searchCity.test(city) === false) {
            cityErrorMsg.textContent = 'Veuillez renseignez votre ville'
        } else if (city.test() == "") {
            alert('Le champs ville est requis')
        } else if (searchMail.test(email) === false) {
            emailErrorMsg.textContent = 'Veuillez renseignez votre adresse email et respecter le format (exemple@domaine.fr)'
        } else if (email.trim() == "") {
            alert('Le champs email est requis')
        } else {
            // on cree un objet regroupant les informations de l'utilisateur et le panier 
            let customerInfo = { "firstName": firstName, "lastName": lastName, "address": address, "city": city, "email": email }
            let customerBasket = []
            // on pousse les produits de notre panier dans customerBasket
            for (let e = 0; e < cart.length; i++) {
                customerBasket.push(basket[e]._id)
            }
        }
        let sendBasket = { 'contact': customerInfo, 'Product': customerBasket }
    
        fetch("http://localhost:3000/api/products/order", {
            method: "POST",
            headers: {
                'Accept': 'application/json',
                'Content-type': 'application/json'
            },
            body: JSON.stringify(sendBasket)
        })
        
            .then(function (res) {
                if (res.ok) {
                    return res.json();
                }
            })
    
           then((changeLocation) =>{
                location.href = 'confirmation.html'
            })
            .then((err) => {
                console.log('erreur fetch , method : post')
                alert("Erreur ")
            })
    
    })
    
    

    • Partager sur Facebook
    • Partager sur Twitter
      23 mai 2022 à 14:55:02

      Salut,

      Voici quelque propositions : 

      // -----------------------------------------------------DECLARATION DES VARIABLES GLOBAL---------------------------------------------------------------------------------
      let a = 0;
      let b = 0;
      let basket;
      let idproduct;
      let colorproduct;
      let quantityproduct
      let element;
      let addquantity;
      let input;
      let totalQuantity;
      let totalPrice;
      // let firstNameText
      // let lastNameText
      // let addressText
      // let cityText
      // let emailText
      let err = 0
      // ---------------------------------------------------------------FONCTIONS--------------------------------------------------------------------------------------
      function viewBasket(data, element) {
          // getNumberProduct(data)
          // On va chercher des elements dans le DOM
          const section = document.getElementById('cart__items');
          totalQuantity = document.getElementById('totalQuantity');
          totalPrice = document.getElementById('totalPrice');
          // Creation de l'elements
          const article = document.createElement('article');
          const cartItemImg = document.createElement('div');
          let img = document.createElement('img');
          const cardItemContent = document.createElement('div');
          const cardItemContentDescription = document.createElement('div');
          let name = document.createElement('h2');
          let color = document.createElement('p');
          let price = document.createElement('p');
          const cardItemContentSettings = document.createElement('div');
          const cartItemcontentSettingsQuantity = document.createElement('div');
          let quantity = document.createElement('p');
          input = document.createElement('input');
          const CartItemContentSettingsDelete = document.createElement('div');
          const deleteItem = document.createElement('p');
          // Création des attributs des éléments
          article.className = 'cart__item';
          cartItemImg.className = 'cart__item__img';
          cardItemContent.className = 'cart__item__content';
          cardItemContentDescription.className = 'cart__item__content__description';
          cardItemContentSettings.className = 'cart__item__content__settings';
          cartItemcontentSettingsQuantity.className = 'cart__item__content__settings__quantity';
          input.type = 'number';
          input.className = 'itemQuantity';
          input.name = "itemQuantity";
          input.min = 1;
          input.max = 100;
          input.value = quantity;
          CartItemContentSettingsDelete.className = 'cart__item__content__settings__delete';
          deleteItem.textContent = 'Supprimer';
          deleteItem.className = 'deleteItem';
          // Création des attributs des éléments
          name.textContent = data.name;
          price.textContent = data.price + '€';
          img.src = data.imageUrl;
          img.alt = data.altTxt;
          colorproduct = element.color;
          quantityproduct = element.quantity;
          color.textContent = colorproduct;
          quantity.textContent = 'Qté :  ';
          input.value = quantityproduct;
          // Injection JS en HTML
          section.appendChild(article);
          article.appendChild(cartItemImg);
          cartItemImg.appendChild(img);
          article.appendChild(cardItemContent);
          cardItemContent.appendChild(cardItemContentDescription);
          cardItemContentDescription.appendChild(name);
          cardItemContentDescription.appendChild(color);
          cardItemContentDescription.appendChild(price);
          article.appendChild(cardItemContentSettings);
          cardItemContentSettings.appendChild(cartItemcontentSettingsQuantity);
          cartItemcontentSettingsQuantity.appendChild(quantity);
          cartItemcontentSettingsQuantity.appendChild(input);
          article.appendChild(CartItemContentSettingsDelete);
          CartItemContentSettingsDelete.appendChild(deleteItem);
          // Evenement qui change la qte des articles dans le panier
          input.addEventListener('input', (e) => {
              basket = JSON.parse(localStorage.getItem('Basket'));
              addquantity = Number(e.target.value);
              //let addprice = 0;
              for(const product of basket) {
                  if (product._id === element._id && product.color === element.color) {
                      product.quantity = addquantity;
                      saveBasket(basket);
                      getNumberProduct(element);
                  }
              }
          })
       
          // Evenement qui supprime un article
          deleteItem.addEventListener('click', (e) => {
       
              basket = JSON.parse(localStorage.getItem('Basket'));
              for (let i = 0; i < basket.length; i++) {
                  if (basket[i]._id === element._id) {
                      let del = basket.splice(i, 1);
                      article.remove(cartItemImg);
                      cardItemContentDescription.remove(name);
                      cardItemContentDescription.remove(color);
                      cardItemContentDescription.remove(price);
                      cartItemImg.remove(img);
                      cartItemcontentSettingsQuantity.remove(quantity);
                      cartItemcontentSettingsQuantity.remove(input);
                      CartItemContentSettingsDelete.remove(deleteItem);
                      saveBasket(basket);
                      getNumberProduct(element);
       
                  }
              }
          })
      }
      // Fonction qui fait une requet au local storage et a l'api
      async function getBasket() {
          basket = JSON.parse(localStorage.getItem('Basket'));
          for(const [data, element] of await Promise.all(
              basket.map(element => [
                  fetch(`http://localhost:3000/api/products/${element._id}`).then((rep) => rep.json()),
                  element
              ])).catch((error) => console.log(error))) {
              viewBasket(data, element);
          }
          getNumberProduct();
      }
      // Fonction qui sauvegarde la panier dans le local storage
      function saveBasket(basket) {
          localStorage.setItem("Basket", JSON.stringify(basket));
      };
      // Fonction qui effectue le calcul de la quantite et du montant
      async function getNumberProduct() {
          a = 0;
          b = 0;
          const request = await fetch(`http://localhost:3000/api/products`).catch((error) => console.log(error));
          const data = await request.json().catch((error) => console.log(error));
          for (let p = 0; p < basket.length; p++) {
              a += Number(basket[p].quantity);
              b += Number(basket[p].quantity) * Number(data.find(x => x._id === basket[p]._id).price);
          }
          document.getElementById('totalQuantity').innerHTML = a;
          document.getElementById('totalPrice').innerHTML = b;
              
       
      }
      getBasket();
      // On va chercher des elements dans le DOM
      let firstName = document.getElementById("firstName");
      let lastName = document.getElementById("lastName");
      let address = document.getElementById("address");
      let city = document.getElementById("city");
      let email = document.getElementById("email");
      const firstNameErrorMsg = document.getElementById("firstNameErrorMsg");
      const lastNameErrorMsg = document.getElementById("lastNameErrorMsg");
      const addressErrorMsg = document.getElementById("addressErrorMsg");
      const cityErrorMsg = document.getElementById("cityErrorMsg");
      const emailErrorMsg = document.getElementById("emailErrorMsg");
      const order = document.getElementById("order");
      // on cree des variables contenant nos regex afin de controler les information saiais par l'utilisateur
      const searchIdentity = /[a-zA-Z]]/g;
      const searchAdresse = /[a-zA-Z]{1,20}/g;
      const searchCity = /[A-Z]+[A-Z]?\-?[0-9]{1,2} ?[0-9]{3}/g;
      const searchMail = /[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([_\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})/g;
      // on cree des evenement pour recuperer les donnees saisis par l'utilisateur
      firstName.addEventListener('change', (e) => {
          firstName = e.target.value;
          console.log(firstName);
      });
       
      lastName.addEventListener('change', (e) => {
          lastName = e.target.value;
      });
       
      address.addEventListener('change', (e) => {
          address = e.target.value;
      });
       
      city.addEventListener('change', (e) => {
          city = e.target.value;
      });
       
      email.addEventListener('change', (e) => {
          email = e.target.value;
      });
       
      // On cree l'evenement qui ecoute le click sur le bouton commander
      order.addEventListener('submit', async (e) => {
          e.preventDefault();
          let customerInfo;
          let customerBasket = [];
          // on verifie le panier
          if (basket.length === 0) {
              alert('Votre Panier est vide !');
              // on verifie les informations entree par l'utilisateur
          } else if (searchIdentity.test(firstName) === false) {
              firstNameErrorMsg.textContent = 'Veuillez renseigner votre prenom';
          } else if (firstName.trim() == "") {
              alert('Le champs prenom est requis');
          }
          else if (searchIdentity.test(lastName) === false) {
              lastNameErrorMsg.textContent = 'Veuillez renseignez votre nom'
          } else if (lastName.trim() == "") {
              alert('Le champs nom est requis');
          } else if (searchAdresse.test(address) === false) {
              addressErrorMsg.textContent = 'Veuillez renseignez votre adresse'
          } else if (address.trim() == "") {
              alert('Le champs adresse est requis');
          } else if (searchCity.test(city) === false) {
              cityErrorMsg.textContent = 'Veuillez renseignez votre ville'
          } else if (city.test() == "") {
              alert('Le champs ville est requis');
          } else if (searchMail.test(email) === false) {
              emailErrorMsg.textContent = 'Veuillez renseignez votre adresse email et respecter le format (exemple@domaine.fr)'
          } else if (email.trim() == "") {
              alert('Le champs email est requis');
          } else {
              // on cree un objet regroupant les informations de l'utilisateur et le panier
              customerInfo = { "firstName": firstName, "lastName": lastName, "address": address, "city": city, "email": email };
              // on pousse les produits de notre panier dans customerBasket
              for (let e = 0; e < cart.length; i++)
                  customerBasket.push(basket[e]._id);
          }
          let sendBasket = { 'contact': customerInfo, 'Product': customerBasket };
       
          const request = await fetch("http://localhost:3000/api/products/order", {
              method: "POST",
              headers: {
                  'Accept': 'application/json',
                  'Content-type': 'application/json'
              },
              body: JSON.stringify(sendBasket)
          });
          let changeLocation;
          if (request.ok)
              changeLocation = await res.json(); // ??? Tu fait quoi du résultat ?
          location.href = 'confirmation.html';
      });
      • 1) Les points-virgules ne sont plus une nécessité en javascript pour les navigateurs les plus récent, mais ne pas les mettre force le navigateur à travailler davantage pour interpréter le code. Donc bien rajouté un point-virgule à la fin de chaque instruction qui la requière, c'est déjà une première optimisation.
      • 2) Une boucle do/for/while sera toujours plus efficace qu'un forEach. Toutefois, la différence d'efficacité reste mince et dans un cas comme le tien où le nombre d'itération est très faible, ça n'a pas vraiment d'incidence sur les performances de ton application.
      • 3) Tu peux améliorer l'efficacité de tes instructions asynchrone (comme fetch) en les regroupant à l'aide de Promise.all.
      • 4) Tu as une horrible boucle while pour faire quelque chose de très simple (ligne 146) : Pour retrouver un élément dans un array, il existe la méthode find. C'est pas une optimisation, mais c'est beaucoup plus claire dans ton code que ce gros pâté.
      • 5) Tu as deux erreurs de scope ligne 227 et 228. Mais c'est une optimisation seulement si tu veux que ton app fonctionne comme tu le souhaite :D.
      • 6) Les alert c'est vraiment pas user-friendly, bon retour dans les années 2000 avec ça :x...
      • 7) C'est juste une suggestion, mais je trouve l'écriture async/await plus claire qu'un enchainement effréné de then.
      • 8) Ligne 91 et 112, tu appelles une fonction qui ne prend pas de paramètre avec un argument qui n'est donc jamais utile (dans les deux cas). Ligne 137 pour la définition de ta fonction.

      Pour en revenir à tes boucles, les optimiser n'a pas vraiment beaucoup de sens (à par pour le coup du while), comme je te le disais, une boucle for est textuellement plus lourde qu'un forEach, mais en terme de performance, ça reste mieux dans la quasi totalité des cas. C'est vraiment qu'une question de préférence j'imagine.

      Par contre, ton code gagnerais vraiment à être écrit plus clairement. Je dit surtout ça pour le jour ou tu vas avoir besoin de te relire, qu'il se sera passer plusieurs semaines/mois et que tu vas tomber sur ta fameuse boucle while et que tu vas pas comprendre ce que tu voulais faire...

      -
      Edité par BrainError 23 mai 2022 à 15:07:39

      • Partager sur Facebook
      • Partager sur Twitter
        23 mai 2022 à 16:36:27

        Merci beaucoup pour ton retour je t'avoue que c'est mon premier code en js et qu'il est pas fini je bute sur deux trois soucis, merci pour ta proposition d'optimisation :)
        • Partager sur Facebook
        • Partager sur Twitter
          23 mai 2022 à 16:59:56

          Bonjour, je n'ai pas lu l'intégralité du fichier (un petit peu longer ) mais justement tu peux déjà envisager de séparer ton code en plusieurs fichiers.

          Pour le faire correctement il faut que tu essaies de déterminer les différentes actions que fait ton code,

          puis de réussir à isoler ces actions dans un code indépendant puis à ce moment tu pourras mettre le code indépendant dans un fichier à part.

          Évidement avoir un certain volume de code qui est séparé en plusieurs fichiers le rend plus facilement lisible/maintenable/debugable

          est par la suite si tu veux écrire des tests ce sera aussi plus facile de la faire avec des petits morceau de code qui on des rôles isolé du reste de l'application.

          À ta place je chercherai comment réussir à décomposer la fonction viewBasket qui est une fonction de quasiment 100 lignes,

          dans l'idéal une fonction n'a qu'un seul rôle est peut s'écrire en une vingtaine de lignes,

          même si la deuxième règle n'est pas toujours vraie c'est mieux d'essayer de s'en rapprocher.

          Je n'ai pas lu l'intégralité de la fonction mais je vois différentes parties du document qui sont mises à jour puis des écouteurs d'événements avec leurs callbacks, ça peut faire des rôles (donc fonctions) différentes.

          • Partager sur Facebook
          • Partager sur Twitter

          suggestion de présentation.

          Aider moi a optimiser mon code svp

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown