代码分割:
代码包的代码渐多,代码包体积过大,加载时间过长
所以要进行分包,即由webpack/rollup/browserify进行的创建多个包并在运行时动态加载。
优点:可以避免加载用户加载不需要的代码,并在初始加载的时候减少所需加载的代码量。
可以使用:
1.import() 当webpack解析到时,会自动进行代码分割,同时确保babel能解析动态import语法,babel-plugin-syntax-dynamic-import插件。
2.React.lazy 能想渲染常规组件一样处理动态引入
const OtherComponent = React.lazy(() => import('./OtherComponent'))
然后在Suspense组件中渲染lazy组件,可以是在等待加载lazy时做优雅降级,如loading指示器等。
一个Suspense组件可以包裹多个懒加载组件
<OtherComponent />
</Suspense>```
3.异常捕获边界 Error boundaries
模块加载失败时,会触发一个错误,这是可以用Error boundaries来处理,以现实良好的用户体验并管理恢复事宜。
4.基于路由的代码分割
多数用户习惯页面间有加载切换的过程,此时可以用React.lazy 和 React.Router
第三方库来配置基于路由的代码分割
5.命名导出
创建一个中间模块来重新导出为默认模块,可以保证tree shaking不会出错,并且不必引入不需要的组件。
## Context 不需要每层组件手动添加props就能在组件树间进行数据传递的方法。
多用于:全局的数据 如当前认证的用户,主题,首选语言,很多不同层级的组件需要访问同样的一些数据,但可能会使复用性变差。
``` <ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider> ```
provider 接收一个value属性,传递给消费组件,一个provider可以和多个消费组件有对应关系,多个provider可以嵌套使用,里面会覆盖外面的数据
## 错误边界
是一种React组件,可以捕获并打印发生在其子组件树任何位置的js错误,并且会渲染出备用UI,可以放在最顶层的路由组件,
但错误边界无法处理以下错误:
1.事件处理,此时可以使用js的try catch
2.异步编码
3.服务端渲染
4.自身抛出的错误
如果在class组件中定义了static getDerivedStateFromError 或 componentDidCatch这两个生命周期中的任一个,他就变成一个错误边界。错误边界类似于js的catch{},但只针对React组件,只有class组件才能称为错误边界组件,并在整个应用中使用他。
React16开始,未被错误边界捕获的错误将会导致整个React组件树被卸载
可以将不同板块放在不同的错误边界中,其余部分仍然能交互
或者使用js错误报告服务
## Refs转发
## Fragments
## 高阶组件
## 与第三方库协同
会添加一个ref到这个根DOM元素,在componentDidMount中,我们能后获取他的引用就可以把他传递给jq插件了,为了防止React在挂载后去触碰这个DOM,可以从render函数返回一个空的div,div元素既没有属性也没有子元素,所以react不会更新他,就使的js可以自由管理这部分DOM,为了避免内存泄漏要记得把所有插件注册的监听都移除掉。
## 性能优化
生产环境要使用压缩版本
Browserify 需要安装插件:
envify(转换器用于设置正确的环境变量) uglifyify(移除开发相关的引用代码) terser(产物传给terser并进行压缩)
Rollup 需要安装插件:
replace(插件确保环境被正确设置) commonjs(插件用于支持CommonJS) terser(插件用于压缩并声称最终的产物)
webpack TerserPlugin插件
##虚拟化长列表
虚拟滚动技术,在有限的时间内渲染有限的内容,降低重新渲染组件消耗的时间,以及创建DOM节点的数量。
react-window 和 react-virtualized
## 避免调停
当组件的props和state变更,React会将最新返回的元素与之前渲染的元素进行对比,以决定是否有必要更新真实的DOM。当它们不相同时,React会更新DOM,也可以通过shouldComponentUpdate来提速,该方法会在重新渲染前被触发,如果返回true,则React执行更新
## Portals
将子节点渲染到存在于父组件以外的DOM节点的方案
## 协调(diffing算法)
React的render方法会创建 React元素组成的树,下次state或props更新时,相同的render方法会返回不同的树,React需要基于两棵树的差别来判断如何有效更新UI以保证当前UI与最新的树保持同步。
当对比两个树时,1⃣️,比较两个树的根结点,根结点类型不同,原树拆卸建新树,
componentWillUnmount-》建新树,componentWillMount-》componentDidMount,
根结点下的组件也会被卸载以及重新装载。
2⃣️,元素的类型相同时,保留DOM节点,仅对比更新有改变的属性,处理完当前节点后,继续递归子节点。
3⃣️,组件元素类型相同时,组件实例保持不变,这样state保持一致,react将更新组件实例的props跟最新的元素保持一致,并调用该实例的componentWillReceiveProps() 和 componentWillUpdate方法-》render
4⃣️,子节点进行递归,同时遍历两个子元素的列表,产生差异时,生成一个mutation
5⃣️,keys 列表里的唯一值
会产生性能损耗的情况:
1.在不同类型的组件中切换,但是输出内容非常相似,建议改成同一类型
2.key应该稳定可预测,通过Math.random生成key导致组件实例和DOM节点被不必要的重建,导致性能下降和子组件的状态丢失。