Skip to content

Translate "Sunsetting Create React App" #833

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Conversation

smikitky
Copy link
Member

No description provided.


```txt
- core.js 25kb
- home.js 25kb
- dashboard.js 25kb
```

One way to do code-splitting is with `React.lazy`. However, this means that the code is not fetched until the component renders, which can cause network waterfalls. A more optimal solution is to use a router feature that fetches the code in parallel while the code is downloading. For example, React Router provides a `lazy` option to specify that a route should be code split and optimize when it is loaded:
コード分割を行う方法のひとつは、`React.lazy` を使用することです。しかし、この方法ではレンダーされる段階になって初めてコードが取得されるため、ネットワークウォーターフォールが発生する可能性があります。より良い解決策は、コードがダウンロードされる間に並行してコードをフェッチするためのルータ機能を使用することです。例えば、React Router `lazy` オプションを提供しており、これを使ってルートをコード分割対象として指定し、読み込みタイミングを最適化できます。
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここよく分かっていません。とりあえず直訳していますが、「コードがダウンロードされる間に並行してコードをフェッチ」って何やねん、と思っています。

「コードがダウンロードされる間に並行してデータをフェッチ」と言いたい? 「コードがダウンロードされる間に並行して別のルートのコードをを(プリ)フェッチ」と言いたい? ただ直後のコードサンプルからはそのような雰囲気が全く感じられませんし…。

Copy link
Collaborator

@honey32 honey32 Jun 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

僕はてっきり「ファイルがロードされたら、即座に該当するチャンクのダウンロードをする」という動作だと思っていましたが、

https://ja.react.dev/reference/react/lazy を見た感じ、「MarkdownPreview初回レンダーしたときに はじめてチャンクのダウンロードが始まる」という挙動になるらしいです。

ローカルでは試していませんが、同ページにデモがあったので、そちらで確認できました。

import { useState, Suspense, lazy } from 'react';
import Loading from './Loading.js';

const MarkdownPreview = lazy(() => delayForDemo(import('./MarkdownPreview.js')));
// MarkdownPreview.js のダウンロードは、トップレベルでいきなり開始する……のではなく、

export default function MarkdownEditor() {
  const [showPreview, setShowPreview] = useState(false);
  const [markdown, setMarkdown] = useState('Hello, **world**!');

  console.log("render")
  return (
    <>
      <textarea value={markdown} onChange={e => setMarkdown(e.target.value)} />
      <label>
        <input type="checkbox" checked={showPreview} onChange={e => setShowPreview(e.target.checked)} />
        Show preview
      </label>
      <hr />
      {showPreview && (
        <Suspense fallback={<Loading />}>
          <h2>Preview</h2>
          <MarkdownPreview markdown={markdown} />
          {/* ^ 実は、この JSX 式のぶんがレンダーされるときに始まる */}
        </Suspense>
      )}
    </>
  );
}

// Add a fixed delay so you can see the loading state
function delayForDemo(promise) {
  console.log("start loading")
  return new Promise(resolve => {
    setTimeout(resolve, 2000);
  }).then(() => promise);
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なので、

  • App.js が読み込まれる
  • App.js において、<MarkdownPreview /> がレンダーされる
  • MarkdownPreview.js のダウンロードが始まる

というウォーターフォールが発生してしまうので、それを避けたい、ということだと思うので、その訳文で問題ないと思います。


ただ、「コードがダウンロードされる間に並行してコードをフェッチ」は、それでもあと 30% ぐらいしっくり来ない…

downloading を「ダウンロードされる」ではなく「(何かを)ダウンロードしている」と訳すべきなのか…?

それとは別に、

  • 前者の「コードが」は「createBrowserRouter が書かれているような、ルーター設定側のコード」
  • 後者の「コードを」は、「そのファイルから参照されている、(lazy) な個別ルートのコード」

と解釈できなくもないですが、根拠がない…

Copy link
Member Author

@smikitky smikitky Jun 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これ分かりました。React Router の Router-level lazy ("Route.lazy") のメリットがよく分かっていなかったのですが、React-based lazyと比べた場合の最大の利点はルーティングがネストしている場合に並行ロードができる、という挙動のようですね。

https://remix.run/blog/lazy-loading-routes#introducing-routelazy

// Router-based lazy
const routes = [{
  path: '/',
  loader: () => getUser(),
  element: <Layout />,
  children: [{
    index: true,
    element: <Home />,
  }, {
    path: 'projects',
    lazy: () => import("./projects"), // 💤 Lazy load!
    children: [{
      path: ':projectId',
      lazy: () => import("./project"), // 💤 Lazy load!
    }],
  }],
}]

ちょっと前まではこういう場合、<Projects><Project> を愚直な React-based lazy で囲んでこう書いていたと思うのですが…

// React-based lazy
const Projects = React.lazy(() => import("./projects"));
const Project = React.lazy(() => import("./project"));

const routes = [{
  path: '/',
  loader: () => getUser(),
  element: <Layout />,
  children: [{
    index: true,
    element: <Home />,
  }, {
    path: 'projects',
    element: <Projects />,
    children: [{
      path: ':projectId',
      element: <Project />
    }],
  }],
}]

…これで /projects/123 にアクセスした場合、ProjectsProject のコンポーネントのコードがウォーターフォールでフェッチされてしまいます。が、Router-level lazy で定義されていれば、深いところに隠れている遅延ロードも(レンダーサイクルとは無関係な)ルータ本体のレベルで認識できるので、この2つのコード(上記の projects.jsxproject.jsx)を同時にフェッチできる、と。

(「コードと関連するデータ」間ではウォーターフォールが残っているので微妙ですが、少なくとも「2つのコード間」のウォーターフォールはないので、そこが良い、みたいな話)

なので意図を汲んで意訳するなら コードのダウンロード中に関連コード群を並行的にフェッチするためのルータ機能 としておくのが良いかなと思いました。直後のコードサンプルでは React-based lazy との違いが表現できてなくて微妙ですが…。

@smikitky

This comment was marked as outdated.

Copy link

vercel bot commented Apr 15, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
legacy-ja-reactjs-org ⬜️ Ignored (Inspect) Visit Preview Jun 16, 2025 7:29am


However, this requires correctly configuring the loaders in your app and trades off complexity for performance.
ただし、これにはアプリ内のローダを正しく設定する必要があり、パフォーマンスのために複雑さが犠牲になっています。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"trade off A (against | for) B" は、「B を得るために、A を得てしまうが、それを我慢する」みたいな語釈があるので、以下のように変えると少しの不自然さを解消できるかと思います。

https://dictionary.cambridge.org/ja/dictionary/english/trade-off

(ついでに、たぶん動詞 requires の目的節を、 文末の performance まで広げるのが正確かと思ったので、そのように語順を入れ替えました。)

Suggested change
ただし、これにはアプリ内のローダを正しく設定する必要があり、パフォーマンスのために複雑さが犠牲になっています
ただし、そのためには、アプリ内のローダを正しく設定することと、パフォーマンスのために複雑さを受け入れることが必要になります

Copy link
Member Author

@smikitky smikitky Jun 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「複雑さが犠牲になる」はシンプルに誤訳ですね、すみません。
ただこの文で並列されているのは requirestrades だと思います。configuringtrades が並列で requires の目的語となっている場合は、"this requires configuring ... and trading off complexity" になるはずです。以下でどうでしょう。

Suggested change
ただし、これにはアプリ内のローダを正しく設定する必要があり、パフォーマンスのために複雑さが犠牲になっています
ただし、このためにはアプリ内のローダを正しく設定する必要があり、パフォーマンスのために複雑さを受け入れていることになってしまいます


While server rendering can improve SEO, it also improves performance by reducing the amount of JavaScript the user needs to download and parse before they can see the content on the screen.
サーバレンダーは SEO も改善しますが、ユーザが画面上のコンテンツを見るためにダウンロード・パースする必要のある JavaScript の量を減らすことで、パフォーマンスも向上させるものです。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

原文では "before" を使っているので、「見れるようになるまでの間に…」のほうが良いと思います。

Suggested change
サーバレンダーは SEO も改善しますが、ユーザが画面上のコンテンツを見るためにダウンロード・パースする必要のある JavaScript の量を減らすことで、パフォーマンスも向上させるものです。
サーバレンダーは SEO も改善しますが、ユーザが画面上のコンテンツを見れるようになるまでの間にダウンロード・パースする必要のある JavaScript の量を減らすことで、パフォーマンスも向上させるものです。

Copy link
Member Author

@smikitky smikitky Jun 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

「見れる」は典型的 "ら抜き" 表現なので避けたいです。以下でどうでしょうか。

Suggested change
サーバレンダーは SEO も改善しますが、ユーザが画面上のコンテンツを見るためにダウンロード・パースする必要のある JavaScript の量を減らすことで、パフォーマンスも向上させるものです。
サーバレンダーは SEO も改善しますが、ユーザが画面上のコンテンツを見られるようになるまでにダウンロード・パースする必要のある JavaScript の量を減らすことで、パフォーマンスも向上させるものです。

「閲覧可能になるまで」とかでもいいです。


```txt
- core.js 25kb
- home.js 25kb
- dashboard.js 25kb
```

One way to do code-splitting is with `React.lazy`. However, this means that the code is not fetched until the component renders, which can cause network waterfalls. A more optimal solution is to use a router feature that fetches the code in parallel while the code is downloading. For example, React Router provides a `lazy` option to specify that a route should be code split and optimize when it is loaded:
コード分割を行う方法のひとつは、`React.lazy` を使用することです。しかし、この方法ではレンダーされる段階になって初めてコードが取得されるため、ネットワークウォーターフォールが発生する可能性があります。より良い解決策は、コードがダウンロードされる間に並行してコードをフェッチするためのルータ機能を使用することです。例えば、React Router `lazy` オプションを提供しており、これを使ってルートをコード分割対象として指定し、読み込みタイミングを最適化できます。
Copy link
Collaborator

@honey32 honey32 Jun 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

僕はてっきり「ファイルがロードされたら、即座に該当するチャンクのダウンロードをする」という動作だと思っていましたが、

https://ja.react.dev/reference/react/lazy を見た感じ、「MarkdownPreview初回レンダーしたときに はじめてチャンクのダウンロードが始まる」という挙動になるらしいです。

ローカルでは試していませんが、同ページにデモがあったので、そちらで確認できました。

import { useState, Suspense, lazy } from 'react';
import Loading from './Loading.js';

const MarkdownPreview = lazy(() => delayForDemo(import('./MarkdownPreview.js')));
// MarkdownPreview.js のダウンロードは、トップレベルでいきなり開始する……のではなく、

export default function MarkdownEditor() {
  const [showPreview, setShowPreview] = useState(false);
  const [markdown, setMarkdown] = useState('Hello, **world**!');

  console.log("render")
  return (
    <>
      <textarea value={markdown} onChange={e => setMarkdown(e.target.value)} />
      <label>
        <input type="checkbox" checked={showPreview} onChange={e => setShowPreview(e.target.checked)} />
        Show preview
      </label>
      <hr />
      {showPreview && (
        <Suspense fallback={<Loading />}>
          <h2>Preview</h2>
          <MarkdownPreview markdown={markdown} />
          {/* ^ 実は、この JSX 式のぶんがレンダーされるときに始まる */}
        </Suspense>
      )}
    </>
  );
}

// Add a fixed delay so you can see the loading state
function delayForDemo(promise) {
  console.log("start loading")
  return new Promise(resolve => {
    setTimeout(resolve, 2000);
  }).then(() => promise);
}


```txt
- core.js 25kb
- home.js 25kb
- dashboard.js 25kb
```

One way to do code-splitting is with `React.lazy`. However, this means that the code is not fetched until the component renders, which can cause network waterfalls. A more optimal solution is to use a router feature that fetches the code in parallel while the code is downloading. For example, React Router provides a `lazy` option to specify that a route should be code split and optimize when it is loaded:
コード分割を行う方法のひとつは、`React.lazy` を使用することです。しかし、この方法ではレンダーされる段階になって初めてコードが取得されるため、ネットワークウォーターフォールが発生する可能性があります。より良い解決策は、コードがダウンロードされる間に並行してコードをフェッチするためのルータ機能を使用することです。例えば、React Router `lazy` オプションを提供しており、これを使ってルートをコード分割対象として指定し、読み込みタイミングを最適化できます。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なので、

  • App.js が読み込まれる
  • App.js において、<MarkdownPreview /> がレンダーされる
  • MarkdownPreview.js のダウンロードが始まる

というウォーターフォールが発生してしまうので、それを避けたい、ということだと思うので、その訳文で問題ないと思います。


ただ、「コードがダウンロードされる間に並行してコードをフェッチ」は、それでもあと 30% ぐらいしっくり来ない…

downloading を「ダウンロードされる」ではなく「(何かを)ダウンロードしている」と訳すべきなのか…?

それとは別に、

  • 前者の「コードが」は「createBrowserRouter が書かれているような、ルーター設定側のコード」
  • 後者の「コードを」は、「そのファイルから参照されている、(lazy) な個別ルートのコード」

と解釈できなくもないですが、根拠がない…

Co-authored-by: honey32 <honey32@bearwapps.com>
@smikitky
Copy link
Member Author

@honey32 ありがとうございます、3箇所再チェックをお願いできますでしょうか

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants