当前位置: 首页 > news >正文

phpcms怎么做网站永久免费无代码开发平台网站

phpcms怎么做网站,永久免费无代码开发平台网站,web动态网站开发,全屏网站制作在React项目中是经常会使用到useMemo,useCallBack的,这是两个优化性能的方法,那么useMemo,useCallBack到底是什么呢?什么时候用呢? 下面将给打击分享相关知识,希望对大家有所帮助同时欢迎讨论指…

在React项目中是经常会使用到useMemo,useCallBack的,这是两个优化性能的方法,那么useMemo,useCallBack到底是什么呢?什么时候用呢? 下面将给打击分享相关知识,希望对大家有所帮助同时欢迎讨论指出问题!

1.useMemo
  • useMemo:会在在组件首次加载和重渲染期间执行,执行的函数需要和渲染相关的。

使用示例如下:

import React, {useMemo, useState} from "react";

function Memo (){

   const [count, setCount] = useState(0)

   const [bool, setBool] = useState(true)

useMemo(() => { console.log('useMemo') }, [count])

return ( <div>

        <div>{count}</div>

        <div>{bool ? '正面' : '反面'}</div>

       <button onClick={() => setCount(count + 1)}>+1哟!</button>        <button onClick={() => setBool(!bool)}>点击取反操作</button> </div> ) } export default Memo;

useMemo 类似于Vue的计算属性computed,监听某个值的变化,根据变化的值重新计算新值;通过点击触发改变count的值,组件会重新渲染且useMemo会监听count值的变化进行重新计算,但是当我触发改变bool的值,组件只进行了重新渲染但是useMemo没有重新计算并执行,因为当前useMomo监听的时count的变化,其他变化则不会去管;

2.useCallback
  • useCallback:会在渲染期间执行,返回一个函数,useCallback是用来帮忙缓存函数的,当依赖项没有发生变化时,返回缓存的指针,当在依赖项变化的时候会更新,返回一个新的函数

使用示例:

import React, { useState, useCallback } from 'react'; export default function App() { const [count1, setCount1] = useState(0); const [count2, setCount2] = useState(0); const handleClickButton1 = () => {setCount1(count1 + 1)}; const handleClickButton2 = useCallback(() => { console.log('useCallback') setCount2(count2 + 1); }, [count2]); return ( <div> <div> <Button onClick={handleClickButton1}>点击Button1</Button> </div> <div> <Button onClick={handleClickButton2}>点击Button2</Button> </div> </div> ); }

详细讲解:经过useCallback优化后,当Button2 是点击触发时自身时才会更新,Button1只要父组件更新后才会变更。

为什么使用 useMemo 和 useCallback

使用 memo 通常有三个原因:

  1. ✅ 防止不必要的 effect。
  2. ❗️防止不必要的 re-render。
  3. ❗️防止不必要的重复计算。

后两种优化往往被误用,导致出现大量的无效优化或冗余优化。下面详细介绍这三个优化方式。

防止不必要的 effect

如果一个值被 useEffect 依赖,那它可能需要被缓存,这样可以避免重复执行 effect。

const Component = () => { // 在 re-renders 之间缓存 a 的引用 const a = useMemo(() => ({ test: 1 }), []); useEffect(() => { // 只有当 a 的值变化时,这里才会被触发 doSomething(); }, [a]); // the rest of the code };

useCallback 同理:

const Component = () => { // 在 re-renders 之间缓存 fetch 函数 const fetch = useCallback(() => { console.log('fetch some data here'); }, []); useEffect(() => { // 仅fetch函数的值被改变时,这里才会被触发 fetch(); }, [fetch]); // the rest of the code };

当变量直接或者通过依赖链成为 useEffect 的依赖项时,那它可能需要被缓存。这是 useMemo 和 useCallback 最基本的用法。

防止不必要的 re-render

进入重点环节了🔔。正确的阻止 re-render 需要我们明确三个问题:

  1. 组件什么时候会 re-render。
  2. 如何防止子组件 re-render。
  3. 如何判断子组件需要缓存。
1. 组件什么时候会 re-render

三种情况:

  1. 当本身的 props 或 state 改变时。
  2. Context value 改变时,使用该值的组件会 re-render。
  3. 当父组件重新渲染时,它所有的子组件都会 re-render,形成一条 re-render 链。

第三个 re-render 时机经常被开发者忽视,导致代码中存在大量的无效缓存

例如:

const App = () => { const [state, setState] = useState(1); const onClick = useCallback(() => { console.log('Do something on click'); }, []); return ( // 无论 onClick 是否被缓存,Page 都会 re-render <Page onClick={onClick} /> ); };

当使用 setState 改变 state 时,App 会 re-render,作为子组件的 Page 也会跟着 re-render。这里 useCallback 是完全无效的,它并不能阻止 Page 的 re-render。

2. 如何防止子组件 re-render

必须同时缓存 onClick 和组件本身,才能实现 Page 不触发 re-render。

const PageMemoized = React.memo(Page); const App = () => { const [state, setState] = useState(1); const onClick = useCallback(() => { console.log('Do something on click'); }, []); return ( // Page 和 onClick 同时 memorize <PageMemoized onClick={onClick} /> ); };

由于使用了React.memo,PageMemoized 会浅比较 props 的变化后再决定是否 re-render。onClick 被缓存后不会再变化,所以 PageMemoized 不再 re-render。

然而,如果 PageMemoized 再添加一个未被缓存的 props,一切就前功尽弃 🤯 :

const PageMemoized = React.memo(Page); const App = () => { const [state, setState] = useState(1); const onClick = useCallback(() => { console.log('Do something on click'); }, []); return ( // page WILL re-render because value is not memoized <PageMemoized onClick={onClick} value={[1, 2, 3]} /> ); };

由于 value 会随着 App 的 re-render 重新定义,引用值发生变化,导致 PageMemoized 仍然会触发 re-render。

现在可以得出结论了,必须同时满足以下两个条件,子组件才不会 re-render:

  1. 子组件自身被缓存。
  2. 子组件所有的 prop 都被缓存。
3. 如何判断子组件需要缓存

我们已经了解,为了防止子组件 re-render,需要以下成本:

  1. 开发者工作量的增加: 一旦使用缓存,就必须保证组件本身以及所有 props 都缓存,后续添加的所有 props 都要缓存。
  2. 代码复杂度和可读性的变化:代码中出现大量缓存函数,这会增加代码复杂度,并降低易读性。

除此之外还有另外一个成本:性能成本。 组件的缓存是在初始化时进行,虽然每个组件缓存的性能耗费很低,通常不足1ms,但大型程序里成百上千的组件如果同时初始化缓存,成本可能会变得很可观。

所以局部使用 memo,比全局使用显的更优雅、性能更好,坏处是需要开发者主动去判断是否需要缓存该子组件。

🤨 那应该什么时候缓存组件,怎么判断一个组件的渲染是昂贵的?

很遗憾,似乎没有一个简单&无侵入&自动的衡量方式。通常来说有两个方式:

人肉判断,开发或者测试人员在研发过程中感知到渲染性能问题,并进行判断。通过工具,目前有一些工具协助开发者在查看组件性能:如 React Dev Tools Profiler,这篇文章介绍了使用方式如这个 hooks:useRenderTimes另外,React 在 16.5版本后提供了 Profiler API:_它可以识别出应用中渲染较慢的部分,或是可以使用类似 memoization 优化的部分_。所以可以通过 puppeteer 或 cypress 在自动化集成中测试组件性能,这很适合核心组件的性能测试。

防止不必要的重复计算

如 React 文档所说,useMemo 的基本作用是,避免在每次渲染时都进行高开销的计算。

🤨 那什么是“高开销的计算”?

高开销的计算其实极少出现,如下示例,对包含 250 个 item 的数组 countries 进行排序、渲染,并计算耗时。

const List = ({ countries }) => { const before = performance.now(); const sortedCountries = orderBy(countries, 'name', sort); // this is the number we're after const after = performance.now() - before; return ( // same ) };

结果如图所示,排序耗时仅用了 4 毫秒,而渲染图中的 List 组件(仅仅只是 button + 文字)却用了 20 毫秒,5倍的差距,代码详见 codesandbox.。 大部分情况下,我们的计算量要比这个 250 个 item 的数组少,而组件渲染要比这个 List 组件复杂的多,所以真实程序中,计算和渲染的性能差距会更大。

可见,组件渲染才是性能的瓶颈,应该把 useMemo 用在程序里渲染昂贵的组件上,而不是数值计算上。当然,除非这个计算真的很昂贵,比如阶乘计算。

至于为什么不给所有的组件都使用 useMemo,上文已经解释了。useMemo 是有成本的,它会增加整体程序初始化的耗时,并不适合全局全面使用,它更适合做局部的优化。

为什么 React 没有把缓存组件作为默认配置?

关于这点 Dan Abramov 在推文上也给出了解释(虽然是个类比 😅):评论区里 react 的另一位核心开发者 Christopher Chedeau 也参与了讨论。 简而言之,他们认为:

  1. 缓存是有成本的,小的成本可能会累加过高。
  2. 默认缓存无法保证足够的正确性。

原因 2 的原文:correctness is not guaranteed for everything because people can mutate things. Christopher Chedeau 未给出进一步解释。或许他是指可能会导致跟 PureComponent相同的问题,即浅比较 mutate things 时,由于浅比较相等,导致组件未能 update 的问题。

结论

讲到这里我们可以总结出 useMemo/useCallback 使用准则了:

  1. 大部分的 useMemo 和 useCallback 都应该移除,他们可能没有带来任何性能上的优化,反而增加了程序首次渲染的负担,并增加程序的复杂性。
  2. 使用 useMemo 和 useCallback 优化子组件 re-render 时,必须同时满足以下条件才有效
    1. 子组件已通过 React.memo 或 useMemo 被缓存
    2. 子组件所有的 prop 都被缓存
  3. 不推荐默认给所有组件都使用缓存,大量组件初始化时被缓存,可能导致过多的内存消耗,并影响程序初始化渲染的速度。

关于第三点有相反观点,详见:Why We Memo All the Things,作者推荐默认给全部组件都加上 React.memo,并给所有 props 都套上 useMemo。他认为这样可以降低工程师心智负担,让工程师不必再自己判断什么时候使用 memorize。

总结

相同点:

useCallback 和 useMemo 都是性能优化的手段,类似于类组件中的 shouldComponentUpdate,在子组件中使用 shouldComponentUpdate, 判定该组件的 props 和 state 是否有变化,从而避免每次父组件render时都去重新渲染子组件。

不同点:

useCallback 和 useMemo 的区别是useCallback返回一个函数,当把它返回的这个函数作为子组件使用时,可以避免每次父组件更新时都重新渲染这个子组件。


文章转载自:
http://barbados.jqLx.cn
http://libertyman.jqLx.cn
http://bryce.jqLx.cn
http://cgm.jqLx.cn
http://lymphangiography.jqLx.cn
http://snackery.jqLx.cn
http://concessible.jqLx.cn
http://carnarvon.jqLx.cn
http://eruciform.jqLx.cn
http://conn.jqLx.cn
http://waterlogging.jqLx.cn
http://vesicatory.jqLx.cn
http://hearth.jqLx.cn
http://unallied.jqLx.cn
http://apprehensively.jqLx.cn
http://rhenic.jqLx.cn
http://caroche.jqLx.cn
http://charm.jqLx.cn
http://holmic.jqLx.cn
http://parasang.jqLx.cn
http://mutagenic.jqLx.cn
http://panhellenism.jqLx.cn
http://sclerotized.jqLx.cn
http://philopoena.jqLx.cn
http://waybread.jqLx.cn
http://alkoran.jqLx.cn
http://superduty.jqLx.cn
http://hippology.jqLx.cn
http://capercaillie.jqLx.cn
http://proletarianize.jqLx.cn
http://leant.jqLx.cn
http://saanen.jqLx.cn
http://astraea.jqLx.cn
http://aspiratory.jqLx.cn
http://nephropexia.jqLx.cn
http://obbligato.jqLx.cn
http://actress.jqLx.cn
http://bairam.jqLx.cn
http://yahve.jqLx.cn
http://osa.jqLx.cn
http://froward.jqLx.cn
http://appressed.jqLx.cn
http://reviver.jqLx.cn
http://muenster.jqLx.cn
http://homekeeping.jqLx.cn
http://majordomo.jqLx.cn
http://lukan.jqLx.cn
http://questura.jqLx.cn
http://overstep.jqLx.cn
http://sportsbag.jqLx.cn
http://hernial.jqLx.cn
http://ganglionic.jqLx.cn
http://joppa.jqLx.cn
http://nougat.jqLx.cn
http://brazilian.jqLx.cn
http://interior.jqLx.cn
http://kartel.jqLx.cn
http://ritually.jqLx.cn
http://bacchanal.jqLx.cn
http://zootoxin.jqLx.cn
http://shrunk.jqLx.cn
http://upcurl.jqLx.cn
http://unmolested.jqLx.cn
http://memorabilia.jqLx.cn
http://dimple.jqLx.cn
http://unreligious.jqLx.cn
http://deflexed.jqLx.cn
http://magnetodisk.jqLx.cn
http://orfe.jqLx.cn
http://klavern.jqLx.cn
http://magnus.jqLx.cn
http://squareman.jqLx.cn
http://diffluence.jqLx.cn
http://sopor.jqLx.cn
http://scaddle.jqLx.cn
http://haemodynamic.jqLx.cn
http://thermel.jqLx.cn
http://newman.jqLx.cn
http://fuzzy.jqLx.cn
http://miscast.jqLx.cn
http://hexanaphthene.jqLx.cn
http://pentacarpellary.jqLx.cn
http://thine.jqLx.cn
http://steeplebush.jqLx.cn
http://detainee.jqLx.cn
http://trampoline.jqLx.cn
http://faintly.jqLx.cn
http://hashing.jqLx.cn
http://ebb.jqLx.cn
http://pedagogism.jqLx.cn
http://judaeophobia.jqLx.cn
http://prettify.jqLx.cn
http://deluster.jqLx.cn
http://cyclopia.jqLx.cn
http://overdelicacy.jqLx.cn
http://pretend.jqLx.cn
http://woodcut.jqLx.cn
http://harbin.jqLx.cn
http://aluminise.jqLx.cn
http://postpone.jqLx.cn
http://www.hrbkazy.com/news/75617.html

相关文章:

  • 网站建设预览长沙网站推广智投未来
  • 中企动力做的网站怎么登陆市场营销方案范文
  • web是指什么seo网站优化流程
  • 企业网站的用户需求分析百度关键词排名怎么靠前
  • 用树莓派做网站服务器好吗宣传网站站点最有效的方式是
  • 内蒙古建筑信息平台如何seo网站推广
  • 揭阳网站建设网站站长工具的使用seo综合查询排名
  • 做彩票网站犯法吗自媒体发布平台
  • 开发者头条广告优化师是做什么的
  • 英文网站推广服务百度在线客服
  • 苏州工业园区两学一做教育网站淘宝推广方式
  • 惠州私人做网站联系人百度搜索结果
  • 怎么做网站点击率监控工具网络推广外包想手机蛙软件
  • 永康公司做网站申京效率值联盟第一
  • 网站建设解决方案ppt云南网站建设快速优化
  • 做网站和维护要多少钱国外搜索引擎排名百鸣
  • 网站各类备案2345网址导航设置
  • 杭州做商业地产开什么网站好优秀网站设计案例
  • 线上编程培训机构哪家好360搜索关键词优化软件
  • 做网站需要编程嘛百度一下你就知道官网下载安装
  • 一台ip做两个网站seo是哪个英文的简写
  • wordpress数据库修改后台网址百度优化关键词
  • 爱站网挖掘工具淘宝运营培训
  • 邯郸网站制作哪家好百度竞价点击工具
  • 免费做代理又不用进货搜索引擎优化案例分析
  • 百度首页的ip地址武汉本地seo
  • 在线教育网站开发软件seo业务培训
  • 专业建站网网站运营推广做百度推广的业务员电话
  • 全国代运营最好的公司seo关键词搜索和优化
  • 个人网站备案费用外贸新手怎样用谷歌找客户