博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用React 16.6新特性优化应用性能
阅读量:5925 次
发布时间:2019-06-19

本文共 3410 字,大约阅读时间需要 11 分钟。

利用React v16.6 Lazy&Suspense提升应用性能

本篇文章示例代码

前言

利用懒加载(Lazy Loading)优化页面性能不是什么新概念,不过React 16.6可以使用React.lazySuspense让原生React实现Lazy Loading大大的简化。

本篇文章也会拓展多种类似解决方案,见拓展部分

主要关键词说明

动态导入(Dynamic Import)

动态导入目前只是TC39的一个提案,不是JS(ES)标准的一部分。该功能可以动态化加载我们分割的组件/页面/文件,具体提案见下方链接:

目前要使用动态导入,需要使用到babel插件:

React.lazy

lazy函数提供了一种非常简便的方法动态导入组件,实现按需加载与代码分割

React.lazy使用方式非常简单,示例:

// lazy 接受一个函数作为参数const MyComponent = React.lazy(() => import('path/MyComponent'));// 展示时才加载(可以自定义一些条件)const App = () => (  
)复制代码

Suspense

Suspense组件用于包装lazy组件,在lazy组件还没有完全加载时,将fallback内容呈现给用户。

用动态加载,编译时会将文件分割,从加载文件到呈现会有时间延迟,此时可以使用Suspense展示一个loading。

使用示例

import React, { Suspense } from 'react';const MyComponent = React.lazy(() => import('path/MyComponent'));const Loading = (  

loading...

);const App = () => (
)复制代码

ErrorBoundary

ErrorBoundary(错误边界),可以使用ErrorBoundary包装Suspense,当Suspense出错时,统一处理错误。当然ErrorBoundary不止可用于Suspense,可以包装任意组件,然后统一处理错误。

实际场景中,可以自己先写一些通用错误页/组件继承自ErrorBoundary,然后包装要处理的组件。

也可以在组件的componentDidCatch生命周期中单独处理错误。

应用

性能优化说明

针对React加载的优化,可以分为两类:

  • 页面加载优化
  • 组件加载优化

很明显,React.lazy + Suspense可以很方便的应用于组件加载优化场景。

示例场景

CSR(客户端渲染)应用多页面的中某个耗时组件的加载

路由层

import React from 'react';import { BrowserRouter as Router, Route } from 'react-router-dom';import Header from './header';import Index from '../pages';import Welcome from '../pages/welcome';export default () => (  
);复制代码

某个存在耗时组件的页面

// welcome.jsimport React, { Suspense } from 'react';// 使用Suspense + React.lazy动态加载的耗时组件const Content = React.lazy(() => import('../components/content'));export default () => (  

Welcome

loading...
}>
);复制代码

说明

假设用webpack编译上面代码产出bundle.js。当进入首页时,加载的bundle.js不会包含Welcome Content部分的代码,切换页面到Welcome时会走网络加载需要的文件。

利用这种方法拆分多个组件时,可以显著的提升首屏时间。

完整示例项目

说明:该项目主要用于React一些新功能及有意思的用法示例,会持续更新,后面会涉及到hooks及最新源码相关,有兴趣的可以star。

拓展

针对SSR(服务端渲染)应用导入性能优化

可以使用 ,Next.js已支持直接使用dynamic import,并且可以指明什么时候动态导入(服务端/客户端),Next.js对首屏做了很多优化,首屏时,服务端会寻找到最简依赖渲染,具体可以点击前面链接查看文档。示例:

// Next.js 动态导入const MyComponent = dynamic(import('../components/MyComponent'), {  ssr: false,  loading: () => false,});复制代码

针对组件的动态加载

针对图片的lazy loading

针对动态请求

  • :对于CSR应用,在不用hooks的情况下,也可以不在componentDidMount中处理请求,让请求更加的优雅。
  • :利用Render Props + React hooks + Context API统一处理请求,支持SSR使用

封装react-request示例(统一请求处理)

import React from 'react';import PropTypes from 'prop-types';import { Fetch } from 'react-request';// import ReactLoading from 'react-loading';import config from '../../config';const CustomFetch = (props) => {  const { url, children } = props;  return (    
data.data} > {({ fetching, failed, data }) => { if (fetching) { // 正在请求:可以展示loading动画 // return
; } if (failed) { // 当前组件请求失败 // return

请求失败...

; } if (data) { // 请求成功 return children(data); } return null; }}
);};CustomFetch.propTypes = { url: PropTypes.string.isRequired,};export default CustomFetch;复制代码

在组件中使用CustomFetch

buildLinks = () => (    
{data => data.map((item, index) => (
{item.name}

{item.name}

))}
);复制代码

后记

其它性能优化方式,以及自己如何实现,可以参考我的上篇文章:

转载于:https://juejin.im/post/5c32d40951882524b333994d

你可能感兴趣的文章
智能家居系统结构标准化
查看>>
翻译:用户变量(User-Defined Variable)(已提交到MariaDB官方手册)
查看>>
016-Spring Boot JDBC
查看>>
Netty1:初识Netty
查看>>
hivesql优化的深入解析
查看>>
MySQL添加新用户、为用户创建数据库、为新用户分配权限
查看>>
javascript&jquery 判断滚动到页面底部
查看>>
拒绝“高冷”词汇!初学C#中的委托
查看>>
chrome插件网站
查看>>
关于CTeX的几个大坑
查看>>
使用SMART监控Ubuntu
查看>>
CentOS 6.9通过RPM安装EPEL源(http://dl.fedoraproject.org)
查看>>
VS2017调试闪退之Chrome
查看>>
IntentService用法
查看>>
echo -n 和echo -e 参数意义
查看>>
Buildroot stress-ng Linux系统压力测试
查看>>
PropertiesUtil 获取文件属性值
查看>>
Linux日志出现大量"kernel: NET: Registered protocol family 36"
查看>>
BZOJ1509: [NOI2003]逃学的小孩(树的直径)
查看>>
性能优化8--内存泄露
查看>>