Код салгах

Bundling

Ихэнх React програмуудын файлууд нь Webpack эсвэл Browserify гэх мэт хэрэгслүүд ашиглан “багцалсан” байдаг. Багцлах гэдэг нь импортлогдсон файлууд болон файлуудыг нэг файл болгон нэгтгэх үйл явц юм: Энэ багц нь веб хуудас дээр нэмэгдэн бүхэл програмын нэг л удаа ачаалдаг.

Example

Програм:

// app.js
import { add } from './math.js';

console.log(add(16, 26)); // 42
// math.js
export function add(a, b) {
  return a + b;
}

Багц:

function add(a, b) {
  return a + b;
}

console.log(add(16, 26)); // 42

Анхаар:

Таны багцууд энэнээс өөр харагдаж болно.

Хэрэв Create React App, Next.js, Gatsby эсвэл төстэй хэрэгсэл ашигласан бол таны програмыг хайрцагнаас гадна багцлах Webpack тохиргоотой болно.

Хэрэв ийм хэрэгслүүд ашиглаагүй бол та өөрөө багцлах тохиргоог хийх болно. Жишээ болгон Webpack-н суулгах болон Эхлэн суралцах заавруудын баримтжуулалтыг харна уу.

Код салгах

Багцлах нь сайн ч таны програм томрохын хэрээр даган томроно. Ялангуяа гуравдагч том сангууд ашиглаж байгаа бол бүр их томроно. Та програмдаа юуг багтааж байгааг анзаарч байхгүй бол ачаалахад хэтэрхий удаан том багцтай болж болзошгүй.

Эцэст нь том багцтай болохоос сэргийлэхийн тулд багцуудаа “салгаж” эхлэх хэрэгтэй. Код-салгах боломж нь Webpack болон Rollup, Browserify шиг хэрэгслүүдэд (via factor-bundle) дэмжигддэг бөгөөд олон салгасан багцууд үүсгэн ажиллагааны үед динамикаар ачаалагддаг.

Код-салгах нь хэрэглэгчид одоо хэрэгтэй байгаа ч энэ ачаалагдсан зүйл нь хэрэглэгчид дахин хэзээ хэрэг болохгүй бол эхлэлийн ачаалалт дээр дуудагдах кодын хэмжээг бууруулахад туслад үүднээс “залхуу-ачаалалт” дуудах боломжийг олгодог. Ингэснээр таны програмын хурдыг гайхалтай нэмэгдүүлж болно.

import()

Код салгахийг өөрийн програмдаа хэрэгжүүлэх сайн арга бол динамик import() бичиглэл юм.

Өмнө:

import { add } from './math';

console.log(add(16, 26));

Дараа:

import("./math").then(math => {
  console.log(math.add(16, 26));
});

Анхаар:

Динамик import() бичиглэл бол ECMAScript (JavaScript) санал болголт бөгөөд одоогоор хэлний стандартын нэг хэсэг болоогүй байна. Энэ нь тун удахгүй хүлээн зөвшөөрөгдөхөөр байгаа болно.

Webpack энэ бичиглэлтэй болох үед энэ нь таны прогамыг кодыг автоматаар салгаж эхэлэнэ. Хэрэв та Create React App ашиглаж байгаа бол энэ нь таньд аль хэдийн тохируулагдаж өгсөн байгаа бөгөөд та үүнийг даруйхан ашиглаж эхлэх хэрэгтэй. Энэ нь мөн хүрээнээс гаднах Next.js дээр ч дэмжигддэг.

Хэрэв та Webpack өөртөө тохируулж байгаа бол та түүний код салгах зааврыг унших нь зүйтэй. Таны Webpack тохиргоо иймэрхүү харагдах хэрэгтэй.

Babel ашиглаж байгаа үед та Babel динамик импорт бичиглэлийг хувиргаж биш хөрвүүлж байгаа эсэхийг нягтлах хэрэгтэй. Ингэхийн тулд танд babel-plugin-syntax-dynamic-import хэрэг болно.

React.lazy

Анхаар:

React.lazy болон Suspence нь сервер талын дүрслэлт дээр хараахан байхгүй юм. Хэрэв та сервер дээр дүрслэлт хийгддэг програмд код салгалт хийхийг хүсвэл Ачаалагдахуйц компонентууд(Loadable Components) ашиглахийг зөвлөж байна. Энэ нь сервер талын дүрслэл дээр багц салгалтыг хийх заавар сайтай.

React.lazy функц нь танд энгийн компонентийн динамикаар импортлон дүрслэж боломжийг олгодог.

Өмнө:

import OtherComponent from './OtherComponent';

Дараа:

const OtherComponent = React.lazy(() => import('./OtherComponent'));

Энэ нь OtherComponent агуулсан багцийг компонент дүрслэгдэх үед динамикаар импортлодог.

React.lazy нь функц авдаг ба тэр нь динамик import()-г дуудах ёстой. Энэ нь Promise буцаах ёстой ба React компонент агуулсан модулийг хайж олдог.

Suspense

MyComponent дүрслэгдэх мөчид OtherComponent-г агуулсан модуль ачаалагдаагүй бол бид ямар нэг уншиж байгаа мэдээлэл гэх мэт ачаалагдаж байгааг нь илэрхийлэх агуулга харуулах хэрэгтэй. Үүнийг Suspense компонентоор хийдэг.

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );
}

fallback шинж чанар нь ямар ч React элементүүд хүлээж авах ба та компонент ачаалагдах хүртэл юуг ч дүрсэлж болно. Та Suspense компонентийг ямар ч залхуу компонентийн дараа байрлуулж болно. Бүр та олон залхуу компонентуудыг хүртэл нэг Suspense компонентоор хүрээлүүлэн ашиглаж болно.

const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </div>
  );
}

Алдааны зааг(boundaries)

Хэрэв бусад модуль ачаалагдаж чадахгүй бол(жишээ нь сүлжээны доголдлоос) алдаа гарна. Та эдгээр алдаануудыг удирдан хэрэглэгчид мэдэгдэх болон дахин сэргээх үйлдлийг алдааны зааг-р хийж болно. Алдааны заагаа үүсгэсний дараа та үүнийг залхуу компонентуудынхаа доор хаана ч ашиглан сүлжээний алдаа гарсан үед алдааны төлвөө дүрсэлж болно.

import MyErrorBoundary from './MyErrorBoundary';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));

const MyComponent = () => (
  <div>
    <MyErrorBoundary>
      <Suspense fallback={<div>Loading...</div>}>
        <section>
          <OtherComponent />
          <AnotherComponent />
        </section>
      </Suspense>
    </MyErrorBoundary>
  </div>
);

Чиглэлд тулгуурласан код салгалт(Route-based code splitting)

Таны програмын хаана код салгахийг шийдэх нь хэцүү байдаг. Та магадгүй багцуудыг тэнцүү байдлаар салгахийг хүсэх ч дэлгэцийн үйл ажиллагаанд саад учруулахгүй байхийг хүсэж болно.

Хамгийн сайн эхлэх газар бол чиглэлүүд(routes) юм. Веб үзэж байгаа хүмүүс хуудас солигдох үед ачаалагдахдаа бага зэрэг цаг авахад дассан байдаг. Мөн та бүхэл хуудсийг дахин нэг удаа дүрслэхийг илүүд үздэг бол таны хэрэглэгчид хуудас дээр байгаа бусад элементүүдтэй харьцах нь цөөн байдаг.

Энэ нь хэрхэн чиглэл дээр тулгуурласан код салгалт хийх жишээг React Router шиг санг React.lazy-тэй хамт ашиглан харуулжээ.

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import React, { Suspense, lazy } from 'react';

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route exact path="/" component={Home}/>
        <Route path="/about" component={About}/>
      </Switch>
    </Suspense>
  </Router>
);

Нэрлэсэн экспортууд

React.lazy нь одоогоор зөвхөн default экспортууд дээр дэмжигддэг. Хэрэв таний импортлохийг хүсэж буй модуль нэрлэсэн экспортууд ашигладаг бол та дундын модуль үүсгэн дахин default-руу экспортлож болно. Энэ нь танд ашиглагдаагүй компонентийг ачаалаагдахгүй байх баталгааг олгодог.

// ManyComponents.js
export const MyComponent = /* ... */;
export const MyUnusedComponent = /* ... */;
// MyComponent.js
export { MyComponent as default } from "./ManyComponents.js";
// MyApp.js
import React, { lazy } from 'react';
const MyComponent = lazy(() => import("./MyComponent.js"));