You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jul 19, 2020. It is now read-only.
Copy file name to clipboardExpand all lines: src/README.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -40,10 +40,10 @@ Rust also helps developers write safer code with its rich type system and owners
40
40
41
41
#### Alternatives?
42
42
43
-
We love to share ideas with other projects and believe we can all help each other reach the full potential of this exciting new technology. If you're not into Yew, you may like the following projects\(listed alphabetically\)
43
+
We love to share ideas with other projects and believe we can all help each other reach the full potential of this exciting new technology. If you're not into Yew, you may like the following projects:
44
44
45
-
*[Draco](https://github.com/utkarshkukreti/draco) - _"A Rust library for building client side web applications with Web Assembly"_
46
45
*[Percy](https://github.com/chinedufn/percy) - _"A modular toolkit for building isomorphic web apps with Rust + WebAssembly"_
47
46
*[Seed](https://github.com/seed-rs/seed) - _"A Rust framework for creating web apps"_
48
-
*[Smithy](https://github.com/rbalicki2/smithy) - _"A framework for building WebAssembly apps in Rust"_
Copy file name to clipboardExpand all lines: src/advanced-topics/optimizations.md
+17-60Lines changed: 17 additions & 60 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,13 +6,9 @@ description: Make your app faster
6
6
7
7
## neq\_assign
8
8
9
-
When a component receives props from its parent component, the `change` method is called. This, in
10
-
addition to allowing you to update the component's state, also allows you to return a `ShouldRender`
11
-
boolean value that indicates if the component should re-render itself in response to the prop changes.
9
+
When a component receives props from its parent component, the `change` method is called. This, in addition to allowing you to update the component's state, also allows you to return a `ShouldRender` boolean value that indicates if the component should re-render itself in response to the prop changes.
12
10
13
-
Re-rendering is expensive, and if you can avoid it, you should. As a general rule, you only want to
14
-
re-render when the props actually changed. The following block of code represents this rule,
15
-
returning `true` if the props differed from the previous props:
11
+
Re-rendering is expensive, and if you can avoid it, you should. As a general rule, you only want to re-render when the props actually changed. The following block of code represents this rule, returning `true` if the props differed from the previous props:
16
12
17
13
```rust
18
14
useyew::ShouldRender;
@@ -36,68 +32,37 @@ impl Example {
36
32
}
37
33
```
38
34
39
-
But we can go further! This is six lines of boilerplate can be reduced down to one by using a trait
40
-
and a blanket implementation for anything that implements `PartialEq`. Check out the `yewtil` crate's
But we can go further! This is six lines of boilerplate can be reduced down to one by using a trait and a blanket implementation for anything that implements `PartialEq`. Check out the `yewtil` crate's `NeqAssign` trait [here](https://docs.rs/yewtil/*/yewtil/trait.NeqAssign.html).
42
36
43
37
## RC
44
38
45
-
In an effort to avoid cloning large chunks of data to create props when re-rendering, we can use
46
-
smart pointers to only clone the pointer instead. If you use `Rc<_>`s in your props and child
47
-
components instead of plain unboxed values, you can delay cloning until you need to modify the data
48
-
in the child component, where you use `Rc::make_mut` to clone and get a mutable reference to the data
49
-
you want to alter. By not cloning until mutation, child components can reject props identical to
50
-
their state-owned props in `Component::change` for almost no performance cost, versus the case where
51
-
the data itself needs to be copied into the props struct in the parent before it is compared and
52
-
rejected in the child.
39
+
In an effort to avoid cloning large chunks of data to create props when re-rendering, we can use smart pointers to only clone the pointer instead. If you use `Rc<_>`s in your props and child components instead of plain unboxed values, you can delay cloning until you need to modify the data in the child component, where you use `Rc::make_mut` to clone and get a mutable reference to the data you want to alter. By not cloning until mutation, child components can reject props identical to their state-owned props in `Component::change` for almost no performance cost, versus the case where the data itself needs to be copied into the props struct in the parent before it is compared and rejected in the child.
53
40
54
-
This optimization is most useful for data types that aren't `Copy`. If you can copy your data easily,
55
-
then it probably isn't worth putting it behind a smart pointer. For structures that can contain lots
56
-
of data like `Vec`, `HashMap`, and `String`, this optimization should be worthwhile.
41
+
This optimization is most useful for data types that aren't `Copy`. If you can copy your data easily, then it probably isn't worth putting it behind a smart pointer. For structures that can contain lots of data like `Vec`, `HashMap`, and `String`, this optimization should be worthwhile.
57
42
58
-
This optimization works best if the values are never updated by the children, and even better, if
59
-
they are rarely updated by parents. This makes `Rc<_>s` a good choice for wrapping property values in
60
-
for pure components.
43
+
This optimization works best if the values are never updated by the children, and even better, if they are rarely updated by parents. This makes `Rc<_>s` a good choice for wrapping property values in for pure components.
61
44
62
45
## View Functions
63
46
64
-
For code readability reasons, it often makes sense to migrate sections of `html!` to their own
65
-
functions so you can avoid the rightward drift present in deeply nested HTML.
47
+
For code readability reasons, it often makes sense to migrate sections of `html!` to their own functions so you can avoid the rightward drift present in deeply nested HTML.
66
48
67
49
## Pure Components/Function Components
68
50
69
-
Pure components are components that don't mutate their state, only displaying content and propagating
70
-
messages up to normal, mutable components. They differ from view functions in that they can be used
71
-
from within the `html!` macro using the component syntax \(`<SomePureComponent />`\) instead of
72
-
expression syntax \(`{some_view_function()}`\), and that depending on their implementation, they can
73
-
be memoized - preventing re-renders for identical props using the aforementioned `neq_assign` logic.
51
+
Pure components are components that don't mutate their state, only displaying content and propagating messages up to normal, mutable components. They differ from view functions in that they can be used from within the `html!` macro using the component syntax \(`<SomePureComponent />`\) instead of expression syntax \(`{some_view_function()}`\), and that depending on their implementation, they can be memoized - preventing re-renders for identical props using the aforementioned `neq_assign` logic.
74
52
75
53
Yew doesn't natively support pure or function components, but they are available via external crates.
76
54
77
-
Function components don't exist yet, but in theory, pure components could be generated by using proc
78
-
macros and annotating functions.
55
+
Function components don't exist yet, but in theory, pure components could be generated by using proc macros and annotating functions.
79
56
80
57
## Keyed DOM nodes when they arrive
81
58
82
59
## Compile speed optimizations using Cargo Workspaces
83
60
84
-
Arguably, the largest drawback to using Yew is the long time it takes to compile. Compile time seems
85
-
to correlate with the quantity of code found within `html!` macro blocks. This tends to not be a
86
-
significant problem for smaller projects, but for web apps that span multiple pages, it makes sense
87
-
to break apart your code across multiple crates to minimize the amount of work the compiler has to do
88
-
for each change made.
61
+
Arguably, the largest drawback to using Yew is the long time it takes to compile. Compile time seems to correlate with the quantity of code found within `html!` macro blocks. This tends to not be a significant problem for smaller projects, but for web apps that span multiple pages, it makes sense to break apart your code across multiple crates to minimize the amount of work the compiler has to do for each change made.
89
62
90
-
You should try to make your main crate handle routing/page selection, move all commonly shared code
91
-
to another crate, and then make a different crate for each page, where each page could be a different
92
-
component, or just a big function that produces `Html`. In the best case scenario, you go from
93
-
rebuilding all of your code on each compile to rebuilding only the main crate, and one of your page
94
-
crates. In the worst case, where you edit something in the "common" crate, you will be right back to
95
-
where you started: compiling all code that depends on that commonly shared crate, which is
96
-
probably everything else.
63
+
You should try to make your main crate handle routing/page selection, move all commonly shared code to another crate, and then make a different crate for each page, where each page could be a different component, or just a big function that produces `Html`. In the best case scenario, you go from rebuilding all of your code on each compile to rebuilding only the main crate, and one of your page crates. In the worst case, where you edit something in the "common" crate, you will be right back to where you started: compiling all code that depends on that commonly shared crate, which is probably everything else.
97
64
98
-
If your main crate is too heavyweight, or you want to rapidly iterate on a deeply nested page \(eg. a
99
-
page that renders on top of another page\), you can use an example crate to create a more simple
100
-
implementation of the main page and render your work-in-progress component on top of that.
65
+
If your main crate is too heavyweight, or you want to rapidly iterate on a deeply nested page \(eg. a page that renders on top of another page\), you can use an example crate to create a more simple implementation of the main page and render your work-in-progress component on top of that.
101
66
102
67
## Build size optimization
103
68
@@ -106,19 +71,13 @@ implementation of the main page and render your work-in-progress component on to
More information about code size profiling: [rustwasm book](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size)
111
75
112
76
### wee\_alloc
113
77
114
-
[wee\_alloc](https://github.com/rustwasm/wee_alloc) is a tiny allocator that is much smaller than the
115
-
allocator that is normally used in Rust binaries. Replacing the default allocator with this one will
116
-
result in smaller WASM file sizes, at the expense of speed and memory overhead.
78
+
[wee\_alloc](https://github.com/rustwasm/wee_alloc) is a tiny allocator that is much smaller than the allocator that is normally used in Rust binaries. Replacing the default allocator with this one will result in smaller WASM file sizes, at the expense of speed and memory overhead.
117
79
118
-
The slower speed and memory overhead are minor in comparison to the size gains made by not including
119
-
the default allocator. This smaller file size means that your page will load faster, and so it is
120
-
generally recommended that you use this allocator over the default, unless your app is doing some
121
-
allocation-heavy work.
80
+
The slower speed and memory overhead are minor in comparison to the size gains made by not including the default allocator. This smaller file size means that your page will load faster, and so it is generally recommended that you use this allocator over the default, unless your app is doing some allocation-heavy work.
122
81
123
82
```rust
124
83
// Use `wee_alloc` as the global allocator.
@@ -152,8 +111,7 @@ Further more it is possible to optimize size of `wasm` code.
The Rust Wasm book features a section about reducing the size of WASM binaries: [Shrinking .wasm size](https://rustwasm.github.io/book/game-of-life/code-size.html)
157
115
158
116
* using `wasm-pack` which by default optimizes `wasm` code in release builds
Copy file name to clipboardExpand all lines: src/concepts/agents.md
+19-24Lines changed: 19 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,16 +4,9 @@ description: Yew's Actor System
4
4
5
5
# Agents
6
6
7
-
Agents are similar to Angular's [Services](https://angular.io/guide/architecture-services)\(but
8
-
without dependency injection\), and provide a Yew with an
9
-
[Actor Model](https://en.wikipedia.org/wiki/Actor_model). Agents can be used to route messages
10
-
between components independently of where they sit in the component hierarchy, or they can be used to
11
-
create a shared state, and they can also be used to offload computationally expensive tasks from the
12
-
main thread which renders the UI. There is also planned support for using agents to allow Yew
13
-
applications to communicate across tabs \(in the future\).
7
+
Agents are similar to Angular's [Services](https://angular.io/guide/architecture-services)\(but without dependency injection\), and provide a Yew with an [Actor Model](https://en.wikipedia.org/wiki/Actor_model). Agents can be used to route messages between components independently of where they sit in the component hierarchy, or they can be used to create a shared state, and they can also be used to offload computationally expensive tasks from the main thread which renders the UI. There is also planned support for using agents to allow Yew applications to communicate across tabs \(in the future\).
In order for agents to run concurrently, Yew uses [web-workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers).
17
10
18
11
## Lifecycle
19
12
@@ -24,12 +17,19 @@ In order for agents to run concurrently, Yew uses
24
17
#### Reaches
25
18
26
19
* Context - There will exist at most one instance of a Context Agent at any given time. Bridges will
27
-
spawn or connect to an already spawned agent on the UI thread. This can be used to coordinate state
28
-
between components or other agents. When no bridges are connected to this agent, the agent will
29
-
disappear.
20
+
21
+
spawn or connect to an already spawned agent on the UI thread. This can be used to coordinate state
22
+
23
+
between components or other agents. When no bridges are connected to this agent, the agent will
24
+
25
+
disappear.
26
+
30
27
* Job - Spawn a new agent on the UI thread for every new bridge. This is good for moving shared but
31
-
independent behavior that communicates with the browser out of components. \(TODO verify\) When the
32
-
task is done, the agent will disappear.
28
+
29
+
independent behavior that communicates with the browser out of components. \(TODO verify\) When the
30
+
31
+
task is done, the agent will disappear.
32
+
33
33
* Public - Same as Context, but runs on its own web worker.
34
34
* Private - Same as Job, but runs on its own web worker.
35
35
* Global \(WIP\)
@@ -38,24 +38,19 @@ task is done, the agent will disappear.
38
38
39
39
### Bridges
40
40
41
-
A bridge allows bi-directional communication between an agent and a component. Bridges also allow
42
-
agents to communicate with one another.
41
+
A bridge allows bi-directional communication between an agent and a component. Bridges also allow agents to communicate with one another.
43
42
44
43
### Dispatchers
45
44
46
-
A dispatcher allows uni-directional communication between a component and an agent. A dispatcher
47
-
allows a component to send messages to an agent.
45
+
A dispatcher allows uni-directional communication between a component and an agent. A dispatcher allows a component to send messages to an agent.
48
46
49
47
## Overhead
50
48
51
-
Agents that live in their own separate web worker (Private and Public) incur serialization overhead
52
-
on the messages they send and receive. They use [bincode](https://github.com/servo/bincode) to
53
-
communicate with other threads, so the cost is substantially higher than just calling a function.
54
-
Unless the cost of computation will outweigh the cost of message passing, you should contain your
55
-
logic in the UI thread agents (Job or Context).
49
+
Agents that live in their own separate web worker \(Private and Public\) incur serialization overhead on the messages they send and receive. They use [bincode](https://github.com/servo/bincode) to communicate with other threads, so the cost is substantially higher than just calling a function. Unless the cost of computation will outweigh the cost of message passing, you should contain your logic in the UI thread agents \(Job or Context\).
56
50
57
51
## Further reading
58
52
59
53
* The [pub\_sub](https://github.com/yewstack/yew/tree/master/examples/pub_sub) example shows how
60
-
components can use agents to communicate with each other.
54
+
55
+
components can use agents to communicate with each other.
0 commit comments