偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試官:說(shuō)說(shuō) React 性能優(yōu)化的手段有哪些?

開(kāi)發(fā) 前端
在React中如何避免不必要的render中,我們了解到如何避免不必要的render來(lái)應(yīng)付上面的問(wèn)題,主要手段是通過(guò)shouldComponentUpdate、PureComponent、React.memo,這三種形式這里就不再?gòu)?fù)述。

[[414674]]

本文轉(zhuǎn)載自微信公眾號(hào)「JS每日一題」,作者灰灰。轉(zhuǎn)載本文請(qǐng)聯(lián)系JS每日一題公眾號(hào)。

一、是什么

React憑借virtual DOM和diff算法擁有高效的性能,但是某些情況下,性能明顯可以進(jìn)一步提高

在前面文章中,我們了解到類(lèi)組件通過(guò)調(diào)用setState方法, 就會(huì)導(dǎo)致render,父組件一旦發(fā)生render渲染,子組件一定也會(huì)執(zhí)行render渲染

當(dāng)我們想要更新一個(gè)子組件的時(shí)候,如下圖綠色部分:

理想狀態(tài)只調(diào)用該路徑下的組件render:

但是react的默認(rèn)做法是調(diào)用所有組件的render,再對(duì)生成的虛擬DOM進(jìn)行對(duì)比(黃色部分),如不變則不進(jìn)行更新

從上圖可見(jiàn),黃色部分diff算法對(duì)比是明顯的性能浪費(fèi)的情況

二、如何做

在React中如何避免不必要的render中,我們了解到如何避免不必要的render來(lái)應(yīng)付上面的問(wèn)題,主要手段是通過(guò)shouldComponentUpdate、PureComponent、React.memo,這三種形式這里就不再?gòu)?fù)述

除此之外, 常見(jiàn)性能優(yōu)化常見(jiàn)的手段有如下:

  • 避免使用內(nèi)聯(lián)函數(shù)
  • 使用 React Fragments 避免額外標(biāo)記
  • 使用 Immutable
  • 懶加載組件
  • 事件綁定方式
  • 服務(wù)端渲染

避免使用內(nèi)聯(lián)函數(shù)

如果我們使用內(nèi)聯(lián)函數(shù),則每次調(diào)用render函數(shù)時(shí)都會(huì)創(chuàng)建一個(gè)新的函數(shù)實(shí)例,如下:

  1. import React from "react"
  2.  
  3. export default class InlineFunctionComponent extends React.Component { 
  4.   render() { 
  5.     return ( 
  6.       <div> 
  7.         <h1>Welcome Guest</h1> 
  8.         <input type="button" onClick={(e) => { this.setState({inputValue: e.target.value}) }} value="Click For Inline Function" /> 
  9.       </div> 
  10.     ) 
  11.   } 

我們應(yīng)該在組件內(nèi)部創(chuàng)建一個(gè)函數(shù),并將事件綁定到該函數(shù)本身。這樣每次調(diào)用 render 時(shí)就不會(huì)創(chuàng)建單獨(dú)的函數(shù)實(shí)例,如下:

  1. import React from "react"
  2.  
  3. export default class InlineFunctionComponent extends React.Component { 
  4.    
  5.   setNewStateData = (event) => { 
  6.     this.setState({ 
  7.       inputValue: e.target.value 
  8.     }) 
  9.   } 
  10.    
  11.   render() { 
  12.     return ( 
  13.       <div> 
  14.         <h1>Welcome Guest</h1> 
  15.         <input type="button" onClick={this.setNewStateData} value="Click For Inline Function" /> 
  16.       </div> 
  17.     ) 
  18.   } 

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

用戶創(chuàng)建新組件時(shí),每個(gè)組件應(yīng)具有單個(gè)父標(biāo)簽。父級(jí)不能有兩個(gè)標(biāo)簽,所以頂部要有一個(gè)公共標(biāo)簽,所以我們經(jīng)常在組件頂部添加額外標(biāo)簽div

這個(gè)額外標(biāo)簽除了充當(dāng)父標(biāo)簽之外,并沒(méi)有其他作用,這時(shí)候則可以使用fragement

其不會(huì)向組件引入任何額外標(biāo)記,但它可以作為父級(jí)標(biāo)簽的作用,如下所示:

  1. export default class NestedRoutingComponent extends React.Component { 
  2.     render() { 
  3.         return ( 
  4.             <> 
  5.                 <h1>This is the Header Component</h1> 
  6.                 <h2>Welcome To Demo Page</h2> 
  7.             </> 
  8.         ) 
  9.     } 

事件綁定方式

在事件綁定方式中,我們了解到四種事件綁定的方式

從性能方面考慮,在render方法中使用bind和render方法中使用箭頭函數(shù)這兩種形式在每次組件render的時(shí)候都會(huì)生成新的方法實(shí)例,性能欠缺

而constructor中bind事件與定義階段使用箭頭函數(shù)綁定這兩種形式只會(huì)生成一個(gè)方法實(shí)例,性能方面會(huì)有所改善

使用 Immutable

在理解Immutable中,我們了解到使用 Immutable可以給 React 應(yīng)用帶來(lái)性能的優(yōu)化,主要體現(xiàn)在減少渲染的次數(shù)

在做react性能優(yōu)化的時(shí)候,為了避免重復(fù)渲染,我們會(huì)在shouldComponentUpdate()中做對(duì)比,當(dāng)返回true執(zhí)行render方法

Immutable通過(guò)is方法則可以完成對(duì)比,而無(wú)需像一樣通過(guò)深度比較的方式比較

懶加載組件

從工程方面考慮,webpack存在代碼拆分能力,可以為應(yīng)用創(chuàng)建多個(gè)包,并在運(yùn)行時(shí)動(dòng)態(tài)加載,減少初始包的大小

而在react中使用到了Suspense和 lazy組件實(shí)現(xiàn)代碼拆分功能,基本使用如下:

  1. const johanComponent = React.lazy(() => import(/* webpackChunkName: "johanComponent" */ './myAwesome.component')); 
  2.   
  3. export const johanAsyncComponent = props => ( 
  4.   <React.Suspense fallback={<Spinner />}> 
  5.     <johanComponent {...props} /> 
  6.   </React.Suspense> 
  7. ); 

服務(wù)端渲染

采用服務(wù)端渲染端方式,可以使用戶更快的看到渲染完成的頁(yè)面

服務(wù)端渲染,需要起一個(gè)node服務(wù),可以使用express、koa等,調(diào)用react的renderToString方法,將根組件渲染成字符串,再輸出到響應(yīng)中

例如:

  1. import { renderToString } from "react-dom/server"
  2. import MyPage from "./MyPage"
  3. app.get("/", (req, res) => { 
  4.   res.write("<!DOCTYPE html><html><head><title>My Page</title></head><body>"); 
  5.   res.write("<div id='content'>");   
  6.   res.write(renderToString(<MyPage/>)); 
  7.   res.write("</div></body></html>"); 
  8.   res.end(); 
  9. }); 

客戶端使用render方法來(lái)生成HTML

  1. import ReactDOM from 'react-dom'
  2. import MyPage from "./MyPage"
  3. ReactDOM.render(<MyPage />, document.getElementById('app')); 

其他

除此之外,還存在的優(yōu)化手段有組件拆分、合理使用hooks等性能優(yōu)化手段...

三、總結(jié)

通過(guò)上面初步學(xué)習(xí),我們了解到react常見(jiàn)的性能優(yōu)化可以分成三個(gè)層面:

  • 代碼層面
  • 工程層面
  • 框架機(jī)制層面

通過(guò)這三個(gè)層面的優(yōu)化結(jié)合,能夠使基于react項(xiàng)目的性能更上一層樓

參考文獻(xiàn)

https://zhuanlan.zhihu.com/p/108666350

https://segmentfault.com/a/1190000007811296

 

責(zé)任編輯:武曉燕 來(lái)源: JS每日一題
相關(guān)推薦

2025-03-26 01:25:00

MySQL優(yōu)化事務(wù)

2024-03-07 17:21:12

HotSpotJVMHot Code

2021-08-11 08:53:23

Git命令面試

2021-09-30 07:57:13

排序算法面試

2021-05-27 05:37:10

HTTP請(qǐng)求頭瀏覽器

2021-06-29 09:47:34

ReactSetState機(jī)制

2021-06-30 07:19:36

React事件機(jī)制

2024-02-21 07:40:17

JVM內(nèi)存虛擬機(jī)

2021-06-02 09:42:29

Node. js全局對(duì)象

2024-07-26 08:10:10

2021-07-01 07:51:45

React事件綁定

2021-05-08 08:35:33

Webpack前端性能

2021-07-05 11:06:11

組件React通信

2021-09-26 10:57:16

集合操作場(chǎng)景

2025-04-01 00:00:00

項(xiàng)目CRUD單例模式

2021-09-27 06:50:04

樹(shù)非線性數(shù)據(jù)

2021-07-14 08:00:13

reactCss模塊

2021-07-07 08:36:45

React應(yīng)用場(chǎng)景

2021-09-14 07:06:13

React項(xiàng)目TypeScript

2021-06-03 08:14:01

NodeProcessJavaScript
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)