Вы когда-нибудь задумывались, почему размер вашего пакета так велик только для того, чтобы использовать несколько зависимостей?
Я создал простой проект с несколькими производственными зависимостями - React, ReactDOM и компонент Button из response-bootstrap.
import React from 'react'; import ReactDOM from 'react-dom'; import { Button } from 'react-bootstrap';
После этого я запустил webpack в продакшене и был шокирован размером пакета даже в продакшене! 359 КБ - это довольно много для отправки, особенно для начинающих пользователей, которые потенциально могут иметь очень медленное подключение к Интернету. Мы можем выполнить некоторое разделение кода и кэширование для повторного использования ресурсов, но все же это всего лишь простое минимальное приложение, которое не должно быть таким большим - все, что я сделал, это подключил приложение Hello World к DOM с помощью кнопки из react-bootstrap
.
Version: webpack 2.2.1 Time: 20143ms Asset Size Chunks Chunk Names bundle.js 359 kB 0 [emitted] [big] main [0] ./~/react/react.js 55 bytes {0} [built] [17] ./~/react-dom/index.js 58 bytes {0} [built] [24] ./~/react-bootstrap/es/SafeAnchor.js 3.75 kB {0} [built] [25] ./~/react-dom/lib/ReactUpdates.js 9.67 kB {0} [built] [44] ./~/react-dom/lib/ReactReconciler.js 6.29 kB {0} [built] [45] ./~/react/lib/React.js 2.71 kB {0} [built] [194] ./src/App.js 64 bytes {0} [built] [314] ./~/react-bootstrap/es/Pager.js 2.93 kB {0} [built] [331] ./~/react-bootstrap/es/index.js 10.8 kB {0} [built] [349] ./~/react-dom/lib/ReactDOM.js 5.16 kB {0} [built] [375] ./~/react-dom/lib/ReactVersion.js 350 bytes {0} [built] [391] ./~/react-dom/lib/findDOMNode.js 2.46 kB {0} [built] [415] ./~/react/lib/ReactVersion.js 350 bytes {0} [built] [416] ./~/react/lib/onlyChild.js 1.34 kB {0} [built] [420] ./src/index.js 781 bytes {0} [built] + 406 hidden modules
Что-то точно не так. Итак, я начал с того, что увидел размер файла для двух зависимостей - React и ReactDOM.
Version: webpack 2.2.1 Time: 8397ms Asset Size Chunks Chunk Names bundle.js 146 kB 0 [emitted] main [3] ./~/object-assign/index.js 2.1 kB {0} [built] [15] ./~/react/lib/React.js 2.71 kB {0} [built] [16] ./~/react/lib/ReactElement.js 11.6 kB {0} [built] [76] ./~/react-dom/index.js 58 bytes {0} [built] [77] ./~/react/react.js 55 bytes {0} [built] [78] ./src/App.js 65 bytes {0} [built] [104] ./~/react-dom/lib/ReactDOM.js 5.16 kB {0} [built] [146] ./~/react-dom/lib/findDOMNode.js 2.46 kB {0} [built] [154] ./~/react-dom/lib/renderSubtreeIntoContainer.js 422 bytes {0} [built] [158] ./~/react/lib/ReactClass.js 27.1 kB {0} [built] [159] ./~/react/lib/ReactDOMFactories.js 5.53 kB {0} [built] [160] ./~/react/lib/ReactPropTypes.js 16.2 kB {0} [built] [162] ./~/react/lib/ReactPureComponent.js 1.32 kB {0} [built] [163] ./~/react/lib/ReactVersion.js 350 bytes {0} [built] [166] ./src/index.js 781 bytes {0} [built] + 152 hidden modules
Окей, примерно ~ 146 КБ. Звучит примерно правильно, согласно спецификациям React. Это означает, что для импорта компонента Button из react-bootstrap
потребовалось огромное количество ~ 213 КБ! Эй, подожди минутку. Это явно не имеет смысла. Все, что я сделал, это импортировал Button из react-bootstrap
. Мне сейчас не нужна вся библиотека… или нет?
Давайте еще раз посмотрим на импорт.
import React from 'react'; import ReactDOM from 'react-dom'; import { Button } from 'react-bootstrap';
Ага, меня осенило. Теперь я вижу, что сделал. Что происходит «под капотом»?
import { Button } from 'react-bootstrap';
эквивалентен
const { Button } = require('react-bootstrap');
что эквивалентно
const Button = {/*react-bootstrap module*/}.Button;
Итак, в конечном итоге я импортировал всю библиотеку response-bootstrap. Мне пришлось это сделать, прежде чем я смог добраться до кнопки!
Итак, что мы можем сделать, чтобы получить именно то, что мы хотим? Получите это прямо сейчас!
import Button from 'react-bootstrap/lib/Button';
И снова запуск webpack в продакшене дает
Version: webpack 2.2.1 Time: 9681ms Asset Size Chunks Chunk Names bundle.js 174 kB 0 [emitted] main [8] ./~/react-dom/lib/ReactUpdates.js 9.67 kB {0} [built] [25] ./~/react/lib/React.js 2.71 kB {0} [built] [28] ./~/react/react.js 55 bytes {0} [built] [127] ./~/react-dom/index.js 58 bytes {0} [built] [128] ./src/App.js 213 bytes {0} [built] [187] ./~/react-bootstrap/lib/Button.js 4.47 kB {0} [built] [203] ./~/react-dom/lib/ReactDOM.js 5.16 kB {0} [built] [229] ./~/react-dom/lib/ReactVersion.js 350 bytes {0} [built] [245] ./~/react-dom/lib/findDOMNode.js 2.46 kB {0} [built] [253] ./~/react-dom/lib/renderSubtreeIntoContainer.js 422 bytes {0} [built] [257] ./~/react/lib/ReactChildren.js 6.19 kB {0} [built] [258] ./~/react/lib/ReactClass.js 27.1 kB {0} [built] [259] ./~/react/lib/ReactDOMFactories.js 5.53 kB {0} [built] [260] ./~/react/lib/ReactPropTypes.js 16.2 kB {0} [built] [266] ./src/index.js 781 bytes {0} [built] + 252 hidden modules
разница в ~ 28kb. Так намного лучше. Но для компонента Button это еще немного =)
Вывод
Урок заключается в том, чтобы всегда проверять размер вашего пакета и проводить базовое сравнение в каждой новой сборке и критически относиться к своим зависимостям. Клиенты всегда на первом месте. Сделайте их счастливыми, и вы будете счастливы. Кроме того, не полагайтесь на деструктуризацию, когда требуются зависимости для уменьшения размера сборки. Это просто для того, чтобы более четко изложить ваши требования.