• 我的博客
  • http://wangxince.site/my-demo-markdown/

React 性能优化

1.减少 render 次数

shouldComponentUpdate PureComponent

shouldComponentUpdate(nextProps,nextState) {return !this.props.xxx === nextProps.xxx
}
// PureComponent 自动浅对比

React.Memo

// 1.当props变化的时候才会重新渲染 浅层对比
function Component(props) {}
const MyComponent = React.memo(Component);
// 2.自定义比较对比Props 如果相等返回true 否则返回false
function MyComponent(props) {}
export default React.memo(MyComponent, (prevProps, nextProps) => boolean);

2.减少函数的重新执行导致的渲染: useCallback

<button onClick={props.onClick}>改标题</button>
// 组件的每次渲染都会重新创建一个新的函数 因此函数的引用地址发生了变化
// 函数会重新开始执行 倒是子组件重新渲染
// 解决办法就是在函数没有改变的时候,重新渲染的时候保持两个函数的引用一致
const memoizedCallback = useCallback(()=>{}, [])
<Child onClick={memoizedCallback} name="xxx" />

3.缓存计算量比较大的函数结果: useMemo

  • 如果没有提供依赖项数组,useMemo 在每次渲染时都会计算新的值
  • 计算量如果很小的计算函数,也可以选择不使用 useMemo,因为这点优化并不会作为性能瓶颈的要点,反而可能使用错误还会引起一些性能问题
const base = useMemo(fn, []);

4.其他优化

1.在 render 渲染函数中不要进行复杂的副作用(数组排序 等等)

2.减少不必要的嵌套

3.虚拟列表

  • https://usehooks-ts.com/react-hook/use-intersection-observer

4.惰性渲染 && 惰性函数

  • 惰性加载表示函数执行的分支只会在函数第一次调用的时候执行。在第一次调用的过程中。
  • 该函数被覆盖为另一个按照合适的方式执行的函数。这样任何对原函数的调用就不用再经过执行的分支了
#var timeStamp = null;function getTimeStamp() {if (timeStamp) {return timeStamp}// 直接为外界的变量赋值timeStamp = new Date().getTime()return timeStamp;}console.log(getTimeStamp());console.log(getTimeStamp());console.log(getTimeStamp());console.log(getTimeStamp());
# 自执行函数 避免污染全局变量var getTimeStamp = (function () {var timeStamp = null;return function () {if (timeStamp) {return timeStamp;}timeStamp = new Date().getTime()return timeStamp;}})()
# 第一次只是在给函数重新定义 第二次执行时候才生效var getTimeStamp = function () {var timeStamp = new Date().getTime()getTimeStamp = function () {return timeStamp}return getTimeStamp()}
# element ui 源码 处理 dom 事件
export const on = (function() {if (!isServer && document.addEventListener) {return function(element, event, handler) {if (element && event && handler) {element.addEventListener(event, handler, false);}};} else {return function(element, event, handler) {if (element && event && handler) {element.attachEvent('on' + event, handler);}};}
})();
#function test(num) {switch (num) {case 1:test = () => 1break;case 2:test = () => 2break;case 3:test = () => 3break;default:test = () => nullbreak;}return test()}console.log(test(null)); // null

5.减少使用箭头函数 => 实例方法

  • 使用箭头函数的情况下,每次组件的重新渲染都创建新的事件处理程序,这会导致子组件重新渲染
// 1.class
<ComplexComponent onClick={evt => onClick(evt.id)} otherProps={values} />;
class MyComponent extends Component {render() {<ComplexComponent onClick={this.handleClick} otherProps={values} />;}handleClick = () => {};
}
// 2.hooks 使用useCallback包裹
const handleClick = useCallback(() => {}, []);
return <ComplexComponent onClick={handleClick} otherProps={values} />;
// 3.当状态很多时候
function useRefProps<T>(props: T) {const ref = useRef < T > props;// 每次渲染更新propsuseEffect(() => {ref.current = props;});
}function MyComp(props) {const propsRef = useRefProps(props);// 现在handleClick是始终不变的const handleClick = useCallback(() => {const { foo, bar, baz, bazz, bazzzz } = propsRef.current;}, []);
}
// 4.class需要bind的时候
// 不要这样 <input type="button" value="Click" onClick={this.handleButtonClick.bind(this)} />
<input type="button" value="Click" onClick={this.handleButtonClick} />;constructor() {this.state = {name: "Mayank"}this.handleButtonClick = this.handleButtonClick.bind(this)}

6.使用 Immutable.js

7.简化 state 和 props

  • 不是所有数据都需要放在 state 里面
  • 如果需要组件响应它的变动, 或者需要渲染到视图中的数据才应该放到 state 中
  • 这样可以避免不必要的数据变动导致组件重新渲染

8.颗粒化组件

  • vue 不需要 shouldComponentUpdate 会自动优化
  • 但是如果太过耦合 只要要任意一个属性值变动就会重新渲染整个组件
  • 应该将数据隔离抽取到单一职责的组件
  • 越细粒度的组件,可以收获更高的性能优化效果

8.懒加载异步组件

  • lazy Suspense
  • 减少主包体积 减少网络带宽
if (this.props.name == 'Mayank') {ComponentToLazyLoad = lazy(() => import('./mayankComponent'));
} else if (this.props.name == 'Anshul') {ComponentToLazyLoad = lazy(() => import('./anshulComponent'));
}
<div><h1>This is the Base User: {this.state.name}</h1><Suspense fallback={<div>Loading...</div>}><ComponentToLazyLoad /></Suspense>
</div>;

8.用 Fragment 代替自己最外层写的元素

9.复杂变动的组件+Key

  • 并不是只有 map 渲染的时候才能写 key
  • element 等组件库会将一些 API 利用 computed 缓存(computed 只有当 props 和 data 中的变量变化的时候才会重新缓存)
  • vue 的 diff 算法有时候自动计算会直接缓存
    • (比如你写了两个 El-Button 这时候 diff 算法将他们当成一个,而组件库内部的 computed 没有重新计算)
    • 此时就可能产生值变化 但是表单的 API 未变化的 bug
    • 这时候就需要给其加不同的 key

10.避免使用内联样式

  • <b style={{“backgroundColor”: “blue”}}>Welcome to Sample Page

11.防流节抖

12.CDN

13.gzip 压缩

http{gzip on;                      #开启gzip功能gzip_types *;                 #压缩源文件类型,根据具体的访问资源类型设定gzip_comp_level 6;            #gzip压缩级别gzip_min_length 1024;         #进行压缩响应页面的最小长度,content-lengthgzip_buffers 4 16K;           #缓存空间大小gzip_http_version 1.1;        #指定压缩响应所需要的最低HTTP请求版本gzip_vary  on;                #往头信息中添加压缩标识gzip_disable "MSIE [1-6]\.";  #对IE6以下的版本都不进行压缩gzip_proxied  off;            #nginx作为反向代理压缩服务端返回数据的条件
}

14.webpack 拆包

css 抽离

plugins: [new MiniCssExtractPlugin({// 对输出的css文件进行重命名filename: 'css/built.css'}),// 压缩cssnew OptimizeCssAssetsWebpackPlugin()
]#{test: /\.css$/,use: [ 'file-loader']['file-loader?name=[name].bundle[hash].css']},

js 抽离

 output: {filename: 'js/[name].js',path: path.resolve(__dirname, 'dist'),},

代码切割

1. 多入口 自动打包多个文件entry: {'jquery': './src/index.js','angular': './src/2.js'},
2. 异部的chunkrequire.ensure([],function(_require){_require('./xxx')})import('./2.css').then(() => {...})
}
#
3.
optimization: {splitChunks: {chunks: 'all'}
}
#
externals: {jquery: 'jQuery'
}
引入cdn

dll

#
硬链接一个 包,再手动scrit引入这个包 之后webpack就不用编译了
#
yarn add add-asset-html-webpack-plugin
webpack --config webpack.config.dll.js && webpack
# 文件路径webpack.config.jswebpack.config.dll.jsdistindex.htmlsrcpublicdlljquerymanifest.json
# webpack.config.js
const path = require('path')
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
module.export = {...externals: {jquery: 'jQuery'},plugins:[new HtmlWebpackPlugin({template: './index.html',filename: 'index.html',minify: { removeComments: true }}),// 告诉webpack哪些库不参与打包,同时使用时的名称也得变~new webpack.DllReferencePlugin({manifest: resolve(__dirname, 'dll/manifest.json')}),// 将某个文件打包输出去,并在html中自动引入该资源new AddAssetHtmlPlugin({filepath: path.resolve(__dirname, 'dll/jquery.js'),publicPath: '../dll',outputPath: 'vendor',}),]
}
# webpack.config.dll.js
const path = require('path');
const webpack = require('webpack')
module.exports = {entry: {jquery: ['jquery'],},output: {filename: '[name].js',path: path.resolve(__dirname, 'dll'),library: '[name]_[hash]'},plugins: [// 打包生成一个 manifest.json --> 提供和jquery映射new webpack.DllPlugin({// 映射库的暴露的内容名称 和 library 相同name: '[name]_[hash]',path: path.join(__dirname, 'dll/manifest.json'),})],mode: 'production'
};
externals: {jquery: 'jQuery'
},
new webpack.ProvidePlugin({$: path.resolve(path.join(__dirname, 'dll/jquery.js'))
}),

其他 cli 集成

  chainWebpack: function(config, { webpack }) {config.merge({optimization: {splitChunks: {chunks: 'all',minSize: 30000,minChunks: 3,automaticNameDelimiter: '.',cacheGroups: {vendor: {name: 'vendors',test({ resource }: any) {return /[\\/]node_modules[\\/]/.test(resource);},priority: 10,},},},},});},

React性能优化(完整版)相关推荐

  1. react性能优化方案_React灵敏且性能卓越的Spray + Akka解决方案,以“在Java和Node.js中发挥并发性和性能”...

    react性能优化方案 在我以前的文章中,我研究了一个虚拟的交易引擎,并将基于Java的阻止解决方案与基于Node.js的非阻止解决方案进行了比较. 在文章的结尾,我写道: 我怀疑随着Node.js的 ...

  2. [react] 你知道的react性能优化有哪些方法?

    [react] 你知道的react性能优化有哪些方法? shouldComponentUpdate PureComponent :Class Component React.Memo :Functio ...

  3. React性能优化记录(不定期更新)

    React性能优化记录(不定期更新) 1. 使用PureComponent代替Component 在新建组件的时候需要继承Component会用到以下代码 import React,{Componen ...

  4. React性能优化SCU | PureComponent | memo

    文章目录 React性能优化SCU React更新机制 render函数被调用 PureComponent 高阶组件memo React性能优化SCU React更新机制 我们在前面文章已经讲解过Re ...

  5. Airbnb 爱彼迎房源详情页中的 React 性能优化

    Airbnb 爱彼迎工程师和数据科学家将定期和大家分享移动开发.系统架构.数据科学及人工智能等领域的技术探索和经验心得. 正文从这开始-- 在一些容易被忽视但又非常重要的场景,可能会有许多严重影响性能 ...

  6. react 组件遍历】_从 Context 源码实现谈 React 性能优化

    (给前端大全加星标,提升前端技能) 转自:魔术师卡颂 学完这篇文章,你会收获: 了解Context的实现原理 源码层面掌握React组件的render时机,从而写出高性能的React组件 源码层面了解 ...

  7. React性能优化总结

    文章同步于Github Pines-Cheng/blog 初学者对React可能满怀期待,觉得React可能完爆其它一切框架,甚至不切实际地认为React可能连原生的渲染都能完爆--对框架的狂热确实会 ...

  8. react性能优化之memo的作用和memo的坑

    前言 在react中,组件渲染的是最常有的事情.但是,有部分的渲染是不必要的,是可以避免的. 在react的一般规则中,只有父组件的某一个状态改变,父组件下面所有的子组件不论是否使用了该状态,都会进行 ...

  9. React 性能优化完全指南,将自己这几年的心血总结成这篇!

    作者: MoonBall 原文地址: https://juejin.cn/post/6935584878071119885 本文分为三部分,首先介绍 React 的工作流,让读者对 React 组件更 ...

最新文章

  1. 依赖包 全局_composer 更新指定的依赖包
  2. 阿里mysql连接数据库服务器配置_配置链接mysql数据库
  3. 简单搞定linux逻辑卷
  4. 【问链财经-区块链基础知识系列】 第十八课 区块链应用于贷款结算
  5. Tomcat虚拟目录
  6. AVL树双旋转+图解
  7. 211计算机建设,“211工程”重点学科信息资源建设综述
  8. [转载] python字符串分割
  9. 陆振波的svm的matlab代码的解释,陆振波SVM的MATLAB代码解释
  10. 驱动级鼠标模拟实现_双飞燕血手幽灵V8M Max电竞鼠标兼具功能和性价比
  11. ARMv6 ARMv7 架构 整体介绍
  12. python爬虫的知识
  13. ORACLE安全加固篇
  14. 如何快速搭建在家里(外网)也能访问的云办公云桌面系统
  15. 物联网设备安全保护,需要这三道防线
  16. 1070: 小汽车的位置 Python
  17. 南方s730手簿说明书_s730手薄
  18. 「作于2018初」我的撸码人生
  19. ASIO 和 Websocket++ 独立编译
  20. Github上有趣的100个python项目

热门文章

  1. php mysql c语言教学网站
  2. 2023 MacBook Pro 与2021 Macbook Pro有哪些差别
  3. 简直绝了:周星驰与赵本山的对话
  4. python线性插值函数_Numpy一维线性插值函数的用法
  5. Matlab:disp函数、imshow函数的使用方法
  6. 使用全屏沉浸模式(Using Immersive Full-Screen Mode)
  7. BraTS数据集处理详解(附代码详解)
  8. 国家级大数据网络加速实验室落户迅雷
  9. 锐炬显卡可以linux吗,大势所趋!Intel锐炬显卡让你抛弃独显
  10. [量化-030]金融哲学-道德经解读-001-道德经的版本问题