-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added page state store caching, preloading, and memory manageme…
…nt (#204) * feat: added eviction to the pss This should fix any memory blowouts (not leaks, just the storage of every single page's state can get a bit heavy), which occasionally occurred in development. * chore: clarified a comment * feat: created facility to support storage of document metadata in pss * feat: prevented network requests for cached head/state After a page is fetched as a subsequent load, it won't be fetched again until the PSS fills up! This doesn't work with initial loads, since the head is pre-interpolated (and I don't want to increase the bundle size by doubling it up in a variable; reading from the HTML is unreliable since JS will likely have already modified it). * feat: added preloading infrastructure This has involved making `RenderCtx` hold much more data in the browser, like the error pages and render context, though this should make routing much lighter. * fix: fixed longstanding clones in app route system Apparently, it's perfectly valid to pass the Sycamore scope through to the Sycamore router, which means we an access everything we need from the render context! (I reckon there'll be a performance improvement to moving the render context into a dedicated system though, beyond Sycamore's context.) * refactor: removed unnecessary if clause in fetching example I think this led to some confusion the other day, so it's clarified now. Just that we don't need `G::IS_BROWSER` if we're target-gating as well. * feat: created user-facing preload system This includes a new `core/preload` example. * chore: applied #212 fix to new `preload` example * feat: added initially loaded page caching This is achieved through an extra `<meta>` delimiter that denotes the end of the `<head>`, which should be pretty reliable at getting what the user intended. * feat: added feature to control initial page caching Advanced `<head>` manipulations *could* in rare cases lead to bugs, so the user can turn this off if necessary, and it's documented in the FAQ section.
- Loading branch information
1 parent
39501dc
commit 0c4fa6b
Showing
28 changed files
with
1,065 additions
and
340 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
dist/ | ||
target_engine/ | ||
target_wasm/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
[package] | ||
name = "perseus-example-preload" | ||
version = "0.4.0-beta.10" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
perseus = { path = "../../../packages/perseus", features = [ "hydrate" ] } | ||
sycamore = "^0.8.1" | ||
serde = { version = "1", features = ["derive"] } | ||
serde_json = "1" | ||
|
||
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] | ||
fantoccini = "0.17" | ||
|
||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] | ||
tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } | ||
## **WARNING!** Before running this example outside the Perseus repo, replace the below line with | ||
## the one commented out below it (changing the path dependency to the version you want to use) | ||
perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } | ||
# perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dlft-server" ] } | ||
|
||
[target.'cfg(target_arch = "wasm32")'.dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Preload Example | ||
|
||
This example demonstrates Perseus' inbuilt imperative preloading functionality, which allows downloading all the assets needed to render a page ahead-of-time, so that, when the user reaches that page, they can go to it without any network requests being needed! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
use perseus::{ErrorPages, Html}; | ||
use sycamore::view; | ||
|
||
pub fn get_error_pages<G: Html>() -> ErrorPages<G> { | ||
let mut error_pages = ErrorPages::new( | ||
|cx, url, status, err, _| { | ||
view! { cx, | ||
p { (format!("An error with HTTP code {} occurred at '{}': '{}'.", status, url, err)) } | ||
} | ||
}, | ||
|cx, _, _, _, _| { | ||
view! { cx, | ||
title { "Error" } | ||
} | ||
}, | ||
); | ||
error_pages.add_page( | ||
404, | ||
|cx, _, _, _, _| { | ||
view! { cx, | ||
p { "Page not found." } | ||
} | ||
}, | ||
|cx, _, _, _, _| { | ||
view! { cx, | ||
title { "Not Found" } | ||
} | ||
}, | ||
); | ||
|
||
error_pages | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
mod error_pages; | ||
mod templates; | ||
|
||
use perseus::{Html, PerseusApp}; | ||
|
||
#[perseus::main(perseus_warp::dflt_server)] | ||
pub fn main<G: Html>() -> PerseusApp<G> { | ||
PerseusApp::new() | ||
.template(crate::templates::index::get_template) | ||
.template(crate::templates::about::get_template) | ||
.error_pages(crate::error_pages::get_error_pages) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use perseus::{Html, Template}; | ||
use sycamore::prelude::{view, Scope}; | ||
use sycamore::view::View; | ||
|
||
#[perseus::template_rx] | ||
pub fn about_page<G: Html>(cx: Scope) -> View<G> { | ||
view! { cx, | ||
p { "Check out your browser's network DevTools, no new requests were needed to get to this page!" } | ||
|
||
a(id = "index-link", href = "") { "Index" } | ||
} | ||
} | ||
|
||
pub fn get_template<G: Html>() -> Template<G> { | ||
Template::new("about").template(about_page) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
use perseus::Template; | ||
use sycamore::prelude::{view, Html, Scope, SsrNode, View}; | ||
|
||
#[perseus::template_rx] | ||
pub fn index_page<G: Html>(cx: Scope) -> View<G> { | ||
// We can't preload pages on the engine-side | ||
#[cfg(target_arch = "wasm32")] | ||
{ | ||
// Get the render context first, which is the one-stop-shop for everything | ||
// internal to Perseus in the browser | ||
let render_ctx = perseus::get_render_ctx!(cx); | ||
// This spawns a future in the background, and will panic if the page you give | ||
// doesn't exist (to handle those errors and manage the future, use | ||
// `.try_preload` instead) | ||
render_ctx.preload(cx, "about"); | ||
} | ||
|
||
view! { cx, | ||
p { "Open up your browser's DevTools, go to the network tab, and then click the link below..." } | ||
|
||
a(href = "about") { "About" } | ||
} | ||
} | ||
|
||
#[perseus::head] | ||
pub fn head(cx: Scope) -> View<SsrNode> { | ||
view! { cx, | ||
title { "Index Page" } | ||
} | ||
} | ||
|
||
pub fn get_template<G: Html>() -> Template<G> { | ||
Template::new("index").template(index_page).head(head) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod about; | ||
pub mod index; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
0c4fa6b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold
1.10
.Wasm Bundle Size
278986
Bytes250090
Bytes1.12
This comment was automatically generated by workflow using github-action-benchmark.
CC: @arctic-hen7
0c4fa6b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Willing to accept this performance regression given the substantial performance improvements to the number of network requests Perseus apps make.