中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

想象力做網(wǎng)站百度官方推廣平臺(tái)

想象力做網(wǎng)站,百度官方推廣平臺(tái),重慶市建設(shè)銀行網(wǎng)站首頁(yè),建筑工程網(wǎng)格化監(jiān)管本文主要講解實(shí)戰(zhàn)項(xiàng)目中React性能優(yōu)化的方法,主要分為三個(gè)大的方面:減少不必要的組件更新、組件優(yōu)化以及tree-shaking,共11個(gè)方法 一、減少不必要組件更新 以下是一些可以避免在 React 提交階段進(jìn)行不必要重新渲染的方法: 1、使…

本文主要講解實(shí)戰(zhàn)項(xiàng)目中React性能優(yōu)化的方法,主要分為三個(gè)大的方面:減少不必要的組件更新、組件優(yōu)化以及tree-shaking,共11個(gè)方法

一、減少不必要組件更新

以下是一些可以避免在 React 提交階段進(jìn)行不必要重新渲染的方法:

1、使用 React.memo(對(duì)于函數(shù)組件)和 PureComponent(對(duì)于類組件)

  1. React.memo
    React.memo 是一個(gè)高階組件,用于包裝函數(shù)組件。它通過(guò)對(duì)組件的 props 進(jìn)行淺層比較來(lái)決定是否重新渲染組件。
    示例:

    import React from 'react';const MyComponent = React.memo(({ data }) => {// 組件渲染邏輯return <div>{data}</div>;
    });
    

    當(dāng) data 的引用沒(méi)有發(fā)生變化時(shí),組件將不會(huì)重新渲染。

  2. PureComponent(對(duì)于類組件):
    PureComponent 會(huì)對(duì) propsstate 進(jìn)行淺層比較。如果它們沒(méi)有變化,組件將不會(huì)重新渲染。
    示例:
    以下是一個(gè)在類組件中使用 PureComponent 的示例,包括數(shù)據(jù)傳遞和更新:

import React, { PureComponent } from 'react';class MyComponent extends PureComponent {// 構(gòu)造函數(shù),初始化狀態(tài)constructor(props) {super(props);this.state = {count: 0,name: 'Initial Name',};}// 處理點(diǎn)擊事件,更新?tīng)顟B(tài)handleClick = () => {// 示例 1:更新數(shù)字狀態(tài)this.setState({ count: this.state.count + 1 });// 示例 2:更新字符串狀態(tài)(如果 name 是從父組件傳遞的 props 且未變化,不會(huì)觸發(fā)重新渲染)// 假設(shè) name 是從父組件傳遞的 props,以下更新不會(huì)觸發(fā)重新渲染(如果 name 未變化)// this.setState({ name: this.props.name });};render() {return (<div><p>Count: {this.state.count}</p><p>Name: {this.state.name}</p><button onClick={this.handleClick}>Increment Count</button></div>);}
}// 父組件
class ParentComponent extends React.Component {constructor(props) {super(props);this.state = {name: 'Parent Name',};}handleNameChange = () => {this.setState({ name: 'Updated Name' });};render() {return (<div><MyComponent name={this.state.name} /><button onClick={this.handleNameChange}>Change Name</button></div>);}
}export default ParentComponent;

在這個(gè)例子中:

  • MyComponent 是一個(gè)繼承自 PureComponent 的類組件。它有一個(gè) count 狀態(tài)用于數(shù)字的遞增展示,還有一個(gè) name 狀態(tài)(也可以是從父組件傳遞的 props)用于展示字符串。

  • render 方法中,展示了 countname 的值,并有一個(gè)按鈕用于觸發(fā) count 的遞增。

  • ParentComponent 是父組件,它有一個(gè) name 狀態(tài),并將其傳遞給 MyComponent。還有一個(gè)按鈕用于更改 name 的狀態(tài)。

PureComponent 會(huì)對(duì) propsstate 進(jìn)行淺層比較。如果 propsstate 的引用沒(méi)有變化,組件將不會(huì)重新渲染。在上面的例子中,如果 MyComponent 接收到的 props.name 沒(méi)有變化,并且 state 中的 count 沒(méi)有更新,MyComponent 就不會(huì)重新渲染。

注意事項(xiàng):

  • PureComponent 的淺層比較對(duì)于基本數(shù)據(jù)類型(如數(shù)字、字符串、布爾值)是有效的,但對(duì)于復(fù)雜數(shù)據(jù)類型(如對(duì)象、數(shù)組),它只會(huì)比較引用。如果對(duì)象或數(shù)組的內(nèi)容發(fā)生變化,但引用不變,PureComponent 可能不會(huì)檢測(cè)到變化。在這種情況下,可以使用 immutable.js 或手動(dòng)在 shouldComponentUpdate 中進(jìn)行深層比較。
  • 如果組件的 propsstate 變化頻繁且計(jì)算成本不高,或者需要進(jìn)行深層比較,可能不需要使用 PureComponent。

2、使用 useCallbackuseMemo

  1. useCallback
    useCallback 用于記憶函數(shù),確保傳遞給子組件的函數(shù)在依賴項(xiàng)不變的情況下不會(huì)重新創(chuàng)建。
    示例:

    import React, { useState, useCallback } from 'react';function ParentComponent() {const [count, setCount] = useState(0);const handleClick = useCallback(() => {// 處理點(diǎn)擊的邏輯}, [count]); // 僅當(dāng) count 變化時(shí)重新創(chuàng)建函數(shù)return (<div><ChildComponent onClick={handleClick} /></div>);
    }
    
  2. useMemo
    useMemo 用于記憶計(jì)算結(jié)果,避免在每次渲染時(shí)都進(jìn)行昂貴的計(jì)算。
    示例:

    import React, { useState, useMemo } from 'react';function MyComponent() {const [data, setData] = useState([]);const computedValue = useMemo(() => {// 進(jìn)行昂貴的計(jì)算return data.map((item) => item * 2);}, [data]);return <div>{computedValue}</div>;
    }
    

3、優(yōu)化 shouldComponentUpdate(對(duì)于類組件)

在類組件中,可以重寫 shouldComponentUpdate 方法來(lái)進(jìn)行更細(xì)粒度的控制。

import React from 'react';class MyComponent extends React.Component {shouldComponentUpdate(nextProps, nextState) {// 進(jìn)行 props 和 state 的比較,決定是否更新return (nextProps.someValue!== this.props.someValue ||nextState.someState!== this.state.someState);}render() {return <div>{/*... */}</div>;}
}

4、避免在渲染階段進(jìn)行副作用操作

副作用操作(如網(wǎng)絡(luò)請(qǐng)求、訂閱事件等)應(yīng)該在 useEffect 中進(jìn)行,而不是在組件的渲染函數(shù)中。這樣可以確保渲染函數(shù)的純粹性,減少不必要的重新渲染觸發(fā)。

import React, { useState, useEffect } from 'react';function MyComponent() {const [data, setData] = useState(null);useEffect(() => {// 進(jìn)行網(wǎng)絡(luò)請(qǐng)求獲取數(shù)據(jù)fetchData().then((result) => setData(result));}, []); // 空依賴數(shù)組確保只在組件掛載時(shí)執(zhí)行一次return <div>{data? data : 'Loading...'}</div>;
}

5、正確設(shè)置 key 屬性(對(duì)于列表渲染)

  • 在渲染列表時(shí),為每個(gè)列表項(xiàng)設(shè)置唯一的 key 屬性。這有助于 React 更高效地識(shí)別和更新列表項(xiàng)。
    import React from 'react';function ListComponent({ items }) {return (<ul>{items.map((item) => (<li key={item.id}>{item.name}</li>))}</ul>);
    }
    

二、組件優(yōu)化

1、useIntersectionObserver

在 React 項(xiàng)目中使用 TypeScript 和 useIntersectionObserver 實(shí)現(xiàn)虛擬滾動(dòng)懶加載的示例代碼:

import React, { useEffect, useRef } from 'react';function LazyLoadComponent() {const imageRefs = useRef<HTMLDivElement[]>([]);const observerRef = useRef<IntersectionObserver | null>(null);useEffect(() => {const options = {root: null,rootMargin: '0px',threshold: 0.1,};observerRef.current = new IntersectionObserver((entries) => {entries.forEach((entry) => {if (entry.isIntersecting) {// 這里可以進(jìn)行實(shí)際的圖片加載或其他數(shù)據(jù)加載邏輯const index = imageRefs.current.findIndex((ref) => ref === entry.target);console.log(`圖片 ${index + 1} 進(jìn)入可視區(qū)域`);// 加載完成后可以停止觀察該元素observerRef.current?.unobserve(entry.target);}});}, options);// 開(kāi)始觀察所有的元素imageRefs.current.forEach((ref) => {if (ref) {observerRef.current?.observe(ref);}});return () => {// 組件卸載時(shí)清理觀察者if (observerRef.current) {observerRef.current.disconnect();}};}, []);const imageList = Array.from({ length: 10 }, (_, index) => index + 1);return (<div style={{ height: '300px', overflowY: 'auto' }}>{imageList.map((item, index) => (<divkey={index}ref={(ref) => {imageRefs.current[index] = ref as HTMLDivElement;}}style={{height: '200px',width: '200px',backgroundColor: 'gray',marginBottom: '10px',}}/>))}</div>);
}export default LazyLoadComponent;

示例詳述

  • useRef 用于創(chuàng)建 imageRefsobserverRef 引用,imageRefs 用于存儲(chǔ)每個(gè)元素的引用,observerRef 用于存儲(chǔ) IntersectionObserver 的實(shí)例。
  • useEffect 中創(chuàng)建了 IntersectionObserver 實(shí)例,并設(shè)置了觀察的選項(xiàng)。在 entries 的回調(diào)中,當(dāng)元素進(jìn)入可視區(qū)域時(shí)進(jìn)行相應(yīng)的操作,這里只是簡(jiǎn)單地打印了信息。
  • 在返回的組件結(jié)構(gòu)中,模擬了一個(gè)包含多個(gè)灰色方塊的列表,每個(gè)方塊都有一個(gè) ref,用于被觀察。

注意,實(shí)際應(yīng)用中,你需要根據(jù)具體的需求進(jìn)行更多的邏輯處理和樣式調(diào)整,比如實(shí)際的圖片加載、數(shù)據(jù)獲取等操作。

2、react-lazyload

在 React 項(xiàng)目中,react-lazyload 可以用于長(zhǎng)列表加載。

(一)基本原理和適用場(chǎng)景

react-lazyload 的核心原理是監(jiān)聽(tīng)元素是否進(jìn)入可視區(qū)域,當(dāng)元素進(jìn)入可視區(qū)域時(shí)才觸發(fā)實(shí)際的加載操作。對(duì)于長(zhǎng)列表加載場(chǎng)景,這一特性非常有用。

在長(zhǎng)列表中,可能存在大量的數(shù)據(jù)項(xiàng)需要展示,一次性加載所有數(shù)據(jù)項(xiàng)可能會(huì)導(dǎo)致性能問(wèn)題,尤其是在處理圖片等資源較大的內(nèi)容時(shí)。使用 react-lazyload 可以延遲加載列表中的元素,只有當(dāng)用戶滾動(dòng)到相應(yīng)位置,元素即將進(jìn)入可視區(qū)域時(shí)才進(jìn)行加載,這樣可以顯著提高初始頁(yè)面加載速度和整體的用戶體驗(yàn)。

(二)使用示例

以下是一個(gè)在 React 項(xiàng)目中使用 react-lazyload 處理長(zhǎng)列表加載的簡(jiǎn)單示例:

  1. 首先,安裝 react-lazyload

    npm install react-lazyload
    
  2. 然后在代碼中使用:

import React from 'react';
import LazyLoad from 'react-lazyload';
import './App.css';const ListItem = ({ index }) => (<div style={{ height: 100, backgroundColor: 'lightblue', marginBottom: 10 }}>列表項(xiàng) {index}</div>
);const LongList = () => {const listLength = 100;const listItems = [];for (let i = 0; i < listLength; i++) {listItems.push(<ListItem key={i} index={i} />);}return (<div style={{ height: 500, overflowY: 'scroll' }}>{listItems.map((item, index) => (<LazyLoad key={index} once={true}>{item}</LazyLoad>))}</div>);
};export default LongList;

在上述示例中,創(chuàng)建了一個(gè)包含 100 個(gè)列表項(xiàng)的長(zhǎng)列表,通過(guò) react-lazyloadLazyLoad 組件包裹每個(gè)列表項(xiàng),實(shí)現(xiàn)了懶加載功能。當(dāng)用戶滾動(dòng)列表時(shí),每個(gè)列表項(xiàng)會(huì)根據(jù)其是否進(jìn)入可視區(qū)域來(lái)決定是否進(jìn)行加載。

(三)性能優(yōu)勢(shì)

  • 減少初始加載時(shí)間:在長(zhǎng)列表場(chǎng)景下,不必在頁(yè)面初始加載時(shí)就加載所有的列表項(xiàng)內(nèi)容,尤其是當(dāng)列表項(xiàng)包含較大的圖片或其他資源時(shí),這可以大大減少初始頁(yè)面加載時(shí)間,讓用戶更快地看到頁(yè)面的主要內(nèi)容。

  • 降低內(nèi)存占用:由于不是一次性加載所有數(shù)據(jù),因此可以減少內(nèi)存的占用,特別是對(duì)于移動(dòng)設(shè)備或內(nèi)存有限的環(huán)境,這有助于提高設(shè)備的響應(yīng)速度和整體性能。

  • 優(yōu)化用戶體驗(yàn):通過(guò)逐步加載內(nèi)容,避免了因?yàn)榇罅繑?shù)據(jù)同時(shí)加載而導(dǎo)致的頁(yè)面卡頓或無(wú)響應(yīng)現(xiàn)象,用戶可以在滾動(dòng)過(guò)程中平滑地瀏覽列表內(nèi)容,提升了用戶體驗(yàn)。

(四)注意事項(xiàng)

樣式處理:在使用 react-lazyload 時(shí),需要注意列表項(xiàng)的樣式設(shè)置。特別是當(dāng)列表項(xiàng)的高度或?qū)挾炔淮_定時(shí),可能會(huì)導(dǎo)致懶加載的判斷出現(xiàn)偏差??梢酝ㄟ^(guò)固定列表項(xiàng)的尺寸或者使用合適的 CSS 布局技巧來(lái)解決這個(gè)問(wèn)題。

三、tree-shaking

1、package.json 中的 sideEffects 配置

  1. package.json 中添加 "sideEffects" 字段:
    如果你的項(xiàng)目中所有的 .css 文件都沒(méi)有副作用(例如沒(méi)有在 CSS 中使用 :global 或類似會(huì)產(chǎn)生全局影響的選擇器),可以將 "sideEffects" 配置為 false,這將告訴 Webpack 可以更激進(jìn)地進(jìn)行 Tree Shaking。
 {"name": "your-app","version": "1.0.0","sideEffects": false}

如果項(xiàng)目中有部分文件有副作用,你可以這樣配置:

{"name": "your-app","version": "1.0.0","sideEffects": ["*.css","some-module-with-side-effects"]
}

這里列出了有副作用的文件或模塊,其他未列出的模塊將被更積極地進(jìn)行 Tree Shaking。

2、組件按需加載Babel-plugin-import

以下是一個(gè)在 React 項(xiàng)目中使用 Babel-plugin-import 的代碼示例。

  1. 首先創(chuàng)建一個(gè)簡(jiǎn)單的 React 項(xiàng)目結(jié)構(gòu):

    my-react-app/
    ├── package.json
    ├── src/
    │   ├── App.js
    │   └── index.js
    
  2. package.json 中添加必要的依賴:

    {"dependencies": {"react": "^18.2.0","react-dom": "^18.2.0"},"devDependencies": {"@babel/core": "^7.22.10","@babel/plugin-proposal-class-properties": "^7.22.3","@babel/plugin-transform-runtime": "^7.22.5","@babel/preset-env": "^7.22.5","@babel/preset-react": "^7.18.6","babel-loader": "^9.1.2"}
    }
    
  3. 創(chuàng)建 .babelrc 文件并配置 Babel-plugin-import

    {"presets": ["@babel/preset-react","@babel/preset-env"],"plugins": [["import",{"libraryName": "antd","libraryDirectory": "es","style": "css"}]]
    }
    
  4. src/App.js 中編寫示例代碼:

    import React from 'react';
    // 使用 Babel-plugin-import 優(yōu)化引入 antd 的 Button 組件
    import { Button } from 'antd';const App = () => {return (<div><Button type="primary">點(diǎn)擊我</Button></div>);
    };export default App;
    
  5. src/index.js 中渲染 App 組件:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import App from './App';ReactDOM.render(<App />, document.getElementById('root'));
    
  6. 假設(shè)使用 Webpack 進(jìn)行構(gòu)建,配置 webpack.config.js

    const path = require('path');module.exports = {entry: './src/index.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'bundle.js'},module: {rules: [{test: /\.(js|jsx)$/,exclude: /node_modules/,use: {loader: 'babel-loader'}}]}
    };
    

這樣,在項(xiàng)目中通過(guò) Babel-plugin-import 對(duì) antd 的組件引入進(jìn)行了優(yōu)化,實(shí)際應(yīng)用中可以根據(jù)自己的項(xiàng)目需求和庫(kù)的使用情況進(jìn)行相應(yīng)的調(diào)整。

3、使用 Lodash 庫(kù)的優(yōu)化

以下是一個(gè)簡(jiǎn)單的代碼示例,展示如何在 React 項(xiàng)目中使用 lodash-es 版本并結(jié)合 Webpack 的 Tree Shaking 功能:

  1. 創(chuàng)建一個(gè) React 項(xiàng)目:

    npx create-react-app my-lodash-example
    cd my-lodash-example
    
  2. 安裝 lodash-es

    npm install lodash-es
    
  3. 創(chuàng)建一個(gè)示例組件 App.js

    import React from 'react';
    import pick from 'lodash-es/pick';const data = {name: 'John',age: 30,city: 'New York'
    };const filteredData = pick(data, ['name', 'age']);const App = () => {return (<div><p>Name: {filteredData.name}</p><p>Age: {filteredData.age}</p></div>);
    };export default App;
    
  4. package.json 中確保 "sideEffects": false(如果你的項(xiàng)目沒(méi)有真正的副作用):

    {"name": "my-lodash-example","version": "0.1.0","private": true,"dependencies": {//..."lodash-es": "^4.17.21","react": "^18.2.0","react-dom": "^18.2.0","react-scripts": "5.0.1"},"sideEffects": false,"scripts": {"start": "react-scripts start","build": "react-scripts build","test": "react-scripts test","eject": "react-scripts eject"}
    }
    
  5. 因?yàn)?create-react-app 隱藏了 Webpack 配置,但是在生產(chǎn)構(gòu)建模式下(npm run build),它默認(rèn)會(huì)啟用 Tree Shaking。

在這個(gè)示例中,我們只從 lodash-es 中引入了 pick 函數(shù),并且通過(guò)配置 sideEffects 和在生產(chǎn)構(gòu)建時(shí),Webpack 會(huì)進(jìn)行 Tree Shaking 來(lái)去除未使用的代碼。

create-react-app 項(xiàng)目中,雖然隱藏了 Webpack 配置,但默認(rèn)在生產(chǎn)構(gòu)建時(shí)已經(jīng)開(kāi)啟了一些優(yōu)化措施包括 Tree Shaking,不過(guò)你可以通過(guò)以下幾種方式來(lái)進(jìn)一步優(yōu)化和確保 Tree Shaking 效果:

4、使用 purgecss(針對(duì) CSS)

  1. 安裝 purgecss 及其相關(guān)依賴:

    npm install purgecss purgecss-webpack-plugin --save-dev
    
  2. webpack.config.js(雖然 create-react-app 隱藏了此文件,但可以通過(guò) eject 暴露出來(lái),這是一個(gè)不可逆操作,需謹(jǐn)慎考慮)中添加 PurgeCSSPlugin

    const PurgeCSSPlugin = require('purgecss-webpack-plugin');module.exports = {//...其他配置plugins: [new PurgeCSSPlugin({paths: glob.sync(`${paths.appSrc}/**/*`, { nodir: true }),}),],
    };
    

    這將幫助去除未使用的 CSS 代碼,與 Tree Shaking 一起優(yōu)化項(xiàng)目體積。

請(qǐng)注意,在對(duì) create-react-app 的配置進(jìn)行修改時(shí),尤其是涉及到 eject 操作,要充分了解其影響和風(fēng)險(xiǎn),并且在修改前最好備份項(xiàng)目代碼。

http://www.risenshineclean.com/news/52900.html

相關(guān)文章:

  • 房地產(chǎn) 網(wǎng)站模板南寧百度seo優(yōu)化
  • 網(wǎng)站備案入口營(yíng)銷活動(dòng)推廣策劃
  • 怎么樣可以設(shè)計(jì)網(wǎng)站搜索引擎優(yōu)化的具體措施
  • 天津市城鄉(xiāng)建設(shè)網(wǎng)網(wǎng)站優(yōu)化的意義
  • 手機(jī)百度網(wǎng)頁(yè)版 入口seo網(wǎng)站優(yōu)化平臺(tái)
  • 怎樣在工商局網(wǎng)站做公示網(wǎng)絡(luò)營(yíng)銷案例及分析
  • 專門做干果批發(fā)的網(wǎng)站國(guó)際新聞?lì)^條今日國(guó)際大事
  • 東莞網(wǎng)站建設(shè)推廣公司哪家好如何推廣app賺錢
  • 亞馬遜網(wǎng)官網(wǎng)首頁(yè)四川seo平臺(tái)
  • 做相冊(cè)本哪個(gè)網(wǎng)站好用嗎短視頻推廣
  • 制作網(wǎng)站公石家莊谷歌seo
  • 做公司網(wǎng)站需要會(huì)什么一鍵優(yōu)化表格
  • 有哪些做微博長(zhǎng)圖網(wǎng)站澤成seo網(wǎng)站排名
  • 辦文明網(wǎng)站 做文明網(wǎng)民活動(dòng)關(guān)鍵詞查詢網(wǎng)
  • 網(wǎng)絡(luò)推廣文案案例鄭州網(wǎng)站seo優(yōu)化公司
  • wordpress黑桃錘擊河北seo網(wǎng)絡(luò)推廣
  • 建設(shè)銀行網(wǎng)站查詢密碼怎么開(kāi)通seo的宗旨是什么
  • 廣州新際網(wǎng)站建設(shè)公司怎么樣世界球隊(duì)最新排名
  • 泰安網(wǎng)站建設(shè)公司seo個(gè)人優(yōu)化方案案例
  • 網(wǎng)站開(kāi)發(fā)得花多少錢營(yíng)業(yè)推廣是一種什么樣的促銷方式
  • 軟件開(kāi)發(fā)項(xiàng)目實(shí)施方案網(wǎng)站seo服務(wù)商
  • php做視頻直播網(wǎng)站信息流廣告投放工作內(nèi)容
  • 普通的訂閱號(hào)怎么做微網(wǎng)站泉州搜索推廣
  • 工程造價(jià)材料信息網(wǎng)山東seo推廣
  • 怎么樣創(chuàng)辦一個(gè)網(wǎng)站如何在國(guó)外推廣自己的網(wǎng)站
  • 專業(yè)酒店設(shè)計(jì)網(wǎng)站建設(shè)廣州網(wǎng)站快速排名
  • 騙子為啥使用香港服務(wù)器seo網(wǎng)站管理
  • dw班級(jí)網(wǎng)站建設(shè)全國(guó)疫情最新情況公布
  • jsp網(wǎng)站開(kāi)發(fā)實(shí)例精講seo外包方案
  • 網(wǎng)站空間 php程序谷歌瀏覽器下載手機(jī)版中文