文章目录React Loadable给 React 应用做代码分割的老牌方案1、 它解决什么问题2、 基本用法3、 loading 组件不只是个spinner4、 预加载与多资源并行5、 服务端渲染这块6、 现在还得用它吗React Loadable给 React 应用做代码分割的老牌方案react-loadable 在 GitHub 上拿到了 16.5K Star。jamiebuilds 出品的这个库只干一件事用动态 import 把组件拆成单独的 bundle按需加载。API 简洁配套了服务端渲染和 Babel 插件在 React 16 时代是代码分割的主流选择之一。1、 它解决什么问题Webpack 打包 React 应用默认会把所有代码塞进一个 bundle。项目小没问题业务一上场bundle 体积轻松冲到几百 KB首屏白屏时间跟着涨。代码分割就是把那一个大包拆成多个小包按页面或组件粒度切分用到啥加载啥。Webpack 2 原生支持import()语法做动态加载但手写一遍要处理加载状态、错误重试、超时、服务端渲染兼容啰嗦得很。react-loadable 把这层麻烦封装成一个高阶组件。传入loader和一个loading组件剩下的它管。2、 基本用法安装yarnaddreact-loadable最小例子import Loadable from react-loadable; import Loading from ./my-loading-component; const LoadableComponent Loadable({ loader: () import(./my-component), loading: Loading, }); export default class App extends React.Component { render() { return LoadableComponent/; } }loader返回一个 Promise解析出来的模块就是LoadableComponent渲染的内容。加载过程中显示Loading组件。3、 loading 组件不只是个spinnerloading组件会收到三个状态 properror、pastDelay、timedOut。errorloader 抛错时拿到 Error 对象可以渲染重试按钮pastDelay超过 delay 阈值默认 200ms才为 true避免加载太快闪一下LoadingtimedOut超过 timeout 阈值才为 true提示用户网络卡了完整模板function Loading(props) { if (props.error) { return divError! button onClick{props.retry}Retry/button/div; } else if (props.timedOut) { return divTaking a long time... button onClick{props.retry}Retry/button/div; } else if (props.pastDelay) { return divLoading.../div; } else { return null; } }delay和timeout都可以在Loadable()配置里改。4、 预加载与多资源并行LoadableComponent.preload()是静态方法可以在用户 hover 按钮时提前触发import()等真正渲染时 chunk 已经在缓存里。Loadable.Map用来并行加载多个资源组件、JSON 数据、CSS 都能塞。render方法必填它会把loaded对象交给你自己组装。Loadable.Map({ loader: { Bar: () import(./Bar), i18n: () fetch(./i18n/bar.json).then(res res.json()), }, render(loaded, props) { let Bar loaded.Bar.default; let i18n loaded.i18n; return Bar {...props} i18n{i18n}/; }, });5、 服务端渲染这块服务端没有import()可用react-loadable 的做法是启动服务前调Loadable.preloadAll()把所有动态模块全部加载完渲染时用Loadable.Capture收集这次请求实际渲染了哪些模块用 Webpack 插件ReactLoadablePlugin生成react-loadable.json记录模块到 bundle 的映射服务端getBundles(stats, modules)拿到这个请求需要的 bundle 列表注入script标签客户端入口调Loadable.preloadReady()等已加载的 bundle 就绪再ReactDOM.hydrate配套 Babel 插件react-loadable/babel会自动注入modules和webpack两个字段免去手动写require.resolveWeak。6、 现在还得用它吗React 16.6 之后官方出了React.lazy加Suspense覆盖了 react-loadable 大部分客户端场景API 更简洁。但 react-loadable 仍有它的位置服务端渲染的 bundle 收集逻辑、pastDelay与timedOut这种细粒度状态、还有历史项目兼容这些都是官方 lazy 没给的。新项目用React.lazy即可老项目迁不动、或者需要服务端 bundle 精确注入的react-loadable 还能继续干。BBC News、Cloudflare、Atlassian、Tinder、Unsplash 这些公司在用户名单里。社区也衍生了react-loadable-visibility基于可视区域加载和react-loadable-ssr-addon增强 SSR两个扩展库。、Unsplash 这些公司在用户名单里。社区也衍生了react-loadable-visibility基于可视区域加载和react-loadable-ssr-addon增强 SSR两个扩展库。