使用React微前端的完整指南 (使用read_csv函数读取某地区房屋销售数据.csv文件)
概述
微前端是一种最新的开发模式,其中Web应用程序用户界面(UI)由自主组件组装而成。这些组件可以由不同的团队使用不同的技术来构建。微前端的架构类似于后端,后端是使用半独立的微服务构建的。
微前端需要将前端单体拆分为几个更小、更容易管理的部分。这种开发架构非常重要,因为它可以提高开发人员处理前端代码的效率。
微前端的优点
- 模块化:微前端将大型复杂应用程序分解成较小的模块,使开发和维护更加容易。
- 独立部署:每个微前端可以独立部署,而无需影响其他模块。
- 团队协作:不同的团队可以并行开发微前端,提高开发效率。
- 技术异构性:微前端支持使用不同的技术构建组件,提供更大的灵活性。
- 可扩展性:微前端架构易于扩展,可以随着应用程序的增长添加新的功能或组件。
微前端的缺点
- 复杂性:微前端架构比单体应用程序更复杂,需要额外的管理和通信。
- 性能:微前端可能会引入额外的网络请求和通信延迟,从而影响性能。
- 版本控制:当不同团队开发不同的微前端时,版本控制和协调可能会变得具有挑战性。
- 安全性:微前端可能引入新的安全风险,因为它们是由不同的团队开发并独立部署的。
实现选项
在React中实现微前端有两种主要方法:
- 模块联邦:Webpack 5中包含的插件,允许在不同的应用程序之间共享模块。
- Web组件:浏览器提供的标准,允许创建可重用的自定义元素。
架构
典型的微前端架构如下所示:
- 主机应用程序:负责加载和协调微前端。
- 微前端:自主组件,由不同的团队使用不同的技术构建。
- 通信机制:用于微前端和主机应用程序之间通信的机制,例如事件总线或RPC。
示例
以下是一个使用React和模块联合构建微前端的示例:
// 主机应用程序 import React from 'react'; import ReactDOM from 'react-dom'; import MicroFrontend from './MicroFrontend'; const App = () => { return (); }; ReactDOM.render(, document.getElementById('root'));
// 微前端(例如,标题) import React from 'react'; import ReactDOM from 'react-dom'; const Header = () => { return ( ); }; // 使用模块联合导出微前端 export default Header;
结论
微前端是一种强大的开发模式,可以简化大型前端应用程序的开发和维护。它通过将应用程序分解成更小的、独立的模块来提供模块化、独立部署和技术异构性等优势。虽然存在一些缺点,例如复杂性、性能和版本控制问题,但微前端架构已在许多组织中得到成功应用。
React性能优化指南
使用React开发的项目,可以从加载性能和运行时性能两个方面进行优化。
加载性能优化的目标是让用户更早地看到界面、更早地和应用交互。运行时性能优化目标是降低卡顿,交互更流畅 。
我们知道React的setState会触发diff和更新。默认是将整个组件树进行对比,但很多情况下diff是不必要的,因为一个子组件的props没有改变,就不需要进行diff工作。
为了避免这种对没有改变props的子组件进行多余的diff工作的情况,React提供了shouldComponentUpdate这个生命周期钩子, shouldComponentUpdate(nextProps, nextState) 。 这个生命周期钩子如果返回true,则会执行后面的render和diff工作,如果返回false,则React不会向下继续。用户可以在这个生命周期钩子中进行state和props的对比,判断是否需要更新。通常一个组件当前的props与nextProps属性值相同,并且state的属性值也相同,则不需要更新。
实现了shouldComponentUpdate这个方法,PureComponent采用了浅比较,
【 前端面试刷题网站 : 灵题库 ,收集大厂面试真题,相关知识点详细解析。】
对应class组件的PureComponent,函数组件有方法实现类似的效果。
由于默认的PureComponent和memo都是默认用的浅比较。因此如果对象层级较深,会导致漏更新。
解决办法是,如果对象改变,重新创建一个对象,如果数组改变,重新创建一个数组,解构赋值可以很容易地实现这一点: {};[] 。
用户可以自己实现shouldComponentUpdate以自定义比较逻辑,对于函数式组件,则可以通过的第二个参数来定义比较逻辑。
如果想要精确地判断区别,除了手动判断,还有一个自动化程度比较高的方式:不可变数据,这时一个不可变数据的JS实现: immutable-js 。
只有发生改动的节点会创建新的引用,因此相应的组件才会执行render和diff。
结论:最佳实践是PureComponent/ + 不可变数据。
Fragment可以避免不必要的dom节点。
JSX的标签表达式要求有一个根节点
如果就想让表达式返回一个标签列表,不应该在最外层加一个根节点,应该使用Fragment。
也可以简写
在注册事件回调时候,不要用匿名函数或者用bind生成新函数,应该用箭头函数或者构造里面bind,最好是构造函数里面bind(因为可以继承)。
当我们需要注册事件回调时候,可以写成这样写:
或者
上面这两种:匿名函数和bind表达式,都不推荐 。因为匿名函数的写法会在每次调用render时候都创建新的函数,而bind表达式也会在每次调用时候创建一个新的函数,React做diff时候发现事件回调函数不同,就会将旧的函数解绑(这样还会触发GC)并且绑定新的函数。
因此最好这样实现
或者
更推荐后者,因为我们知道:
class Test {log = () => {};} 和 class Test {log() {}}
这两种写法的区别在于前者log是类的实例方法,而后者是原型方法,因此在构造函数中绑定,能让其他使用原型继承方法继承Test的组件可以继承到log方法。
如果使用函数式组件,应该使用useCallback这个hook。关于useCallback的使用,请参考本知识库的React进阶一文。
因为React在解析JSX时候需要将style对象解析成css style字符串。更推荐将样式写在CSS中。
如果在render方法进行setState,可能导致循环地进行diff工作。
让条件分支中只包含需要改动的元素,不包含不需要改动的元素,防止diff子节点和更新节点时候增加不必要的操作,消耗性能。
示例:
应该改成下面这种写法:
我们知道,Vue中有计算属性的能力,能够根据依赖的数据计算出我们关心的数据,而且有缓存的能力:依赖的值不变的话,不需要计算,直接返回结果。
React如果想要实现根据依赖的数据计算我们关心的数据,方法很简单。
但是这样实现没有缓存值的能力,当计算耗时较长时候会影响性能。
如何实现缓存值的能力呢?
可以使用memorize-one这个库:
如果使用函数式组件,可以使用useMemo来实现。关于useMemo库的使用,请参考本讲义中React进阶一文。
react-vitualize
启用concurrent mode之后,React会采取可中断渲染,让大规模的diff计算不会影响到界面的渲染,保证渲染和交互的流畅性。
使用Suspense组件可以在加载局部组件时候有更好的切换加载体验。
concurrent详细的介绍请阅读本系列concurrent mode文章。
不使用key或者用index作为key,都可能使列表在变化时候,让React无法辨别前后item对应关系,只能遍历对比,更新属性,这样可能会有多余的操作,造成性能损耗。
为什么需要key呢?我会单独写一篇文章详细讲解。
React官方提供了一个性能检测工具: react-addons-perf 。
这个工具可以在渲染React应用时候打印各个组件的各种耗时,用来分析性能浪费。
其中比较重要的一个方法是printWasted(),可以打印并未更新组件的渲染操作,如果发现你的组件花了很长时间render和diff,但组件视图实际并未发生变化,那就要考虑是否需要引入PureComponent等优化渲染性能了。
哪位大佬有 React前端技术与工程实践,这个教材网盘链接求一下大家!感恩
我这里有您想要的资源,通过网络网盘免费分享给您:
《React前端技术与工程实践》
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。