Skip to content

Commit

Permalink
Archive the documents.
Browse files Browse the repository at this point in the history
  • Loading branch information
langyo committed Oct 13, 2024
1 parent 029fe73 commit 586484d
Show file tree
Hide file tree
Showing 122 changed files with 11,861 additions and 0 deletions.
86 changes: 86 additions & 0 deletions website/i18n/ja/docusaurus-plugin-content-docs/version-0.22.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{
"version.label": {
"message": "Next",
"description": "The label for version current"
},
"sidebar.docs.category.Getting Started": {
"message": "Getting Started",
"description": "The label for category Getting Started in sidebar docs"
},
"sidebar.docs.category.Concepts": {
"message": "Concepts",
"description": "The label for category Concepts in sidebar docs"
},
"sidebar.docs.category.Concepts.link.generated-index.title": {
"message": "Yew concepts",
"description": "The generated-index page title for category Concepts in sidebar docs"
},
"sidebar.docs.category.Concepts.link.generated-index.description": {
"message": "Learn about the important Yew concepts!",
"description": "The generated-index page description for category Concepts in sidebar docs"
},
"sidebar.docs.category.HTML": {
"message": "HTML",
"description": "The label for category HTML in sidebar docs"
},
"sidebar.docs.category.Components": {
"message": "Function Components",
"description": "The label for category Components in sidebar docs"
},
"sidebar.docs.category.Advanced topics": {
"message": "Advanced topics",
"description": "The label for category Advanced topics in sidebar docs"
},
"sidebar.docs.category.Advanced topics.link.generated-index.title": {
"message": "Advanced topics",
"description": "The generated-index page title for category Advanced topics in sidebar docs"
},
"sidebar.docs.category.Advanced topics.link.generated-index.description": {
"message": "Learn about the advanced topics and inner workings of Yew!",
"description": "The generated-index page description for category Advanced topics in sidebar docs"
},
"sidebar.docs.category.More": {
"message": "More",
"description": "The label for category More in sidebar docs"
},
"sidebar.docs.category.More.link.generated-index.title": {
"message": "Miscellaneous",
"description": "The generated-index page title for category More in sidebar docs"
},
"sidebar.docs.category.Migration guides": {
"message": "Migration guides",
"description": "The label for category Migration guides in sidebar docs"
},
"sidebar.docs.category.yew": {
"message": "yew",
"description": "The label for category yew in sidebar docs"
},
"sidebar.docs.category.yew-agent": {
"message": "yew-agent",
"description": "The label for category yew-agent in sidebar docs"
},
"sidebar.docs.category.yew-router": {
"message": "yew-router",
"description": "The label for category yew-router in sidebar docs"
},
"sidebar.docs.category.Using Basic Web Technologies In Yew": {
"message": "Intro With Basic Web Technologies",
"description": "The label for category Using Basic Web Technologies In Yew in sidebar docs"
},
"sidebar.docs.category.Using Basic Web Technologies In Yew.link.generated-index.title": {
"message": "Yew Take on Basic Web Technologies",
"description": "The generated-index page title for category Using Basic Web Technologies In Yew in sidebar docs"
},
"sidebar.docs.category.Using Basic Web Technologies In Yew.link.generated-index.description": {
"message": "Yew mostly operates on the idea of keeping everything that a reusable piece of UI may need, in one place - rust files. But also seeks to stay close to the original look of the technology. Explore further to fully grasp what we mean by these statements:",
"description": "The generated-index page description for category Using Basic Web Technologies In Yew in sidebar docs"
},
"sidebar.docs.category.Hooks": {
"message": "Hooks",
"description": "The label for category Hooks in sidebar docs"
},
"sidebar.docs.category.Struct Components": {
"message": "Struct Components",
"description": "The label for category Struct Components in sidebar docs"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: How it works
description: Low level details about the framework
---

# 低レベルなライブラリの中身

コンポーネントのライフサイクルの状態機械、VDOM の異なるアルゴリズム
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
---
title: Optimizations
description: Make your app faster
---

# 最適化とベストプラクティス

## neq_assign

親コンポーネントから props を受け取った際、`change`メソッドが呼ばれます。
これはコンポーネントの状態を更新することができるのに加え、コンポーネントが props が変わった際に再レンダリングするかどうかを決める
`ShouldRender`という真偽値を返すことができます。

再レンダリングはコストがかかるもので、もし避けられるのであれば避けるべきです。
一般的なルールとして props が実際に変化した際にのみ再レンダリングすれば良いでしょう。
以下のコードブロックはこのルールを表しており、props が前と変わったときに`true`を返します。

```rust
use yew::ShouldRender;

#[derive(PartialEq)]
struct ExampleProps;

struct Example {
props: ExampleProps,
};

impl Example {
fn change(&mut self, props: ExampleProps) -> ShouldRender {
if self.props != props {
self.props = props;
true
} else {
false
}
}
}
```

しかし我々は先に進んでいけます!
この 6 行のボイラープレードは`PartialEq`を実装したものにトレイトとブランケットを用いることで 1 行のコードへと落とし込むことができます。
[こちら](https://docs.rs/yewtil/*/yewtil/trait.NeqAssign.html)にて`yewtil`クレートの`NewAssign`トレイトを見てみてください。

## 効果的にスマートポインタを使う

**注意: このセクションで使われている用語がわからなければ Rust book は
[スマートポインタについての章](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html)
があり、非常に有用です。**

再レンダリングの際に props を作るデータを大量にコピーしないために、スマートポインタを用いてデータ自体ではなくデータへの参照だけを
コピーできます。
props や子コンポーネントで関連するデータに実データではなく参照を渡すと、子コンポーネントでデータを変更する必要がなければ
データのコピーを避けることができます。
その際、`Rc::make_mut`によって変更したいデータの変更可能な参照を得ることができます。

これにより、props が変更されたときにコンポーネントが再レンダリングされるかどうかを決めるかで`Component::change`に更なる恩恵があります。
なぜなら、データの値を比較する代わりに元々のポインタのアドレス (つまりデータが保管されている機械のメモリの場所) を比較できるためです。
2 つのポインターが同じデータを指す場合、それらのデータの値は同じでなければならないのです。
ただし、その逆は必ずしも成り立たないことに注意してください!
もし 2 つのポインタが異なるのであれば、そのデータは同じである可能性があります。
この場合はデータを比較するべきでしょう。

この比較においては`PartialEq`ではなく`Rc::ptr_eq`を使う必要があります。
`PartialEq`は等価演算子`==`を使う際に自動的に使われます。
Rust のドキュメントには[`Rc::ptr_eq`についてより詳しく書いてあります](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.ptr_eq)

この最適化は`Copy`を実装していないデータの型に対して極めて有効なものです。
もしデータを簡単に変更できるのであれば、スマートポインタに取り換える必要はありません。
しかし`Vec``HashMap``String`などのような重たいデータの構造体に対してはスマートポインタを使うことで
パフォーマンスを改善することができるでしょう。

この最適化は値がまだ一度も子によって更新されていない場合に極めて有効で、親からほとんど更新されない場合においてもかなり有効です。
これにより、`Rc<_>s`が純粋なコンポーネントに対してプロパティの値をラップする良い一手となります。

## View 関数

コードの可読性の理由から`html!`の部分を関数へと移植するのは意味があります。
これは、インデントを減らすのでコードを読みやすくするだけでなく、良いデザインパターンを産むことにも繋がるのです。
これらの関数は複数箇所で呼ばれて書くべきコード量を減らせるため、分解可能なアプリケーションを作ることができるのです。

## 純粋なコンポーネント

純粋なコンポーネントは状態を変化せず、ただ中身を表示してメッセージを普通の変更可能なコンポーネントへ渡すコンポーネントのことです。
View 関数との違いとして、純粋なコンポーネントは式の構文\(`{some_view_function()}`\)ではなく
コンポーネントの構文\(`<SomePureComponent />`\)を使うことで`html!`マクロの中で呼ばれる点、
そして実装次第で記憶され (つまり、一度関数が呼ばれれば値は"保存"され、
同じ引数でもう一度呼ばれても値を再計算する必要がなく最初に関数が呼ばれたときの保存された値を返すことができる)、
先述の`neq_assign`ロジックを使う別々の props で再レンダリングを避けられる点があります。

Yew は純粋な関数やコンポーネントをサポートしていませんが、外部のクレートを用いることで実現できます。

## 関数型コンポーネント (a.k.a フック)

関数型コンポーネントはまだ開発中です!
開発状況については[プロジェクトボード](https://github.com/yewstack/yew/projects/3)に詳しく書いてあります。

## キー付き DOM ノード

## ワークスペースでコンパイル時間を減らす

間違いなく Yew を使う上での最大の欠点はコンパイルに時間がかかる点です。
プロジェクトのコンパイルにかかる時間は`html!`マクロに渡されるコードの量に関係しています。
これは小さなプロジェクトにはそこまで問題ないようですが、大きなアプリではコードを複数クレートに分割することでアプリに変更が加られた際に
コンパイラの作業量を減らすのが有効です。

一つ可能なやり方として、ルーティングとページ洗濯を担当するメインのクレートを作り、それぞれのページに対して別のクレートを作ることです。
そうして各ページは異なるコンポーネントか、`Html`を生成する大きな関数となります。
アプリの異なる部分を含むクレート同士で共有されるコードはプロジェクト全体で依存する分離したクレートに保存されます。
理想的には 1 回のコンパイルでコード全てを再ビルドせずメインのクレートかどれかのページのクレートを再ビルドするだけにすることです。
最悪なのは、"共通"のクレートを編集して、はじめに戻ってくることです:
共有のクレートに依存している全てのコード、恐らく全てのコードをコンパイルすることです。

もしメインのクレートが重たすぎる、もしくは深くネストしたページ (例えば別ページのトップでレンダリングされるページ)
で速く繰り返したい場合、クレートの例を用いてメインページの実装をシンプルにしたりトップで動かしているコンポーネントをレンダリングできます。

## バイナリサイズを小さくする

- Rust のコードを最適化する
- `cargo.toml` \( release profile を定義 \)
- `wasm-opt`を用いて wasm のコードを最適化する

**注意: バイナリサイズを小さくするのについては[Rust Wasm Book](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size)に詳しく書いてあります。**

### Cargo.toml

`Cargo.toml``[profile.release]`のセクションに設定を書き込むことでリリースビルドを小さくすることが可能です。

```text
[profile.release]
# バイナリに含むコードを少なくする
panic = 'abort'
# コードベース全体での最適化 ( 良い最適化だがビルドが遅くなる)
codegen-units = 1
# サイズの最適化( よりアグレッシブに )
opt-level = 'z'
# サイズの最適化
# opt-level = 's'
# プログラム全体の分析によるリンク時最適化
lto = true
```

### wasm-opt

更に`wasm`のコードのサイズを最適化することができます。

The Rust Wasm Book には Wasm バイナリのサイズを小さくすることについてのセクションがあります:
[Shrinking .wasm size](https://rustwasm.github.io/book/game-of-life/code-size.html)

- `wasm-pack`でデフォルトの`wasm`のコードをリリースビルド時に最適化する
- `wasm-opt`によって直接`wasm`ファイルを最適化する

```text
wasm-opt wasm_bg.wasm -Os -o wasm_bg_opt.wasm
```

#### yew/examples/にある例を小さなサイズでビルドする

注意: `wasm-pack`は Rust と Wasm のコードへの最適化を組み合わせます。`wasm-bindgen`はこの例では Rust のサイズ最適化を用いていません。

| 使用したツール | サイズ |
| :-------------------------- | :----- |
| wasm-bindgen | 158KB |
| wasm-bindgen + wasm-opt -Os | 116KB |
| wasm-pack | 99 KB |

## 参考文献:

- [The Rust Book のスマートポインタに関する章](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html)
- [the Rust Wasm Book でのバイナリサイズを小さくすることについて](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size)
- [Rust profiles についてのドキュメント](https://doc.rust-lang.org/cargo/reference/profiles.html)
- [binaryen プロジェクト](https://github.com/WebAssembly/binaryen)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: Callbacks
description: ComponentLink and Callbacks
---

”リンク”コンポーネントはコンポーネントがコールバックを登録できて自身を更新することができるメカニズムです。

## ComponentLink API

### callback

実行時にコンポーネントの更新メカニズムにメッセージを送信するコールバックを登録します。
これは、渡されたクロージャから返されるメッセージで `send_self` を呼び出します。
`Fn(IN) -> Vec<COMP::Message>`が渡され、`Callback<IN>`が返されます。

### send_message

現在のループが終了した直後にコンポーネントにメッセージを送信し、別の更新ループを開始します。

### send_message_batch

実行時に一度に多数のメッセージを一括して送信するコールバックを登録します。
メッセージによってコンポーネントが再レンダリングされる場合、バッチ内のすべてのメッセージが処理された後、コンポーネントは再レンダリングされます。
`Fn(IN) -> COMP::Message`が渡され、`Callback<IN>`が返されます。

## コールバック

_\(This might need its own short page.\)_

コールバックは、Yew 内のサービス、エージェント、親コンポーネントとの通信に使われます。
これらは単に `Fn``Rc` でラップしただけであり、クローンを作成できるようにするためのものです。

これらの関数には `emit` 関数があり、`<IN>` 型を引数に取り、それをアドレスが欲しいメッセージに変換します。
親からのコールバックが子コンポーネントに props で提供されている場合、子は `update` ライフサイクルフックで `emit` をコールバックに呼び出して親にメッセージを返すことができます。
マクロ内で props として提供されたクロージャや関数は自動的にコールバックに変換されます。
Loading

0 comments on commit 586484d

Please sign in to comment.