diff options
author | Peter Cai <[email protected]> | 2020-04-18 16:46:11 +0800 |
---|---|---|
committer | Peter Cai <[email protected]> | 2020-04-18 16:46:11 +0800 |
commit | 5c2615a6cbea62d69717dde2deb7bed3e494a06f (patch) | |
tree | a884b757fd741fa5da0899e50f0105cb0f8c802c | |
parent | e0d8c949866a9487e08452ba7e3dde14282cfa96 (diff) | |
download | paprika-5c2615a6cbea62d69717dde2deb7bed3e494a06f.tar.gz |
blog: get rid of Vec allocation in render for good
just spawn the cache whitelist task onto the js ev loop and don't care
about it; the write only need to succeed once and that normally happens
at the very first time.
-rw-r--r-- | src/blog.rs | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/src/blog.rs b/src/blog.rs index 3a5bbd1..86d013d 100644 --- a/src/blog.rs +++ b/src/blog.rs @@ -9,10 +9,10 @@ use crate::utils::*; use js_sys::{JsString, RegExp}; use pulldown_cmark::*; use serde::{Serialize, Deserialize}; -use std::future::Future; use std::vec::Vec; use wasm_bindgen::JsCast; use wasm_bindgen::closure::Closure; +use wasm_bindgen_futures::spawn_local; // A list of the UUIDs of all published blog posts // This should be SORTED with the newest posts at lower indices (closer to 0) @@ -215,16 +215,25 @@ impl PostContentCache { Some(cache) } - async fn transform_tag<'a>(tag: &mut Tag<'a>) { + fn transform_tag<'a>(tag: &mut Tag<'a>) { match tag { Tag::Image(_, url, _) => { // Convert all external image to our cached URL // to protect users and speed up page loading let url_encoded: String = js_sys::encode_uri_component(url).into(); // Also write this URL to whitelist + // (just throw the task onto the JS ev loop, + // because to make this function async we MUST need to + // allocate Vec later in the render function) // we don't care about if this write succeeds or not, // because even if it breaks we still can recover by a simple refresh - let _ = store::put_str(&Self::url_to_cache_whitelist_key(url), "Y").await; + // and once it's written, it's permanent, so we expect the write + // to succeed as soon as the article is submitted + let url_cache_key = Self::url_to_cache_whitelist_key(url); + spawn_local(async move { + let _ = store::put_str(&url_cache_key, "Y").await; + () + }); // Now we can overwrite the tag URL *url = format!("{}{}", IMG_CACHE_PREFIX, url_encoded).into(); }, @@ -233,17 +242,15 @@ impl PostContentCache { } fn transform_tags<'ev>( - parser: impl 'ev + Iterator<Item = Event<'ev>> - ) -> impl 'ev + Iterator<Item = impl Future<Output = Event<'ev>>> { + parser: impl Iterator<Item = Event<'ev>> + ) -> impl Iterator<Item = Event<'ev>> { parser.map(|mut ev| { - async { - match ev { - Event::Start(ref mut tag) | Event::End(ref mut tag) => { - Self::transform_tag(tag).await; - ev - }, - _ => ev - } + match ev { + Event::Start(ref mut tag) | Event::End(ref mut tag) => { + Self::transform_tag(tag); + ev + }, + _ => ev } }) } @@ -329,17 +336,11 @@ impl PostContentCache { let parser = Parser::new_ext(&post.content, Options::all()); // Apply code highlighting via Highlight.js let parser = Self::transform_code_block_highlight(parser); - // Apply async tag transform (resulting in an iterator of Futures) + // Apply tag transform let parser = Self::transform_tags(parser); - // Await on every Future in the queue to convert them back as Events - let mut events: Vec<Event> = vec![]; - for ev in parser { - events.push(ev.await); - } - let mut html_output = String::new(); - html::push_html(&mut html_output, events.into_iter()); + html::push_html(&mut html_output, parser); html_output = Self::transform_html(html_output); PostContentCache { uuid: post.uuid.clone(), |