react-loadable
Недавно я учился реагировать, скорость загрузки первого экрана предыдущего проекта была очень медленной, поэтому я собрал некоторые методы оптимизации.react-loadable
Эта библиотека была обнаружена в процессе исследования загрузки по требованию компонентов маршрутизации, по сутиreact-router v4
официальный такжеcode splitting
связанная практика, но она больше не доступна в текущей версии webpack 3.0, поскольку необходимо использовать следующий связанный синтаксис
import loadSomething from 'bundle-loader?lazy!./Something'
Заинтересованные студенты могут учиться самостоятельно.
react-router-v4:code-splitting
Позже я обнаружил, что библиотека react-loadable может помочь нам загружать по запросу.На самом деле, она не сильно отличается от официальной реализации react-router-v4.Основное использование выглядит следующим образом:
Шаг 1: Сначала подготовьте компонент Loding, это официально, лучше, если вы напишете его сами:
const MyLoadingComponent = ({ isLoading, error }) => {
// Handle the loading state
if (isLoading) {
return <div>Loading...</div>;
}
// Handle the error state
else if (error) {
return <div>Sorry, there was a problem loading the page.</div>;
}
else {
return null;
}
};
Шаг 2: Внедрите react-loadable
import Loadable from 'react-loadable';
const AsyncHome = Loadable({
loader: () => import('../containers/Home'),
loading: MyLoadingComponent
});
Шаг 3: Замените наши оригинальные компоненты
<Route path="/" exact component={AsyncHome} />
Таким образом, вы обнаружите, что компонент импортируется только тогда, когда маршрут совпадает, достигаяcode splitting
Эффект в том, что мы часто говорим о загрузке по требованию, код делится на блоки, а не загружает все компоненты в начале.
Можно заметить, что щелчок по разным маршрутам загрузит чанк.js, который мы разделяем.
Ядро: импорт()
не делайimport
ключевые слова иimport()
Метод перепутан, метод введен для динамической загрузки.
import
Введение ключевых слов статически скомпилировано и улучшено, что создает устойчивость к нашей загрузке по запросу (закадровый голос: требование может быть загружено динамически), поэтому естьimport()
,а такжеreact-loadable
используетсяimport()
для динамической нагрузки.
Руан Ифэн: Загрузка реализации модуля
Более того, этот метод не может передавать переменные, а может использовать только строки и строковые шаблоны.Изначально я хотел абстрагировать код, который генерирует компоненты, но он оказался мертвым и живым, и я обнаружил, что яма здесь.
Loadable
react-loadable
Там 5к звезд, а внутренний механизм очень совершенен.Я не должен понимать текущий исходный код, поэтому прочитал его по ошибке.initial commit
исходный код.
мы сталкиваемся сLoadable
Использование функции выглядит следующим образом:
const AsyncHome = Loadable({
loader: () => import('../containers/Home'),
loading: MyLoadingComponent
});
В качестве параметра получает объект конфигурации, имя первого свойстваloader
, — метод динамической загрузки нужных нам модулей, второй параметр — нашLoading
Компонент, этот компонент будет занимать место в процессе еще не завершенной динамической загрузки.
{
loader: () => import('../containers/Home'),
loading: MyLoadingComponent
}
Возвращаемое значение этого метода является компонентом реакции, мыRoute
Когда компонент соответствует URL-адресу, этот компонент загружается, а компонент загружает компонент асинхронно и обрабатывает ошибки с помощью метода загрузчика. На самом деле их так много, и это также означает немного высокоуровневых компонентов.
Затем давайте взглянем на исходный код (часть параметров исходного кода использует ts для проверки типов).
import React from "react";
export default function Loadable(
loader: () => Promise<React.Component>,
LoadingComponent: React.Component,
ErrorComponent?: React.Component | null,
delay?: number = 200
) {
// 有时组件加载很快(<200ms),loading 屏只在屏幕上一闪而过。
// 一些用户研究已证实这会导致用户花更长的时间接受内容。如果不展示任何 loading 内容,用户会接受得更快, 所以有了delay参数。
let prevLoadedComponent = null;
return class Loadable extends React.Component {
state = {
isLoading: false,
error: null,
Component: prevLoadedComponent
};
componentWillMount() {
if (!this.state.Component) {
this.loadComponent();
}
}
loadComponent() {
// Loading占位
this._timeoutId = setTimeout(() => {
this._timeoutId = null;
this.setState({ isLoading: true });
}, this.props.delay);
// 进行加载
loader()
.then(Component => {
this.clearTimeout();
prevLoadedComponent = Component;
this.setState({
isLoading: false,
Component
});
})
.catch(error => {
this.clearTimeout();
this.setState({
isLoading: false,
error
});
});
}
clearTimeout() {
if (this._timeoutId) {
clearTimeout(this._timeoutId);
}
}
render() {
let { error, isLoading, Component } = this.state;
// 根据情况渲染Loading 所需组件 以及 错误组件
if (error && ErrorComponent) {
return <ErrorComponent error={error} />;
} else if (isLoading) {
return <LoadingComponent />;
} else if (Component) {
return <Component {...this.props} />;
}
return null;
}
};
}
Amway о проекте, которым я занимаюсьreact-music
Использованная литература:
Введение в загружаемые файлы React
Руан Ифэн: Загрузка реализации модуля