当前位置:首页 > 科技  > 软件

React性能优化之useMemo、useCallback

来源: 责编: 时间:2023-11-02 09:09:43 247观看
导读前言在React应用程序中进行性能优化至关重要,因为它直接影响用户体验,随后影响转化率和用户留存率。一个经过优化的React应用加载更快,响应迅速,消耗更少的资源,从而为用户提供更顺畅的互动体验。优化React应用程序的性能

前言

在React应用程序中进行性能优化至关重要,因为它直接影响用户体验,随后影响转化率和用户留存率。一个经过优化的React应用加载更快,响应迅速,消耗更少的资源,从而为用户提供更顺畅的互动体验。优化React应用程序的性能对于保留和吸引用户、降低跳出率以及最终实现所期望的业务结果至关重要。sWG28资讯网——每日最新资讯28at.com

记忆化(Memoization)是改善React应用程序性能的一种方式。记忆化涉及缓存值和函数以实现更快的渲染。sWG28资讯网——每日最新资讯28at.com

在本文中,我们将了解什么是记忆化以及如何使用useMemo和useCallback钩子来实现记忆化。sWG28资讯网——每日最新资讯28at.com

理解React中的记忆化

记忆化是存储计算结果的过程,以便在不重新计算的情况下检索它。记忆化用于跳过组件的不必要重新渲染。sWG28资讯网——每日最新资讯28at.com

在React中,可以通过使用useMemo和useCallback钩子来实现记忆化。这些钩子允许你通过缓存函数调用和函数本身来跳过重新渲染。sWG28资讯网——每日最新资讯28at.com

使用useMemo入门

useMemo钩子用于缓存函数调用。useMemo钩子接受两个参数:sWG28资讯网——每日最新资讯28at.com

  • 函数
  • 依赖项数组
const doubledNumber = useMemo(() => {  return someExpensiveCalculation(number);}, [number]);

useMemo钩子在第一次渲染时返回调用函数的结果。在后续重新渲染中,useMemo钩子将提供你的函数调用的缓存值,除非至少一个依赖项发生更改。sWG28资讯网——每日最新资讯28at.com

在JavaScript中,函数在代码再次运行时会被重新创建。这意味着尽管函数的代码相同,但每次应用程序重新渲染时,你的函数并不相同。这是因为JavaScript对象和函数是引用对象。sWG28资讯网——每日最新资讯28at.com

useMemo钩子旨在通过缓存调用函数的结果来消除函数的重新创建。在后续重新渲染中,useMemo钩子会返回缓存的值,跳过函数的重新创建。sWG28资讯网——每日最新资讯28at.com

让我们通过一个实际示例来了解如何在React中使用useMemo。sWG28资讯网——每日最新资讯28at.com

在这个示例中,我们正在对几千篇博客文章进行排序,并将每篇博客文章显示在屏幕上。在每次重新渲染时对博客文章进行排序可能会减慢我们的应用程序。sWG28资讯网——每日最新资讯28at.com

使用useMemo钩子来跳过博客文章的排序,如果文章列表没有更改。sWG28资讯网——每日最新资讯28at.com

function PostList({ posts }) {  const sortedPosts = useMemo(() => {    return [...posts].sort((a, b) => a.date - b.date);  }, [posts]);  return (    <div>      <h2>已排序的文章</h2>      <ul>        {sortedPosts.map((post) => (          <li key={post.id}>{post.title}</li>        ))}      </ul>    </div>  );}

useMemo钩子用于缓存sortedPosts。只有在posts的值更改时,sortedPosts才会重新计算。sWG28资讯网——每日最新资讯28at.com

通过这种方式,排序操作仅在文章数组更改时发生,从而跳过重新渲染并提高性能。sWG28资讯网——每日最新资讯28at.com

充分利用useCallback的能力

useCallback用于缓存函数声明。它同样接受两个参数:sWG28资讯网——每日最新资讯28at.com

  • 函数
  • 依赖项数组

与useMemo不同,useCallback不会调用你的函数。useCallback只是将函数返回给你。你可以自行决定何时以及是否调用函数。sWG28资讯网——每日最新资讯28at.com

useCallback钩子的工作方式与useMemo钩子类似。useCallback通过返回函数的缓存版本来消除函数的重新创建。只有在依赖项中的至少一个值发生更改时,才会重新创建你的函数。sWG28资讯网——每日最新资讯28at.com

让我们看一个使用useCallback来优化React应用程序的示例。sWG28资讯网——每日最新资讯28at.com

在React组件中,当单击按钮时,你有一个对产品数组进行排序的函数。在每次重新渲染时,这个排序函数都会被重新创建。sWG28资讯网——每日最新资讯28at.com

使用useCallback钩子来缓存sortPosts函数声明,以及posts状态作为一个依赖项。sWG28资讯网——每日最新资讯28at.com

import React, { useState, useCallback } from 'react';function PostList() {  const [posts, setPosts] = useState([    { id: 1, title: '文章1', date: new Date('2023-10-15T00:00:00.000Z') },    { id: 2, title: '文章2', date: new Date('2023-10-10T00:00:00.000Z') },    { id: 3, title: '文章3', date: new Date('2023-10-20T00:00:00.000Z') },  ]);  const sortPosts = useCallback(() => {    const sortedPosts = [...posts].sort((a, b) => a.date - b.date);    setPosts(sortedPosts);  }, [posts]);  return (    <div>      <button onClick={sortPosts}>排序文章</button>      <ul>        {posts.map((post) => (          <li key={post.id}>{post.title}</li>        )}      </ul>    </div>  );}export default PostList;

现在,只有当posts状态更改时,sortPosts函数才会被重新创建,从而提高我们的React应用程序性能。sWG28资讯网——每日最新资讯28at.com

通过结合使用useCallback和useMemo来优化性能

useCallback和useMemo钩子可以一起使用,以获得显著的性能提升。sWG28资讯网——每日最新资讯28at.com

React组件重新渲染依赖以下两个条件:sWG28资讯网——每日最新资讯28at.com

  • 状态发生变化
  • 属性发生变化

通过useCallback钩子,你可以缓存属性(如果是一个函数),然后将其传递给包装在useMemo中的子组件。sWG28资讯网——每日最新资讯28at.com

接下来看一个将useCallback与useMemo结合使用的示例。sWG28资讯网——每日最新资讯28at.com

假设你正在为网站开发产品列表页面。用户可以根据价格、品牌和类别等各种标准对产品进行筛选和排序。sWG28资讯网——每日最新资讯28at.com

如果不使用useCallback和useMemo钩子,你的ProductList组件将如下所示:sWG28资讯网——每日最新资讯28at.com

javascriptCopy codeimport React, { useState } from 'react';function ProductList({ products }) {  const [filter, setFilter] = useState('');  const [sortBy, setSortBy] = useState('price');  // 根据用户输入筛选产品  const filteredProducts = products.filter(product =>    product.title.toLowerCase().includes(filter.toLowerCase())  );  // 对筛选后的产品进行排序  const sortedProducts = [...filteredProducts].sort((a, b) => {    if (sortBy === 'price') {      return a.price - b.price;    } else if sortBy === 'rating') {      return b.rating - a.rating;    }    // 在这里处理其他排序条件  });  // 处理筛选更改  const handleFilterChange = (event) => {    setFilter(event.target.value);  };  // 处理排序更改  const handleSortChange = (event) => {    setSortBy(event.target.value);  };  return (    <div>      <input        type="text"        placeholder="筛选产品"        value={filter}        onChange={handleFilterChange}      />      <select value={sortBy} onChange={handleSortChange}>        <option value="price">价格</option>        <option value="rating">评分</option>        {/* 根据需要添加更多排序选项 */}      </select>      <ul>        {sortedProducts.map(product => (          <li key={product.id}>{product.title}</li>        )}      </ul>    </div>  );}export default ProductList;

虽然ProductList组件没有问题,但它可能导致不必要的重新渲染和性能瓶颈。sWG28资讯网——每日最新资讯28at.com

如果ProductList处理大量产品,不必要的重新渲染会减慢你的电子商务站点。sWG28资讯网——每日最新资讯28at.com

使用useMemo和useCallback钩子来减轻不必要的重新渲染并加速你的网站。sWG28资讯网——每日最新资讯28at.com

javascriptCopy codeimport React, { useState, useMemo, useCallback } from 'react';function ProductList({ products }) {  const [filter, setFilter] = useState('');  const [sortBy, setSortBy] = useState('price');  // 根据用户输入筛选产品  const filteredProducts = useMemo(() => {    return products.filter(product => product.title.toLowerCase().includes(filter.toLowerCase()));  }, [products, filter]);  // 对筛选后的产品进行排序  const sortedProducts = useMemo(() => {    return [...filteredProducts].sort((a, b) => {      if (sortBy === 'price') {        return a.price - b.price;      } else if sortBy === 'rating') {        return b.rating - a.rating;      }      // 在这里处理其他排序条件    });  }, [filteredProducts, sortBy]);  // 记忆化回调来处理筛选更改  const handleFilterChange = useCallback((event) => {    setFilter(event.target.value);  }, []);  // 记忆化回调来处理排序更改  const handleSortChange = useCallback((event) => {    setSortBy(event.target.value);  }, []);  return (    <div>      <input        type="text"        placeholder="筛选产品"        value={filter}        onChange={handleFilterChange}      />      <select value={sortBy} onChange={handleSortChange}>        <option value="price">价格</option>        <option value="rating">评分</option>        {/* 根据需要添加更多排序选项 */}      </select>      <ul>        {sortedProducts.map(product => (          <li key={product.id}>{product.title}</li>        )}      </ul>    </div>  );}export default ProductList;

在这个经过优化的ProductList组件版本中,useMemo用于优化筛选和排序操作,而useCallback用于记忆化筛选和排序更改的事件处理程序函数。ProductList组件仅在products的值发生变化时重新渲染。sWG28资讯网——每日最新资讯28at.com

注意事项

尽管useMemo和useCallback是性能优化钩子,但开发人员往往会过度使用这些钩子。有些情况下,使用useMemo和useCallback并不对你的应用程序产生大的收益。由于现代计算机的快速性质,大多数操作都是廉价的。在操作廉价的情况下,你不需要useMemo和useCallback钩子。例如,你有一个要排序的包含100个帖子的数组。使用useMemo或useCallback钩子不会带来任何性能提升,因为排序操作只需要几毫秒。sWG28资讯网——每日最新资讯28at.com

总结

记忆化用于提高React应用程序的性能,记忆化用于跳过组件的不必要重新渲染。useMemo和useCallback钩子分别用于记忆化返回值和函数声明。虽然useMemo和useCallback的行为类似,但两者之间存在关键差异。useMemo返回调用函数的结果;useCallback返回函数本身。sWG28资讯网——每日最新资讯28at.com

useMemo和useCallback钩子有助于优化性能,但使用它们也可能带来一些潜在问题,如过度优化和增加代码复杂性。sWG28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-16535-0.htmlReact性能优化之useMemo、useCallback

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 七个杀手级IntelliJ IDEA插件

下一篇: 你写的Python代码到底多快?这些测试工具了解了解

标签:
  • 热门焦点
  • 6月安卓手机性能榜:vivo/iQOO霸占旗舰排行榜前三

    6月安卓手机性能榜:vivo/iQOO霸占旗舰排行榜前三

    2023年上半年已经正式过去了,我们也迎来了安兔兔V10版本,在新的骁龙8Gen3和天玑9300发布之前,性能榜的榜单大体会以骁龙8Gen2和天玑9200+为主,至于那颗3.36GHz的骁龙8Gen2领先
  • 5月iOS设备好评榜:iPhone 14仅排第43?

    5月iOS设备好评榜:iPhone 14仅排第43?

    来到新的一月,安兔兔的各个榜单又重新汇总了数据,像安卓阵营的榜单都有着比较大的变动,不过iOS由于设备的更新换代并没有那么快,所以相对来说变化并不大,特别是iOS好评榜,老款设
  • 学习JavaScript的10个理由...

    学习JavaScript的10个理由...

    作者 | Simplilearn编译 | 王瑞平当你决心学习一门语言的时候,很难选择到底应该学习哪一门,常用的语言有Python、Java、JavaScript、C/CPP、PHP、Swift、C#、Ruby、Objective-
  • 自动化在DevOps中的力量:简化软件开发和交付

    自动化在DevOps中的力量:简化软件开发和交付

    自动化在DevOps中扮演着重要角色,它提升了DevOps的效能。通过自动化工具和方法,DevOps团队可以实现以下目标:消除手动和重复性任务。简化流程。在整个软件开发生命周期中实现更
  • 这款新兴工具平台,让你的电脑效率翻倍

    这款新兴工具平台,让你的电脑效率翻倍

    随着信息技术的发展,我们获取信息的渠道越来越多,但是处理信息的效率却成为一个瓶颈。于是各种工具应运而生,都在争相解决我们的工作效率问题。今天我要给大家介绍一款效率
  • 猿辅导与新东方的两种“归途”

    猿辅导与新东方的两种“归途”

    作者|卓心月 出品|零态LT(ID:LingTai_LT)如何成为一家伟大企业?答案一定是对&ldquo;势&rdquo;的把握,这其中最关键的当属对企业战略的制定,且能够站在未来看现在,即使这其中的
  • 新电商三兄弟,“抖快红”成团!

    新电商三兄弟,“抖快红”成团!

    来源:价值研究所作 者:Hernanderz 随着内容电商的概念兴起,抖音、快手、小红书组成的&ldquo;新电商三兄弟&rdquo;成为业内一股不可忽视的势力,给阿里、京东、拼多多带去了巨大压
  • 3699元!iQOO Neo8 Pro顶配版今日首销:1TB UFS 4.0同价位唯一

    3699元!iQOO Neo8 Pro顶配版今日首销:1TB UFS 4.0同价位唯一

    5月23日,iQOO推出了全新的iQOO Neo8系列,包含iQOO Neo8和iQOO Neo8 Pro两个版本,其中标准版搭载高通骁龙8+,而Pro版更是首发搭载了联发科天玑9200+旗舰
  • iQOO Neo8 Pro抢先上架:首发天玑9200+ 安卓性能之王

    iQOO Neo8 Pro抢先上架:首发天玑9200+ 安卓性能之王

    经过了一段时间的密集爆料,昨日iQOO官方如期对外宣布:将于5月23日推出全新的iQOO Neo8系列新品,官方称这是一款拥有旗舰级性能调校的作品。随着发布时
Top