Размер пакета имеет значение.

Всем привет!

Итак, в прошлый день я прочитал историю о том, как Netflix уменьшил размер пакета своей целевой страницы, и это меня вдохновило: они удалили React и вместо этого использовали vanillaJS, но я не могу этого сделать. У меня ограниченное время для этой конкретной работы, поэтому я собираюсь добиться максимального сокращения в кратчайшие сроки.

Конечно, мы используем сжатие на стороне сервера, чтобы наши пользователи всегда получали самый маленький файл javascript, но даже после сжатия размер целевой страницы значительно велик (и, конечно, большая сила, такая как сжатие, требует большой ответственности - декомпрессия-)

Прежде чем мы начнем, позвольте мне отметить это; Я удалил мое приложение create-response-app, и если вы этого не сделали, сделайте это.

npm run eject

Примечание: после извлечения вы можете отменить его. Будь осторожен!

это запустит процесс извлечения из скриптов сборки Create React Native App. Вам зададут пару вопросов о том, как вы хотите построить свой проект. После успешного выполнения этой команды вы также должны выполнить все шаги, указанные ниже, которые применимы к вашей среде.

Первый шаг: проанализируйте комплект

мы должны установить пакет npm под названием «source-map-explorer».

npm install --save source-map-explorer

вы также можете использовать пряжу.

yarn add source-map-explorer

Затем в package.json добавьте следующую строку в scripts:

"analyze": "source-map-explorer build/static/js/main.*",

давай катимся.

npm run build 
npm run analyze

это откроет новую вкладку в вашем браузере по умолчанию, давайте взглянем на нее

так вот как выглядит пакетный анализ? довольно сложно, правда? Не совсем.

Оказалось, проблема в нашей лени. Наша целевая страница раньше была частью нашего основного приложения, но несколько месяцев назад мы их разделили. Мы забыли удалить кучу ненужных пакетов, и они сделали проект больше, чем должен быть.

Давайте посмотрим внимательнее, и вы легко увидите, что наши главные игроки - это момент, react-bootstrap, сахар, react -dom (реагировать) и redux-form, jquery ( как-то ).

Момент проблемы

Moment - действительно потрясающий пакет, простой в использовании и довольно мощный. С самого начала моей карьеры в области веб-разработки это был мой любимый способ легко вручить свидания, но он действительно большой.

Его ядро ​​составляет всего 52 КБ, но по какой-то причине он импортирует сразу все файлы локали. Он не имеет модульной структуры, поэтому вы можете использовать в своем приложении файлы локалей для всех языков мира.

Я не хочу этого, я использовал только tr, поэтому давайте избавимся от бесполезных локалей, к сожалению для нас, ни его документация, ни его ядро ​​не содержат подходящего для нас решения, но мы всегда можем использовать Webpack для этой работы. Мы будем использовать webpack.ContextReplacementPlugin.

Возможно, вы используете большие пакеты, такие как Moment, всегда старайтесь использовать модульные пакеты, чтобы вам не приходилось импортировать всю библиотеку сразу.

добавьте строку ниже в свой config / webpack.config.prod.js (вы также можете добавить это в webpack.config.dev.js, но это может замедлить или не замедлить разработчика прогресс сборки и может вызвать задержку при просмотре в реальном времени.)

// find plugins part and add this line, 
plugins: [

    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/),

вы можете изменить часть / en / на любой языковой стандарт. давайте перестроим наше приложение и проанализируем его.

Как видите, размер момента уменьшился до 59 КБ с помощью всего одной строки.

Сахар вреден !!

Шучу (Если вы не сидите на какой-то диете или не страдаете диабетом), мы использовали сахар по какой-то причине (не помню почему, не могли понять ни того, ни другого).

Когда я просмотрел документацию, я понял, что мы делаем это неправильно. Наши операторы импорта такие:

const Sugar = require('sugar');
// or 
import Sugar from 'sugar'

но это супер неправильно. Сахар имеет модульную структуру, и вам следует импортировать ту часть, которую вы хотите использовать.

import Sugar from 'sugar/number'
// or 
const Sugar = require('sugar/number')
// you don't have to change any code, 

теперь это должно уменьшить размер вашего пакета, но для меня этого было недостаточно, и, как я уже сказал, я даже не помню даже, для чего использовался этот пакет, я думаю, это один из остатков нашего основного проекта. поэтому я заменил Sugar на Vanilla JS и избавился от всего этого.

Redux-форма? Подождите, где я это использовал?

Хорошо, я использую Redux-форму в большинстве своих проектов, но я не помню, чтобы использовал ее на целевой странице, поэтому я поискал ее в проекте и нашел утечку. Проклятие! Как я это забыл?

Я просто скомбинировал его с другими редукторами и забыл.

import { combineReducers } from 'redux'
import { reducer as form } from 'redux-form'
import authReducer from './reducer_auth'
import fetchReducer from './reducer_fetch'
import {reducer as toastr} from  'react-redux-toastr'
import pageReducer from './reducer_page';
import { routerReducer as routing } from "react-router-redux"

const rootReducer = combineReducers({
  form,
  routing,
  toastr,
  auth: authReducer,
  data : fetchReducer,
  //post : postReducer,
//  validate : validateReducer,
  page : pageReducer,
});

export default rootReducer;

Я удалил его, и размер нашего пакета уменьшился до 877kb, хорошо, но недостаточно.

Кстати, само redux тоже является остатком. Я полностью удалю это

Следующий шаг - замена React на Preact

Preact - это легкая альтернатива React. Его ядро ​​составляет всего 4 КБ, и он в основном совместим с React.

Отказ от ответственности: несмотря на то, что Preact утверждает, что он совместим с React и его экосистемой, все еще есть некоторые пакеты (например, response-router), которые не работают должным образом и могут вызвать сбой вашего приложения.

yarn add preact preact-compat

Пакет Preact включает управление ядром и внутренним пространством, а предварительная совместимость требуется для совместимости с React.

Теперь, когда мы успешно загрузили пакеты preact, можно переходить к замене react на preact.

Для этого вы должны удалить свое приложение.

перейдите к config / webpack.config.dev.js и config / webpack.config.prod.js, найдите псевдоним и добавьте в него следующие строки.

alias: {
 
    "react": "preact-compat",
    "react-dom": "preact-compat"
    // there might be a defination for react native, keep it.
} 

После этого перезапустите приложение и проверьте, совместим ли preact с вашими пакетами.

К сожалению, это не помогло мне, и response-router вызвал ошибки.

Следующий шаг: замена response-router на preact-router

Это легко сделать, но если вы уже определили слишком много маршрутов, не пытайтесь это сделать и удалите Preact.

yarn add preact-router

Вы можете найти документацию здесь.

После всех этих шагов размер моего пакета уменьшился до 577 КБ, что на данный момент достаточно.

эти шаги сработали для меня, я не потерял никакой функциональности, но я не могу дать вам никакой гарантии, что это сработает и в вашем проекте.

Альтернатива: разделение кода

что, если в вашем приложении нет неиспользуемых библиотек? или ваше приложение слишком велико, чтобы даже пытаться заменить Preact на React? что тогда делать? Что ж, вы бы предпочли использовать разделение кода, к счастью для нас, приложение create-react-app поддерживает разделение кода.

Разделение на основе маршрута может быть лучшим выбором для разделения кода. Ознакомьтесь с документацией React;



Как добавить в приложение разбиение кода на основе маршрута?

сначала импортировать Suspense, lazy из React.

import React, {Suspense, lazy} from 'react';

теперь замените строки импорта на React lazy loading

// replace that line
import Index from './components/Index'
// to this
const Index = lazy(() => import('./components/Index'))

а теперь добавьте Suspense, и все готово.

<Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route exact path="/" component={Index}/>
      </Switch>
  </Suspense>

Спасибо за чтение :)!