欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React組件性能提升實(shí)現(xiàn)方法詳解

 更新時(shí)間:2023年03月06日 10:02:24   作者:懶得跟豬打架  
這篇文章主要介紹了React組件性能最佳優(yōu)化實(shí)踐分享,React組件性能優(yōu)化的核心是減少渲染真實(shí)DOM節(jié)點(diǎn)的頻率,減少Virtual?DOM比對(duì)的頻率,更多相關(guān)內(nèi)容需要的朋友可以參考一下

react組件的性能優(yōu)化的核心是減少渲染真實(shí)DOM節(jié)點(diǎn)的頻率,減少Virtual DOM比對(duì)的頻率。

組件卸載前執(zhí)行清理操作

在組件中為window 注冊(cè)的全局事件,以及定時(shí)器,在組件卸載前要清理掉。防止組件卸載后繼續(xù)執(zhí)行影響應(yīng)用性能。

import React from 'react'
import { useEffect } from 'react'
import { observer } from 'mobx-react-lite'
function TestAdvance () {
  useEffect(() => {
    let timer = setInterval(() => {
      console.log('定時(shí)器被觸發(fā)了')
    }, 1000)
    // 返回一個(gè)卸載時(shí)會(huì)被觸發(fā)的函數(shù)來對(duì)timer進(jìn)行清理
    return () => clearInterval(timer)
  }, [])
  return <div>Test</div>
}
export default observer(TestAdvance)

通過純組件提升組件性能(類組件)

什么是純組件(PureComponent)

純組件會(huì)對(duì)組件輸入的數(shù)據(jù)進(jìn)行淺層比較,如果當(dāng)前輸入數(shù)據(jù)和上次輸入數(shù)據(jù)相同,組件不會(huì)重新渲染。

什么是淺層比較

  • 比較引用數(shù)據(jù)類型在內(nèi)存中的引用地址是否相同;
  • 比較基本數(shù)據(jù)類型的值是否相同。

如何實(shí)現(xiàn)純組件

  • 類組件集成 PureComponent 類
  • 函數(shù)組件使用 memo 方法
import React from 'react'
class App extends React.Component {
  constructor () {
    super()
    this.state = {
      person: { name: '張三', age: 20, job: 'waiter' }
    }
  }
  updateName () {
    setInterval(() => {
      this.setState({ person: { ...this.state.person, name: '張三' } })
    }, 3000)
  }
  componentDidMount () {
    console.log('componentDidMount')
    this.updateName()
  }
  render () {
    return (
      <div>
        <RegularComponent name={this.state.person.name} />
        <PureComponent name={this.state.person.name} />
      </div>
    )
  }
}
class RegularComponent extends React.Component {
  render () {
    console.log('RegularComponent')
    return <div>{this.props.name}</div>
  }
}
class PureComponent extends React.PureComponent {
  render () {
    console.log('PureComponent')
    return <div>{this.props.name}</div>
  }
}
export default App

淺層比較和深度diff的性能對(duì)比,為什么需要先進(jìn)行淺層比較,而不直接進(jìn)行diff比較呢。

和進(jìn)行diff 比較相比,淺層比較將消耗更少的性能。diff 操作會(huì)重新遍歷整棵 Virtual DOM樹,而淺層比較只操作當(dāng)前組件的 state 和 props。

可以看到PureComponent 當(dāng)狀態(tài)值沒有改變時(shí)是不會(huì)被重新渲染的。

通過shouldComponentUpdate生命周期函數(shù)提升組件性能

shouldComponentUpdate是類組件當(dāng)中的一個(gè)生命周期函數(shù),它允許我們?cè)谶@個(gè)方法當(dāng)中通過返回true 或者 false,來決定是否要重新渲染組件。

純組件只能進(jìn)行淺層比較,要進(jìn)行深層比較的話,需要使用到shouldComponentUpdate,它用于編寫自定義比較邏輯。

函數(shù)的第一個(gè)參數(shù)時(shí)nextProps, 第二個(gè)參數(shù)是nextState。

在內(nèi)存中當(dāng)中有兩個(gè)對(duì)象,即使這兩個(gè)對(duì)象的長(zhǎng)得一摸一樣,實(shí)際上它們有不同的引用地址,這個(gè)時(shí)候再怎么比較他們都不相同。

在我們的自定義邏輯中,如果返回true,則需要重新渲染組件;如果返回false,則不需要重現(xiàn)渲染組件了。

import React from 'react'
class App extends React.Component {
  constructor () {
    super()
    this.state = {
      person: { name: '張三', age: 20, job: 'waiter' }
    }
  }
  updateName () {
    setInterval(() => {
      this.setState({ person: { ...this.state.person, job: 'Writer' } })
    }, 3000)
  }
  componentDidMount () {
    console.log('componentDidMount')
    this.updateName()
  }
  /* shouldComponentUpdate (nextProps, nextState) {
    if (
      nextState.person.age !== this.state.person.age ||
      nextState.person.name !== this.state.person.name
    ) {
      return true
    } else {
      return false
    }
  } */
  render () {
    return (
      <div>
        <RegularComponent name={this.state.person.name} />
        <PureComponent name={this.state.person.name} />
      </div>
    )
  }
}
class RegularComponent extends React.Component {
  render () {
    console.log('RegularComponent')
    return <div>{this.props.name}</div>
  }
  shouldComponentUpdate (nextProps, nextState) {
    console.log(this.props, nextProps)
    if (nextProps.name !== this.props.name) {
      return true
    } else {
      return false
    }
  }
}
class PureComponent extends React.PureComponent {
  render () {
    console.log('PureComponent')
    return <div>{this.props.name}</div>
  }
}
export default App

函數(shù)組件使用memo 減少渲染次數(shù)

memo的基本使用

將函數(shù)組件變?yōu)榧兘M件,將當(dāng)前props和上一次的props進(jìn)行淺層比較,如果相同就阻止組件重新渲染。

// 未使用memo方法包裹組件
import React, { useEffect, useState } from 'react'
function App () {
  const [name] = useState('張三')
  const [index, setIndex] = useState(0)
  useEffect(() => {
    let timer = setInterval(() => {
      setIndex(prev => prev + 1)
    }, 1000)
    return () => {
      clearInterval(timer)
    }
  }, [index])
  return (
    <div>
      {index}
      <ShowName name={name} />
    </div>
  )
}
function ShowName ({ name }) {
  console.log('render...')
  return <div>{name}</div>
}
export default App

使用memo封裝子組件,讓子組件減少不必要的渲染。

// 使用memo封裝子組件
import React, { memo, useEffect, useState } from 'react'
function App () {
  const [name] = useState('張三')
  const [index, setIndex] = useState(0)
  useEffect(() => {
    let timer = setInterval(() => {
      setIndex(prev => prev + 1)
    }, 1000)
    return () => {
      clearInterval(timer)
    }
  }, [index])
  return (
    <div>
      {index}
      <ShowName name={name} />
    </div>
  )
}
const ShowName = memo(function ({ name }) {
  console.log('render...')
  return <div>{name}</div>
})
export default App

可以看到僅初次渲染時(shí),渲染了一次。

為memo 方法傳遞自定義比較邏輯

在memo方法內(nèi)部,其實(shí)也是進(jìn)行的淺層比較。這個(gè)淺層比較對(duì)于引用數(shù)據(jù)類型來說,比較的是數(shù)據(jù)的引用地址。所以如果遇到引用數(shù)據(jù)類型的話,我們需要去傳遞自定義比較邏輯。

memo方法是可以接收第二個(gè)參數(shù)的,第二個(gè)參數(shù)是一個(gè)函數(shù),我們可以通過這個(gè)函數(shù)參數(shù)來編寫我們自定義比較邏輯。該函數(shù)參數(shù)接收兩個(gè)參數(shù),分別是prevProps和nextProps。

與shouldComponentUpdate的返回值邏輯相反,返回true,則不重新渲染;返回false的話則需要重新渲染。如果想讓這個(gè)組件重新渲染的話就返回false,否則返回true。

// 給memo傳遞第二個(gè)參數(shù),自定義比較邏輯
import React, { memo, useEffect, useState } from 'react'
function App () {
  const [person, setPerson] = useState({ name: '張三', age: 20, job: 'waiter' })
  const [index, setIndex] = useState(0)
  useEffect(() => {
    let timer = setInterval(() => {
      setIndex(prev => prev + 1)
      setPerson({ ...person, job: 'chef' })
    }, 1000)
    return () => {
      clearInterval(timer)
    }
  }, [index, person])
  return (
    <div>
      {index}
      <ShowName person={person} />
    </div>
  )
}
function compare (prevProps, nextProps) {
  if (
    prevProps.person.name !== nextProps.person.name ||
    prevProps.person.age !== nextProps.person.age
  ) {
    return false
  }
  return true
}
const ShowName = memo(function ({ person }) {
  console.log('render...')
  return (
    <div>
      {person.name} {person.age}
    </div>
  )
}, compare)
export default App

通過組件懶加載提供應(yīng)用性能

使用組件懶加載,可以減少bundle 文件大小,加快組件呈遞速度。

路由組件懶加載

import React, { lazy, Suspense } from 'react'
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'
// import Home from './pages/Home'
// import List from './pages/List'
// import NotFound from './pages/NotFound'
const Home = lazy(() => import(/* webpackChunkName: "Home" */ './pages/Home'))
const List = lazy(() => import(/* webpackChunkName: "List" */ './pages/List'))
const NotFound = lazy(() => import('./pages/NotFound'))
function App () {
  return (
    <BrowserRouter>
      <Link to='/'>首頁(yè) </Link>
      <Link to='/list'>列表頁(yè)</Link>
      <Suspense fallback={<div>loading...</div>}>
        <Routes>
          <Route path='/' element={<Home />} />
          <Route path='/list' element={<List />} errorElement={<NotFound />} />
        </Routes>
      </Suspense>
    </BrowserRouter>
  )
}
export default App

可以看到,List頁(yè)面chunk 只有在頁(yè)面被加載渲染時(shí)才被被請(qǐng)求下載。

根據(jù)條件進(jìn)行組件懶加載

適用于組件不會(huì)隨條件頻繁切換。

import React, { lazy } from 'react'
import { Suspense } from 'react'
function Test () {
  let LazyComponent = null
  if (false) {
    LazyComponent = lazy(() =>
      import(/* webpackChunkName: "Home-Test" */ './Home')
    )
  } else {
    LazyComponent = lazy(() =>
      import(/* webpackChunkName: "List-Test" */ './List')
    )
  }
  return (
    <Suspense fallback={<div>Test loading...</div>}>
      <LazyComponent />
    </Suspense>
  )
}
export default Test

通過使用占位符標(biāo)記提升React組件的渲染性能

使用Fragment 避免額外標(biāo)記

React組件中返回的jsx 如果有多個(gè)同級(jí)元素,多個(gè)同級(jí)元素必須要有一個(gè)共同的父級(jí)。

<div>
...
</div> 
// 上面會(huì)多出一個(gè)無意義標(biāo)記
// 應(yīng)該改為 
<fragment>
...
</fragment>
// 或者寫成下面這樣也是可以的
<>
...
</>

為了滿足上面的條件,我們通常都會(huì)在最外層添加一個(gè)div,但是這樣的話就會(huì)多出一個(gè)無意義的標(biāo)記。如果每個(gè)組件都多出這樣的一個(gè)無意義標(biāo)記的話,瀏覽器渲染引擎的負(fù)擔(dān)就會(huì)加劇。

為了解決這個(gè)問題,react推出了fragment占位符標(biāo)記。使用占位符標(biāo)記,既滿足了擁有共同的父級(jí)的要求,又不會(huì)多出額外的無意義標(biāo)記。

另外,fragment標(biāo)記對(duì)也可以簡(jiǎn)寫成 :<></>

通過避免使用內(nèi)聯(lián)函數(shù)提升組件性能

因?yàn)樵谑褂脙?nèi)聯(lián)函數(shù)后,render 方法每次進(jìn)行時(shí)都會(huì)創(chuàng)建該函數(shù)的新實(shí)例,導(dǎo)致 React 在進(jìn)行Virtual DOM比對(duì)時(shí),新舊函數(shù)比對(duì)不相等,導(dǎo)致總是為元素綁定新的函數(shù)實(shí)例,而舊的函數(shù)實(shí)例又要交給垃圾回收器處理。

正確的做法是:在組件中單獨(dú)定義函數(shù),將函數(shù)綁定給事件。

render(){return(<input onChange={e => this.setState({inputValue: e.target.value})} />)}
// 在類組件中,應(yīng)該采用下面的方式來改寫從而避免該元素被重新渲染
setInputvalue = e => {
    this.setState({inputValue: e.target.value})
}
render(){
    return (<input onChange={this.setInputValue} />)
}

這樣一來,無論render方法被重新執(zhí)行多少次,類的屬性是不會(huì)發(fā)生變化的,所以在這個(gè)地方即使render方法被重新執(zhí)行n次,那它每次都不會(huì)產(chǎn)生新的函數(shù)實(shí)例,所以它每次不會(huì)給onChange去添加新的函數(shù)。

在構(gòu)造函數(shù)中進(jìn)行this指向的更正

在類組件中如果使用fn(){}這種方式定義函數(shù),函數(shù)this默認(rèn)指向 undefined 。也就是說函數(shù)內(nèi)部的 this 指向需要被更正。

可以在構(gòu)造函數(shù)中對(duì)函數(shù)的this 進(jìn)行更正,也可以在行內(nèi)進(jìn)行更正。兩者看起來沒有太大的區(qū)別,但是對(duì)性能的影響是不同的。

對(duì)于行內(nèi)更正來說,每一次render方法在執(zhí)行的時(shí)候它都會(huì)調(diào)用bind方法生成新的函數(shù)實(shí)例,也就是上邊提到的內(nèi)聯(lián)函數(shù)對(duì)性能的影響是一樣的。

因此比較推薦的是在構(gòu)造函數(shù)當(dāng)中去更正this的指向。因?yàn)闃?gòu)造函數(shù)只執(zhí)行一次,也就是函數(shù)的this 指向只更正一次,效率較高。

import React, { Component } from 'react'
export default class index extends Component {
  constructor () {
    super()
    // 方法一:(推薦使用)
    // 構(gòu)造函數(shù)只執(zhí)行一次,所以函數(shù)this 指向更正的代碼也只執(zhí)行一次。
    this.handleClick = this.handleClick.bind(this)
  }
  handleClick () {
    console.log(this)
  }
  handleClick2= () {
    console.log(this)
  }
  render () {
    // 方式二:跟內(nèi)聯(lián)函數(shù)類似,不推薦,應(yīng)避免使用
    // 問題:render 放啊每次執(zhí)行時(shí)都會(huì)調(diào)用bind方法生成新的函數(shù)實(shí)例。
    return <button onClick={this.handleClick.bind(this)}>按鈕</button>
  }
}

類組件中的箭頭函數(shù)

在類組件中使用箭頭函數(shù)不會(huì)存在this 指向問題。因?yàn)榧^函數(shù)本身并不綁定this.

handleClick2= ()=> console.log(this)

箭頭函數(shù)在this 指向問題上是比較占優(yōu)勢(shì)的,但是同時(shí)也有不利的一面。

當(dāng)使用箭頭函數(shù)時(shí),該函數(shù)被添加為類的實(shí)例對(duì)象屬性,而不是原型對(duì)象屬性。如果組件被多次重用,每個(gè)組件實(shí)例對(duì)象中都會(huì)有一個(gè)相同的函數(shù)實(shí)例,降低了函數(shù)實(shí)例的可重用性,造成了資源浪費(fèi)。

綜上所述, 更正函數(shù)內(nèi)部this 指向的最佳做法是: 在構(gòu)造函數(shù)中使用 bind 方法進(jìn)行綁定。 10. 避免使用內(nèi)聯(lián)樣式屬性以提升組件性能

當(dāng)使用內(nèi)聯(lián)style 為元素添加樣式時(shí),內(nèi)聯(lián)style 會(huì)被編譯成 JavaScript 代碼,通過JavaScript代碼將樣式規(guī)則映射到元素的身上,瀏覽器就會(huì)花費(fèi)更多的時(shí)間執(zhí)行腳本和渲染UI,從而增加了組件的渲染時(shí)間。

// 例如:這段代碼的樣式會(huì)涉及到腳本的執(zhí)行,效率低,資源開銷大
<div style={{background: 'red'}}>Style in line</div>// 例如:這段代碼的樣式會(huì)涉及到腳本的執(zhí)行,效率低,資源開銷大
<div style={{background: 'red'}}>Style in line</div>

更好的辦法是:

將CSS 文件導(dǎo)入樣式組件,能通過CSS直接做的事情就不要通過JavaScript去做。因?yàn)镴avaScript操作DOM非常慢。而CSS默認(rèn)開啟了GPU的渲染加速,更加高效。

優(yōu)化條件渲染以提升組件性能

頻繁的掛載和卸載組件,是一項(xiàng)耗性能的操作。為了確保應(yīng)用程序的性能,應(yīng)該減少組件掛載和卸載的次數(shù)。

在react中,我們經(jīng)常會(huì)根據(jù)條件渲染不同的組件,條件渲染是一項(xiàng)必做的優(yōu)化操作。

import React from 'react'
import Home from './Home'
import List from './List'
import Test from './Test'
function App () {
  if (true) {
    return (
      <>
        <Test />
        <Home />
        <List />
      </>
    )
  } else {
    return (
      <>
        <Home />
        <List />
      </>
    )
  }
}
export default App

在上面的代碼中,顯然這種大范圍的條件渲染不太合理,存在優(yōu)化的空間,整個(gè)頁(yè)面隨著判斷條件改變而變化的部分只有Test 組件,因此,可以僅對(duì)Test組件進(jìn)行條件渲染判斷,從而減少不必要的組件卸載和掛載的次數(shù)。

import React from 'react'
import Home from './Home'
import List from './List'
import Test from './Test'
function App () {
  return (
    <>
      {true && <Test />}
      <Home />
      <List />
    </>
  )
}
export default App

避免重復(fù)的無限渲染

當(dāng)應(yīng)用程序狀態(tài)發(fā)生更改時(shí),react 就會(huì)調(diào)用render 方法,如果在render 方法中繼續(xù)更改應(yīng)用程序狀態(tài),就會(huì)發(fā)生render 方法遞歸調(diào)用導(dǎo)致應(yīng)用報(bào)錯(cuò)。

import React, { Component } from 'react'
export default class index extends Component {
  constructor () {
    super()
    this.state = { name: '張三' }
    // 方法一:(推薦使用)
    // 構(gòu)造函數(shù)只執(zhí)行一次,所以函數(shù)this 指向更正的代碼也只執(zhí)行一次。
    this.handleClick = this.handleClick.bind(this)
  }
  handleClick () {
    console.log(this)
  }
  render () {
    this.setState({ name: '李四' })
    // 方式二:跟內(nèi)聯(lián)函數(shù)類似,不推薦,應(yīng)避免使用
    // 問題:render 放啊每次執(zhí)行時(shí)都會(huì)調(diào)用bind方法生成新的函數(shù)實(shí)例。
    return <button onClick={this.handleClick.bind(this)}>按鈕</button>
  }
}

與其他生命周期函數(shù)不同,render方法應(yīng)該被作為純函數(shù)。

這意味著,在render方法中不要做以下的事情:

  • 不要調(diào)用setState方法;
  • 不要使用其他手段查詢更改原生DOM元素;
  • 以及不要做其他更改應(yīng)用程序的任何操作。

render 方法對(duì)的執(zhí)行要根據(jù)狀態(tài)的改變,這樣可以保持組件的行為和渲染方式一致。

所以,在react當(dāng)中,不要在render方法當(dāng)中,不要在componentWillUpdate這個(gè)生命周期函數(shù)當(dāng)中,不要在componentDidUpdated這個(gè)生命周期函數(shù)當(dāng)中繼續(xù)調(diào)用setState方法去更新狀態(tài)。否則將導(dǎo)致重復(fù)的無限渲染,應(yīng)用程序崩潰。

為應(yīng)用程序創(chuàng)建錯(cuò)誤邊界

默認(rèn)情況下,組件渲染錯(cuò)誤會(huì)導(dǎo)致整個(gè)應(yīng)用程序的中斷,創(chuàng)建錯(cuò)誤邊界可確保在特定組件發(fā)生錯(cuò)誤時(shí)應(yīng)用程序不會(huì)中斷。從而增加應(yīng)用程序的健壯性(魯棒性)。

錯(cuò)誤邊界是一個(gè)React組件,可以捕獲子級(jí)組件在渲染時(shí)發(fā)生的錯(cuò)誤,當(dāng)錯(cuò)誤發(fā)生時(shí),可以將錯(cuò)誤記錄下來,可以顯示備用UI界面。

錯(cuò)誤邊界涉及兩個(gè)生命周期函數(shù),分別為:getDerivedStateFromError 和 componentDidCatch.

getDerivedStateFromError: 是一個(gè)靜態(tài)方法,方法中返回一個(gè)對(duì)象,該對(duì)象會(huì)和state 對(duì)象進(jìn)行合并,用于更改應(yīng)用程序的狀態(tài),從而給我們提供顯示備用UI界面的機(jī)會(huì)。

componentDidCatch:該方法用于記錄應(yīng)用程序的錯(cuò)誤信息,該方法的參數(shù)就是錯(cuò)誤對(duì)象。

import React, { Component } from 'react'
import ErrorTrigger from '../components/ErrorTrigger'
export default class ErrorBoundaries extends Component {
  constructor () {
    super()
    this.state = {
      hasError: false
    }
  }
  componentDidCatch (error) {
    // 可以將程序錯(cuò)誤信息記錄到遠(yuǎn)端服務(wù)器
    console.log('componentDidCatch')
  }
  static getDerivedStateFromError () {
    console.log('getDerivedStateFromError')
    return {
      // 該返回對(duì)象會(huì)和state 對(duì)象進(jìn)行合并
      hasError: true
    }
  }
  render () {
    if (this.state.hasError) {
      return <>我是備用UI界面</>
    }
    return (
      <>
        <ErrorTrigger />
      </>
    )
  }
}
import React, { Component } from 'react'
export class ErrorTrigger extends Component {
  render () {
    throw new Error('錯(cuò)誤邊界內(nèi)發(fā)生錯(cuò)誤了')
    return <div>ErrorTrigger</div>
  }
}
export default ErrorTrigger

注意??:錯(cuò)誤邊界不能捕獲異步錯(cuò)誤,例如點(diǎn)擊按鈕時(shí)發(fā)生的錯(cuò)誤。

避免數(shù)據(jù)結(jié)構(gòu)突變

組件中的props和state 的數(shù)據(jù)結(jié)構(gòu)應(yīng)該保持一致,數(shù)據(jù)結(jié)構(gòu)突變會(huì)導(dǎo)致輸出不一致。

import React, { Component } from 'react'
export default class App extends Component {
  constructor () {
    super()
    this.state = {
      person: {
        name: '張三',
        age: 20,
        job: 'waiter'
      }
    }
  }
  render () {
    const { name, age, job } = this.state.person
    return (
      <>
        <p>
          {name} {age} {job}
        </p>
        <button
          onClick={() =>
            this.setState({
              ...this.state,
              person: {
                age: 30
              }
            })
          }
        >
          更新信息
        </button>
      </>
    )
  }
}

點(diǎn)擊更新信息按鈕前

點(diǎn)擊更新信息按鈕后

這是因?yàn)閿?shù)據(jù)狀態(tài)在發(fā)生更改時(shí),發(fā)生了數(shù)據(jù)結(jié)構(gòu)突變導(dǎo)致的數(shù)據(jù)丟失。

使用setState更改狀態(tài)代碼應(yīng)該修改為:

this.setState({
  ...this.state,
  // 這里的person 數(shù)據(jù)結(jié)構(gòu)應(yīng)該和原來的保持一致,避免數(shù)據(jù)丟失
  // person: {
  //   age: 30
  // }
  person: {
    ...this.state.person,
    age: 30
  }
})

修改更新數(shù)據(jù)保持結(jié)構(gòu)一致的代碼后點(diǎn)擊更新信息按鈕后的顯示

優(yōu)化依賴項(xiàng)大小

在程序應(yīng)用開發(fā)中,常常會(huì)依賴第三方包,但我們不想引用包中所有的代碼,我們只想用到哪些代碼就包含哪些代碼。

此時(shí),可以使用插件對(duì)依賴項(xiàng)進(jìn)行優(yōu)化,優(yōu)化資源。

拿lodash舉例:

應(yīng)用基于create-react-app 腳手架創(chuàng)建:

下載依賴

npm install react-app-rewired customize-cra lodash babel-plugin-lodash

react-app-rewired: 覆蓋create-react-app的默認(rèn)配置

module.exports = function(oldConfig){
  return newConfig
}
// 參數(shù)中的oldConfig 就是默認(rèn)的webpack config

customize-cra: 導(dǎo)出了一些輔助方法,可以讓以上寫法更加簡(jiǎn)潔。

const {override, useBabelRc} from 'customize-cra'
module.exports = override(
(oldConfig) => newConfig,
(oldConfig) => newConfig
)
// override 可以接收多個(gè)參數(shù),每個(gè)參數(shù)都是一個(gè)配置函數(shù),函數(shù)接收oldConfig,返回 newConfig
// useBabelRc 允許使用 .babelrc 文件進(jìn)行 babel 配置

babel-plugin-lodash: 對(duì)應(yīng)用中的lodash 進(jìn)行精簡(jiǎn)

在項(xiàng)目根目錄下新建 config-overrides.js 并加入配置代碼

const {override, useBabelRc} from 'customize-cra'
module.exports = override(useBabelRc())
// 這里使用 .babelrc 文件進(jìn)行 babel 配置

修改package.json 中的文件構(gòu)建命令

把原來命令中的 react-scripts 改為 react-app-rewired

  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject" 
  },

創(chuàng)建 .babelrc 文件并加入配置

{
    "plugins":["lodash"]
}

命令打包生成的生產(chǎn)環(huán)境下的三種js文件

main.[hash].chunk.js 主應(yīng)用程序代碼,App.js 等

1.[hash].chunk.js 第三方依賴包的代碼,包含在node_modules中導(dǎo)入的模塊

runtime~main.[hash].js webpack的運(yùn)行時(shí)代碼

優(yōu)化前后結(jié)果比對(duì):

到此這篇關(guān)于React組件性能提升實(shí)現(xiàn)方法詳解的文章就介紹到這了,更多相關(guān)React組件性能優(yōu)化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于React Native使用axios進(jìn)行網(wǎng)絡(luò)請(qǐng)求的方法

    關(guān)于React Native使用axios進(jìn)行網(wǎng)絡(luò)請(qǐng)求的方法

    axios是一個(gè)基于Promise的Http網(wǎng)絡(luò)庫(kù),可運(yùn)行在瀏覽器端和Node.js中,Vue應(yīng)用的網(wǎng)絡(luò)請(qǐng)求基本都是使用它完成的。這篇文章主要介紹了React Native使用axios進(jìn)行網(wǎng)絡(luò)請(qǐng)求,需要的朋友可以參考下
    2021-08-08
  • React自定義hooks同步獲取useState的最新狀態(tài)值方式

    React自定義hooks同步獲取useState的最新狀態(tài)值方式

    這篇文章主要介紹了React自定義hooks同步獲取useState的最新狀態(tài)值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • react?hooks?d3實(shí)現(xiàn)企查查股權(quán)穿透圖結(jié)構(gòu)圖效果詳解

    react?hooks?d3實(shí)現(xiàn)企查查股權(quán)穿透圖結(jié)構(gòu)圖效果詳解

    這篇文章主要為大家介紹了react?hooks?d3實(shí)現(xiàn)企查查股權(quán)穿透圖結(jié)構(gòu)圖效果詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • React中hook函數(shù)與useState及useEffect的使用

    React中hook函數(shù)與useState及useEffect的使用

    這篇文章主要介紹了React中hook函數(shù)與useState及useEffect的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-10-10
  • react函數(shù)組件類組件區(qū)別示例詳解

    react函數(shù)組件類組件區(qū)別示例詳解

    這篇文章主要為大家介紹了react函數(shù)組件類組件區(qū)別示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 詳解React中key的作用

    詳解React中key的作用

    這篇文章主要介紹了React中key的作用,幫助大家更好的理解和學(xué)習(xí)使用React,感興趣的朋友可以了解下
    2021-04-04
  • create-react-app開發(fā)常用配置教程

    create-react-app開發(fā)常用配置教程

    這篇文章主要為大家介紹了create-react-app開發(fā)常用配置教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • 關(guān)于React16.0的componentDidCatch方法解讀

    關(guān)于React16.0的componentDidCatch方法解讀

    這篇文章主要介紹了關(guān)于React16.0的componentDidCatch方法解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • React中的useEffect useLayoutEffect到底怎么用

    React中的useEffect useLayoutEffect到底怎么用

    這篇文章主要介紹了React中的useEffect useLayoutEffect具體使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-02-02
  • React中memo useCallback useMemo方法作用及使用場(chǎng)景

    React中memo useCallback useMemo方法作用及使用場(chǎng)景

    這篇文章主要為大家介紹了React中三個(gè)hooks方法memo useCallback useMemo的作用及使用場(chǎng)景示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2023-03-03

最新評(píng)論