Анализ принципа реактивно-загружаемых

внешний интерфейс JavaScript React.js Webpack

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Эффект в том, что мы часто говорим о загрузке по требованию, код делится на блоки, а не загружает все компоненты в начале.

chunk

Можно заметить, что щелчок по разным маршрутам загрузит чанк.js, который мы разделяем.

Ядро: импорт()

не делайimportключевые слова иimport()Метод перепутан, метод введен для динамической загрузки.

importВведение ключевых слов статически скомпилировано и улучшено, что создает устойчивость к нашей загрузке по запросу (закадровый голос: требование может быть загружено динамически), поэтому естьimport(),а такжеreact-loadableиспользуетсяimport()для динамической нагрузки.

Руан Ифэн: Загрузка реализации модуля

tc39/proposal-dynamic-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

webpack v3 в сочетании с react-router v4 для динамического импорта — загрузка по требованию (ленивая загрузка)

Руан Ифэн: Загрузка реализации модуля

tc39/proposal-dynamic-import

Разделение кода в react-router4 (на основе webpack)

react-router-v4:code-splitting