React性能优化(完整版)

2023-11-16

  • 我的博客
  • 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 = () => 1
        break;
      case 2:
        test = () => 2
        break;
      case 3:
        test = () => 3
        break;
      default:
        test = () => null
        break;
    }
    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;
  // 每次渲染更新props
  useEffect(() => {
    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-length
  gzip_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'
   }),
   // 压缩css
   new 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. 异部的chunk
   require.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.js
  webpack.config.dll.js
  dist
     index.html
  src
  public
  dll
     jquery
     manifest.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,
            },
          },
        },
      },
    });
  },
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React性能优化(完整版) 的相关文章

  • 用不同的颜色为 Google 热图着色

    我试图开发一个遵循 Google Map API 的热度 https developers google com maps documentation javascript examples layer heatmap https deve
  • 如何聚焦反应路由器链接

    我有一个用于搜索的输入框 并且希望能够按向下键将焦点从输入移动到列表的第一个s 看来我这里的东西不起作用 因为不是实际的 DOM 节点 我能够使用它来工作 a 代替 though let Link require react router
  • 在每页上插入折叠标记 (wkhtmltopdf)

    我正在使用 wkhtmltopdf 0 12 2 1 创建发票等 我需要在 pdf 的每一页上显示折叠标记 如果内容大于一页 如何在每个页面上使用 javascript 重复它们 这是我的基本标记 div class marks div c
  • 缩放事件侦听器之前的 Javascript OpenLayers

    我正在尝试将 OpenLayers 设置为在缩放开始之前不显示矢量图层 并使其在缩放结束后重新出现 我已经像这样建立了缩放结束部分 map new OpenLayers Map map element eventListeners zoom
  • Ajax JSON 数据和灯箱冲突

    我有一个带有灯箱插件的画廊设置光廊 http sachinchoolur github io lightGallery docs 该画廊与静态 HTML 完美配合 当我动态抓取 API 数据并尝试让灯箱处理这些项目时 问题就出现了 我似乎无
  • Backbone 中的加载栏

    我想显示加载消息 图标 直到列表中的所有项目都已呈现 这是我的示例中的 jsfiddle http jsfiddle net 9R9zU 58 http jsfiddle net 9R9zU 58 我尝试在 Feed 部分添加一个带有加载栏
  • 嵌套辅助函数和性能

    嵌套辅助函数对于使代码更易于理解非常有用 谷歌甚至建议在他们的应用程序中使用嵌套函数时尚指南 https google styleguide googlecode com svn trunk javascriptguide xml Nest
  • Menu.Item 中的 Antd 自动换行

    可以在 Menu Item 组件中应用自动换行吗 示例不起作用
  • 有没有好的 JQuery twitter 小部件可以循环推文?

    我想知道是否有任何 JQuery 小部件提供了循环加载推文的功能 例如在官方小部件中http twitter com about resources widgets widget profile http twitter com about
  • Nextjs 无法在生产环境中的“.next”目录中找到有效的构建

    我正在 docker 中运行我的应用程序 但我的生产构建和启动脚本仅在 docker 环境中失败 虽然node env开发在docker环境下运行良好 这是我的脚本 无法进行生产构建并启动服务器 我正在使用nodemon和babel bui
  • 为 Meteor 数据创建编号列表

    有没有办法获取 Meteor 集合中项目的编号列表的 编号 我知道我可以在 html 中做到这一点 但我觉得如果我可以在 spacebars 中放置一些东西 那么样式会更容易 如果我可以使用更好的术语 请告诉我 像这样的东西 前 20 部电
  • 使用本机 JavaScript 获取过渡中的 CSS 值

    这个问题之前被问过 但答案使用了 jQuery here https stackoverflow com q 8920934 3186555 因此 我将调整问题以专门询问native解决方案 to 最小化依赖关系 假设您有一个 div 然后
  • Cosmos DB 中的 MaxItemCount 源选项属性不起作用

    我正在尝试编写一个运行 SQL 查询的简单存储过程 并且我想通过使用 MaxItemCount 属性来限制结果 查询生成 3 个文档 但我只想返回 1 个文档 我使用 MaxItemCount 属性强制执行此限制 但这似乎不起作用 func
  • 限制 jQuery id 字符串吗?

    简而言之 我的问题是字符串在 jQuery 中作为可搜索 id 或可搜索内容有什么限制 更新 我得到了 ID 部分 但不是为什么我什至无法使用该字符串搜索 html 内容 对于任何愿意告诉我一个正则表达式来将模式从 MM dd yy HH
  • javascript:window.print() 打印 2 页,而我有 1 页

    我有一个简单的 HTML 文档 其中仅包含图像标签 我想在文档加载后打印图像 我的代码 img src form1 jpg alt form1 style margin 0 auto display block 它可以工作 但问题是它打印图
  • 如何按字母顺序排序并先小写排序

    如何获得以下排序的结果Food to Eat然后是 食物123 显然 第二个较低的 o 应该将 要吃的食物 带到排序后的第一个项目中 我很惊讶这个问题不容易通过谷歌找到答案 这个壮举没有包含在 javascript 标准中也让我感到惊讶 F
  • 更改javascript nodejs中所有页面的href url

    我已经实现了具有多种语言下拉菜单的引导导航栏 当我选择语言时 它将翻译页面 如何更改其他页面的 url 和按钮文本 当我选择french 将所有网址更改为 fr about and fr contact 如何使用 JavaScript 进行
  • WooCommerce 使用 AJAX 设置购物车数量?

    我已经为此绞尽脑汁好几天了 需要一些指导 我正在为 WooCommerce 网站完全从头开始制作自定义主题 现在我正在尝试让购物车功能正常工作 我一直试图使用按钮 来更新购物车中产品的数量 对我来说问题似乎是WC 我在functions p
  • 利用重力效果拖动元素

    我想完成类似于 photoshop com 和此网站的功能 http mrdoob com projects chromeexperiments google gravity http mrdoob com projects chromee
  • 使用 nginx 在云上部署 django 和 React

    我有一个 digitalocean 服务器 并且已经使用 Gunicorn 和 nginx 部署了 Django 后端服务器 如何在同一台服务器上部署 React 应用程序 您可以构建 React 应用程序并使用 Nginx 提供其静态文件

随机推荐

  • Windows文本编辑器——推荐、介绍与安装(1)

    撰写时间 2023年4月11日 目的 介绍各种类型的文本编辑器 阐述编辑器的优缺点 并提供安装与使用方法 前言 文本编辑器是应用各种已有的编程语言进行软件开发的一种重要工具 它能够帮助开发者更加高效地编写代码 也能够帮助电脑小白快速上手各种
  • Qt Model View TreeView及对应Model

    点击上方蓝字可直接关注 方便下次阅读 如果对你有帮助 可以点个在看 让它可以帮助到更多老铁 一 概述 接着之前的话题继续 如果把之前的QTableView改成QTreeView 我们在不改变Model的情况下可以直接得到一个没有结构层次的
  • Linux KVM 使用教程(一)

    文章目录 1 KVM简介 2 KVM 的功能列表 3 KVM 工具集合 3 1 Virsh命令 1 KVM简介 1 KVM 全称是 基于内核的虚拟机 Kernel based Virtual Machine 它是Linux 的一个内核模块
  • python2(基本)

    实验02 基本 一 课内实验题 共10小题 100分 题型得分 100 描述 编写程序 从键盘输入两个整数 计算并输出这两个整数的和 平均值 最小值和最大值 平均值保留2位小数 输入 分行输入两个整数 输出 分行输出两个整数的和 平均值 最
  • JDK1.8 下载与安装

    JDK安装 JDK1 8下载 下载链接 https www oracle com java technologies javase javase jdk8 downloads html 根据操作系统版本下载 这里以win10 64位操作系统
  • 驱动程序里ioctl下switch问题

    今天在写步进电机驱动程序时 switch语句引出3个分支 case 0 case 1 case 2 case 0 什么都不做 case 1让步进电机正向转动 case 2让步进电机反向转动 但是测试时 case 2怎么也动不起来 后来把ca
  • PLSQL Developer的配置方法

    1 下载32位的版本instantclient basic nt 11 2 0 3 0 zip 因为PLSQLDev是32位的 没有64位的版本 这 个和操作系统无关 2 instantclient下载完后是一个压缩文件 不需要安装 配置一
  • 服务器系统如何清理,服务器清理内存怎么清理

    服务器清理内存怎么清理 内容精选 换一换 本节操作指导您完成Windows操作系统云服务器磁盘空间清理 弹性云服务器匀出一部分磁盘空间来充当内存使用 当内存耗尽时 云服务器可以使用虚拟内存来缓解内存的紧张 但当内存使用率已经非常高时 频繁的
  • 关于HTTP协议,一篇就够了

    HTTP简介 HTTP协议是Hyper Text Transfer Protocol 超文本传输协议 的缩写 是用于从万维网 WWW World Wide Web 服务器传输超文本到本地浏览器的传送协议 HTTP是一个基于TCP IP通信协
  • TCP 连接管理机制(一)——TCP三次握手详解 + 为什么要有三次握手

    TCP是面向连接的协议 在通信之前需要先建立连接 其本质就是打开一个socket文件 这个文件有自己的缓冲区 如果要发送数据 上层把数据拷贝到发送缓冲区 如果是接收数据 OS直接把来自网络的数据拷贝到接收缓冲区里 那么三次握手期间 Serv
  • youversion.com的圣经无法使用、无法连接、无法下载离线版本的解决方法

    最近 youversion com的圣经无法使用 无法连接 无法下载离线版本了 这是一部很好用的圣经软件 以前一直用着 后来ipad越狱重新安装的时候就不能连接了 后来无意间发现原来是这个网站被和谐了 至于GCD为什么这么做 以咱的智商尚不
  • 接口自动化测试须知

    一 做接口测试需要哪些技能 做接口测试 需要的技能 基本就是以下几点 业务流 了解系统及内部各个组件之间的业务逻辑交互 数据流 了解接口的I O input output 输入输出 协议 包括http协议 TCP IP协议族 http协议
  • CMD查杀端口的两种方式

    第一种 netstat ano windows r输入cmd并打开 输入netstat ano 记住对应的6052 输入杀掉端口 taskkill pid 6052 f 第二种 netstat aon findstr 8080 直接输入ne
  • Win10 + VS2017 + Ceres配置

    前言 Ceres是google出品的一款基于C 的开源非线性优化库 官方文档 Ceres官方文档地址 依赖库 Eigen 官网 glog github gflags github Ceres github 配置过程 1 Eigen Eige
  • Python3 爬虫 requests+BeautifulSoup4(BS4) 爬取小说网站数据

    刚学Python爬虫不久 迫不及待的找了一个网站练手 新笔趣阁 一个小说网站 前提准备 安装Python以及必要的模块 requests bs4 不了解requests和bs4的同学可以去官网看个大概之后再回来看教程 爬虫思路 刚开始写爬虫
  • GPT专业应用:快速生成职位描述(JD)

    正文共 814 字 阅读大约需要 3 分钟 人力资源必备技巧 您将在3分钟后获得以下超能力 快速生成职位描述 Beezy评级 B级 经过简单的寻找 大部分人能立刻掌握 主要节省时间 推荐人 Kim 编辑者 Linda 图片由 Lexica
  • 数据中台与传统大数据平台有什么区别?_光点科技

    一 数据中台 数据中台是聚合和治理跨域数据 将数据抽象封装成服务 提供给前台以业务价值的逻辑概念 数据中台是在平台概念上的升级 不再单纯的将功能进行大杂烩 理念上 中台有几个特点 第一 更强调数据集中存储 统一管理 提供标准化的服务 第二
  • 【毕业设计】基于springboot + vue微信小程序商城

    目录 前言 创新点 亮点 毕设目录 一 视频展示 二 系统介绍 三 项目地址 四 运行环境 五 设计模块 前台 后台 六 系统功能模块结构图 数据库设计 七 准备阶段 使用真实支付 使用模拟支付 八 使用说明 九 登录后台 十 后台页面展示
  • 前端常用工具库方法整理

    欢迎点击领取 前端面试题进阶指南 前端登顶之巅 最全面的前端知识点梳理总结 前言 在闲余的时间整理一份我们可能用到的前端工具库方法 依赖库 名称 cropperjs 图片裁剪 exif js lrz 图片旋转问题 html2canvas d
  • React性能优化(完整版)

    我的博客 http wangxince site my demo markdown React 性能优化 1 减少 render 次数 shouldComponentUpdate PureComponent shouldComponentU