Skip to content

Commit

Permalink
docs: made general improvements (#180)
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Russell <git@ryanrussell.org>

Signed-off-by: Ryan Russell <git@ryanrussell.org>
  • Loading branch information
ryanrussell authored Aug 28, 2022
1 parent fb00daf commit 1def873
Show file tree
Hide file tree
Showing 12 changed files with 17 additions and 17 deletions.
2 changes: 1 addition & 1 deletion docs/0.3.4/en-US/reference/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ However, Perseus exports a macro called `web_log!` that can be used to print to

## Debugging the build process

If you have a problem in your build process, you'll probably notice quite quickly that you can't see any `dbg!`, `println!`, or `web_log!` calls in your terminal when you run `perseus serve` (or `export`, `build`, etc.). This is because the CLI hides the output of the commands that it runs behind the scenes (if you've ever had the CLI spout an error at you and show you everything it's done behind the scenes, you'll probably understand why!). As useful as this is for simple usability, it can be extremely annoying for loggin, so the CLI provides a separate command `perseus snoop <process>`, which allows you to run one of the commands that the CLI does, directly. Usually, this will be `perseus snoop build`, though you can also use `perseus snoop wasm-build` if you're having an issue in your Wasm building (usually caused by a crate that can't work in the browser), or `perseus snoop serve` if you're getting errors on the server (which shouldn't happen unless you've modified it). To learn more, see [this page](:reference/snooping).
If you have a problem in your build process, you'll probably notice quite quickly that you can't see any `dbg!`, `println!`, or `web_log!` calls in your terminal when you run `perseus serve` (or `export`, `build`, etc.). This is because the CLI hides the output of the commands that it runs behind the scenes (if you've ever had the CLI spout an error at you and show you everything it's done behind the scenes, you'll probably understand why!). As useful as this is for simple usability, it can be extremely annoying for logging, so the CLI provides a separate command `perseus snoop <process>`, which allows you to run one of the commands that the CLI does, directly. Usually, this will be `perseus snoop build`, though you can also use `perseus snoop wasm-build` if you're having an issue in your Wasm building (usually caused by a crate that can't work in the browser), or `perseus snoop serve` if you're getting errors on the server (which shouldn't happen unless you've modified it). To learn more, see [this page](:reference/snooping).
4 changes: 2 additions & 2 deletions docs/0.3.4/en-US/reference/deploying/size.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

If you're used to working with Rust, you're probably used to two things: performance is everything, and Rust produces big binaries. With Wasm, these actually become problems because of the way the web works. If you think about it, your Wasm files (big because Rust optimizes for speed instead of size by default) need to be sent to browsers. So, the larger they are, the slower your site will be (because it'll take longer to load). Fortunately, Perseus only makes this relevant when a user first navigates to your site with its [subsequent loads](:advanced/subsequent-loads) system. However, it's still worth optimizing code size in places.

Before we go any further though, it's worth addressing a common misconception about Wasm. The size of the final Wasm bianry for the Perseus basic example is usually around 200-300kB (this of course changes over time), which would be utterly unacceptable with JavaScript, but this would be considered about normal for an image. It's common to compare Wasm file sizes to JS file sizes, but Wasm is actually much similar to an image, because, unlike with JS, the browser can instantiate it much more quickly because it's already been compiled. This is a complex topic, but the general idea is that Wasm file sizes are better compared to image file sizes than to JS file sizes. You can read more about this [here](https://hacks.mozilla.org/2018/01/making-webassembly-even-faster-firefoxs-new-streaming-and-tiering-compiler/).
Before we go any further though, it's worth addressing a common misconception about Wasm. The size of the final Wasm binary for the Perseus basic example is usually around 200-300kB (this of course changes over time), which would be utterly unacceptable with JavaScript, but this would be considered about normal for an image. It's common to compare Wasm file sizes to JS file sizes, but Wasm is actually much similar to an image, because, unlike with JS, the browser can instantiate it much more quickly because it's already been compiled. This is a complex topic, but the general idea is that Wasm file sizes are better compared to image file sizes than to JS file sizes. You can read more about this [here](https://hacks.mozilla.org/2018/01/making-webassembly-even-faster-firefoxs-new-streaming-and-tiering-compiler/).

Now onto the optimizations. If you've worked with Rust and Wasm before, you may be familiar with `wasm-opt`, which performs a ton of optimizations for you. Perseus does this automatically with `wasm-pack`. But we can do better.

The easiest way to apply size optimizations for Perseus is the [`perseus-size-opt` plugin](https://github.com/arctic-hen7/perseus-size-opt), which prevents the need for ejecting to apply optimizations in `.perseus/`, and requires only a single line of code to use. Check it out [here](https://github.com/arctic-hen7/perseus-size-opt) for more details! It's recommended that all Perseus apps use this plugin before they deploy to production, because it can result in size decreases of upwards of 100kb, which translates into real increases in loading time for your users.

*Note: every size optimization has a trade-off with either speed or compile-time, and you should test the performance of your app after applying these optimizations to make sure you're happy with the results, because the balance between speed and size will be different for every app. That said, using even all these optimizations usually has a negligible performance impact.*

Usually, this will be enough for most apps, though, if you really want to cut down a few kilobytes, you can use `default-features = false` on the `perseus` dependency in your `Cargo.toml` to deactivate [live reloading](:reference/live-reloading) and [HSR](:reference/state/hsr). These don't *do* anything in production, though they do have a very slight code footprint, which can be elimimated by entirely disabling their features (`live-reloading` and `hsr`, which are enabled by default). Note that you'll probably only want to do this in production, as using this setting will disable these features in development as well. Note though that this will usually only remove fewer than 5kB from your final bundle (sometimes less).
Usually, this will be enough for most apps, though, if you really want to cut down a few kilobytes, you can use `default-features = false` on the `perseus` dependency in your `Cargo.toml` to deactivate [live reloading](:reference/live-reloading) and [HSR](:reference/state/hsr). These don't *do* anything in production, though they do have a very slight code footprint, which can be eliminated by entirely disabling their features (`live-reloading` and `hsr`, which are enabled by default). Note that you'll probably only want to do this in production, as using this setting will disable these features in development as well. Note though that this will usually only remove fewer than 5kB from your final bundle (sometimes less).
2 changes: 1 addition & 1 deletion docs/0.3.4/en-US/reference/engines.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Engines

Perseus' plugins system aims to enable extrreme extensibility of Perseus to support niche use-cases, but it can't do everything. Occasionally, a problem is best solved by rewriting significant parts of the contents of `.perseus/`. These contents constitute Perseus' *engine*, the thing that ties together all the code exposed by the various Perseus libraries into an app. As mentioned before, the engine actually takes in your app's code as a library and produces a final app based on it (so technically, the engine is your *app* in the strictest sense, you provide the details).
Perseus' plugins system aims to enable extreme extensibility of Perseus to support niche use-cases, but it can't do everything. Occasionally, a problem is best solved by rewriting significant parts of the contents of `.perseus/`. These contents constitute Perseus' *engine*, the thing that ties together all the code exposed by the various Perseus libraries into an app. As mentioned before, the engine actually takes in your app's code as a library and produces a final app based on it (so technically, the engine is your *app* in the strictest sense, you provide the details).

The Perseus CLI comes bundled with the default Perseus engine, but, be it for experimentation of necessary workarounds, it also supports using custom engines by providing the `-e` option at the top level (that is, `perseus -e <engine> serve` or similar). The value of this should be a URL to a Git repository available online, and a branch name can be optionally supplied after an `@` at the end (e.g. `https://github.com/user/repo@v3.0.1`). The URL provided should be one that can be put into the `git clone` command, and the branch (if provided) must be available on the repository. If you're routinely using an alternative engine, it's best for convenience to alias the `perseus` command to `perseus -e <custom-engine-url>` on your system.

Expand Down
4 changes: 2 additions & 2 deletions docs/0.3.4/en-US/reference/hydration.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

In the examples of `Cargo.toml` files shown thus far, we've enabled a feature called `hydrate` on Perseus. This feature controls _hydration_, which is a way of making your app more performant. To explain it, we'll need to go a little in-depth.

Perseus uses server-side rendering of some kind for almost everything. In fact, unless you explicitly make something only run in the browser, Perseus will try to prerender it on the server first, either at build-time (faster, so Perseus does this for everything it can) or at request-time. This prerendering process yields a series of HTML and JSON fiels that make up the markup and state of your app. When a page is requested by a user, Perseus can serve them these files, and then the app shell (the Wasm code that runs everything in a Perseus app in the browser) will bring everything to life.
Perseus uses server-side rendering of some kind for almost everything. In fact, unless you explicitly make something only run in the browser, Perseus will try to prerender it on the server first, either at build-time (faster, so Perseus does this for everything it can) or at request-time. This prerendering process yields a series of HTML and JSON fields that make up the markup and state of your app. When a page is requested by a user, Perseus can serve them these files, and then the app shell (the Wasm code that runs everything in a Perseus app in the browser) will bring everything to life.

Those prerendered files can be imagined as solid iron, but, to make your app work, we need molten iron. In the real world, you need a lot of heat to turn iron into a liquid, and you need a lot of code to turn simple markup into interactive buttons and text in a browser! So, let's go through the metaphor a bit more: the build process and server are the miners that fetch all the iron out of the mines of the tempalte code you write. Then, that iron is sent to the user's browser, and the app shell does _something_ to get molten iron that can be used to run your app.
Those prerendered files can be imagined as solid iron, but, to make your app work, we need molten iron. In the real world, you need a lot of heat to turn iron into a liquid, and you need a lot of code to turn simple markup into interactive buttons and text in a browser! So, let's go through the metaphor a bit more: the build process and server are the miners that fetch all the iron out of the mines of the template code you write. Then, that iron is sent to the user's browser, and the app shell does _something_ to get molten iron that can be used to run your app.

Without hydration, the app shell will kindly thank the server for sending it the solid iron, and will then proceed to mine more of its own. In other words, the app shell will completely ignore the prerendered files that the server has sent (displaying them only until it's ready, which is why Perseus apps still work without JavaScript!).

Expand Down
2 changes: 1 addition & 1 deletion docs/0.3.4/en-US/reference/i18n/defining.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The first part of setting up i18n in Perseus is to state that your app uses it,
{{#include ../../../../examples/core/i18n/src/lib.rs}}
```

There are two paremeters to the `.locales()` function: the default locale for your app, and then any other locales it supports (other than the default). Each of these locales should be specified in the form `xx-XX`, where `xx` is the language code (e.g. `en` for English, `fr` for French, `la` for Latin) and `XX` is the region code (e.g. `US` for United States, `GB` for Great Britain, `CN` for China).
There are two parameters to the `.locales()` function: the default locale for your app, and then any other locales it supports (other than the default). Each of these locales should be specified in the form `xx-XX`, where `xx` is the language code (e.g. `en` for English, `fr` for French, `la` for Latin) and `XX` is the region code (e.g. `US` for United States, `GB` for Great Britain, `CN` for China).

## Routing

Expand Down
2 changes: 1 addition & 1 deletion docs/0.3.4/en-US/reference/index-view.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The Index View

In most Perseus apps, you can just ofcus on building your app's templates, and leave the boilerplate entirely to the Perseus engine, but sometimes that isn't quite sufficient, like if you want to use one stylesheet across your entire app. In traditional architectures, these are the kinds of modifications you might make to an `index.html` file that a framework inserts itself into, and you can do exactly this with Perseus! If you provide an `index.html` file in the root of your porject (not inside `src/`), Perseus will insert itself into that!
In most Perseus apps, you can just focus on building your app's templates, and leave the boilerplate entirely to the Perseus engine, but sometimes that isn't quite sufficient, like if you want to use one stylesheet across your entire app. In traditional architectures, these are the kinds of modifications you might make to an `index.html` file that a framework inserts itself into, and you can do exactly this with Perseus! If you provide an `index.html` file in the root of your project (not inside `src/`), Perseus will insert itself into that!

However, if you're using Perseus, you probably don't want to be writing HTML right? You're supposed to be using Sycamore! Well, that's completely true, and so Perseus supports creating an index view with Sycamore code! You can do this like so:

Expand Down
2 changes: 1 addition & 1 deletion docs/0.3.4/en-US/reference/pitfalls-and-bugs.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ If you add `default-features = false` to your `Cargo.toml` and expect Perseus to

If you've tried to download the bleeding-edge version of the CLI with `cargo install`, using a Git dependency on the `perseus-cli` package, you've probably been hit with a whole host of errors that don't make a whole lot of sense! The reason for this is that the Perseus CLI depends on including a folder that's not checked into Git (the engine, `.perseus/`, but transformed in various ways). That means that, to build the CLI, you need to have that folder available, which `cargo install` isn't smart enough to do yet from a Git dependency.

The way you get around this is unfortunately inconvenient, you'll have to manually clone the whole Perseus repository and then build the CLI yourself. You can do that by running `bonnie setup` in the root of the Perseus repo (after you've cloned it), and then you can build the binary in `packages/perseus-cli/` -- that will give you a copy of the CLI in `target/`! Be warned though that ussing the bleeding-edge CLI is generally not recommended, as the interdependencies in the engine can be quite fragile, and even the smallest changes that aren't breaking usually can be breaking when you're using the bleeding-edge version of the CLI with a released version of Perseus.
The way you get around this is unfortunately inconvenient, you'll have to manually clone the whole Perseus repository and then build the CLI yourself. You can do that by running `bonnie setup` in the root of the Perseus repo (after you've cloned it), and then you can build the binary in `packages/perseus-cli/` -- that will give you a copy of the CLI in `target/`! Be warned though that using the bleeding-edge CLI is generally not recommended, as the interdependencies in the engine can be quite fragile, and even the smallest changes that aren't breaking usually can be breaking when you're using the bleeding-edge version of the CLI with a released version of Perseus.

## Hydration doesn't work with X

Expand Down
2 changes: 1 addition & 1 deletion docs/0.3.4/en-US/reference/plugins/using.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ In addition to the usual `PerseusApp` setup, this also uses the `.plugins()` fun

To register a plugin, we use the `.plugin()`/`.plugin_with_client_privilege()` function on `Plugins`, which takes two parameters: the plugin's definition (a `perseus::plugins::Plugin`) and any data that should be provided to the plugin. The former should be exported from the plugin's crate, and the latter you'll need to provide based on the plugin's documentation. Note that plugins can accept almost anything as data (specifically, anything that can be expressed as `dyn Any`).

Plugins in Perseus are fantastic, but they're also a great way to increase your Wasm bundle size, which will make your website slower to laod when users first visit it. To mitigate this, Perseus lets plugin authors define where their plugins should run: in the browser (`PluginEnv::Client`), on the server-side (`PluginEnv::Server`), or on both (`PluginEnv::Both`). Plugins that only run on the server-side should be registered with `.plugin()`, and they will not be included in your final Wasm binary, which keeps your website nimble. If a plugin does need to run on the client though, it can be registered with `.plugin_with_client_privilege()` instead, which is named separately for conditional compilation reasons as well as to create a clear separation. But don't worry, if you accidentally register a plugin with the wrong function, your app won'y build, and Perseus will tell you that you've used the wrong function.
Plugins in Perseus are fantastic, but they're also a great way to increase your Wasm bundle size, which will make your website slower to load when users first visit it. To mitigate this, Perseus lets plugin authors define where their plugins should run: in the browser (`PluginEnv::Client`), on the server-side (`PluginEnv::Server`), or on both (`PluginEnv::Both`). Plugins that only run on the server-side should be registered with `.plugin()`, and they will not be included in your final Wasm binary, which keeps your website nimble. If a plugin does need to run on the client though, it can be registered with `.plugin_with_client_privilege()` instead, which is named separately for conditional compilation reasons as well as to create a clear separation. But don't worry, if you accidentally register a plugin with the wrong function, your app won'y build, and Perseus will tell you that you've used the wrong function.
Loading

0 comments on commit 1def873

Please sign in to comment.