简体   繁体   中英

Any way to optimize function?

so, I have this function here

const [shopItems,setShopItems] = useState("");_
 useEffect(()=> {
    commerce.products.list().then((product) => {
      setShopItems(product)
    });
  }, [])

  
  function categorize(category) {
    let categoryarray = []
    if (shopItems!= "s") {
      shopItems.data.forEach((el)=> {
        for (let i =0; i < el.categories.length; i++) {
          if (el.categories[i].slug == category) categoryarray.push(el)
        }
      })

    }
    return categoryarray;
  }


the useEffect Hook was just for context, I'm mostly concerned about the categorize function. Is there anyway to optimize this since I have observed that my website scrolls very slowly, and I think this might be one of the culprits behind the slow scrolling speeds. Thanks in Advance!

The only way I can see to optimise that code is to exit as soon as a match is found. (I prefer using a while loop for this purpose).

shopItems.data.forEach(el => {
    let idx = 0;
    while (idx < el.categories.length) {
        if (el.categories[idx].slug == category) {
            categoryarray.push(el);
            break;
        } else {
            idx++;
        }
    }
});

If you wanted something that looked slightly better (not mixing forEach and for , for example) you could use this: (no performance enhancements as far as I can see though)

shopItems.data.forEach(el => {
    if (el.categories.map(({ slug }) => slug).includes(category)) categoryarray.push(el);
});

Or even use reduce :

let categoryarray = shopItems.data.reduce((a, c) => {
    if (c.categories.map(({ slug }) => slug).includes(category) return a.concat(c);
    else return a;
}, []);

The first option is still the most performant as realistically it will run through the loop less times.

You can use useMemo https://reactjs.org/docs/hooks-reference.html#usememo

useMemo works by having 2 parameters. A function and an array of dependencies, if any of the dependencies change it re-runs the provided function and stores the value, next render if the dependencies havent changed it just uses the previous value.

const categories = useMemo(() =>  
    let categoryarray = []
    if (shopItems!= "s") {
      shopItems.data.forEach((el)=> {
        for (let i =0; i < el.categories.length; i++) {
          if (el.categories[i].slug == category) categoryarray.push(el)
        }
      })

    }
    return categoryarray;
}, [shopItems.data, category])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM