arctic-hen7 / perseus-size-opt

Adds size optimizations to any Perseus app automatically.
MIT License
10 stars 2 forks source link

No optimization effects (pending changes in Perseus) #1

Closed phaleth closed 2 years ago

phaleth commented 3 years ago

Today, I've noticed this new plugin and also the simple example this repo holds, which I've tried to deploy with the Dockerfile bellow. Notice that there is no wee_alloc or other sort of manual optimization in place.

Dockerfile

# get the base image
FROM rust:1.55-slim AS build

# install build dependencies
RUN apt update \
  && apt install -y --no-install-recommends lsb-release apt-transport-https \
  build-essential curl

# prepare root project dir
WORKDIR /app

# download the target for wasm
RUN rustup target add wasm32-unknown-unknown

# install wasm-pack
RUN cargo install wasm-pack

# retrieve the src dir
RUN curl https://codeload.github.com/arctic-hen7/perseus-size-opt/tar.gz/main | tar -xz --strip=2 perseus-size-opt-main/examples/simple

# go to src dir
WORKDIR /app/simple

# install perseus-cli
RUN cargo install perseus-cli --version 0.3.0-beta.13

# clean app
RUN perseus clean

# adjust app config
RUN sed -i s'/perseus = .*/perseus = "0.3.0-beta.13"/' ./Cargo.toml \
  && sed -i s'/perseus-size-opt = .*/perseus-size-opt = "0.1.0"/' ./Cargo.toml \
  && cat ./Cargo.toml

# modify and prepend lib.rs
RUN sed -i s'/"Hello World!"/"世界您好 !"/' ./src/lib.rs \
  && cat ./src/lib.rs

# prep app
RUN perseus prep

# adjust and append perseus config
RUN sed -i s'/perseus = .*/perseus = "0.3.0-beta.13"/' .perseus/Cargo.toml \
  && cat .perseus/Cargo.toml

# deploy app
RUN perseus deploy

# prepare deployment image
FROM bitnami/minideb:buster

WORKDIR /app

COPY --from=build /app/simple/pkg /app/

ENV PERSEUS_STANDALONE=true

ENV HOST=0.0.0.0

CMD ["./server"]

The result is that the plugin isn't doing any optimization at all. Bellow is a picture of a browser with network tab opened.

plugin-not-optimizing

As always the Dockerfile above is standalone.

I can provide more feedback if needed, but right now I think this plugin does not add much value. For the most part I do like the way this plugin is headed, but I'd highly recommend leaving it aside at least for the time being until optimizations for production becomes a necessity to deal with for a broader Perseus userbase.

The reason for the above statement is that I've noticed optimizations of the bundle.wasm size I've managed to do lately seem to add pretty much questionable value. I've noticed that those optimizations affect not only the client side bundle.wasm size, but also shrink the size of the server binary deployed on the server, which should not be desired. Not sure if the aim of this plugin is to do any different and leave the server side bundle unoptimized.

arctic-hen7 commented 3 years ago

Haha you beat me to opening this! I'm aware that currently this plugin actually increases binary size in some cases, and that will be fixed by the issue of feature-gating in Perseus. Because this plugin only uses the tinker action, you don't actually need plugins enabled to use it (perseus tinker will manage that for you), so after that issue is closed, this plugin should have major effects! That said, if you apply it on the Perseus website without running perseus tinker, the binary size goes up to 1.5MB, and after running perseus tinker, it goes down to 1.2MB, so the fault is definitely in the core package rather than here I think.

arctic-hen7 commented 3 years ago

Sorry, didn't mean to close this!

phaleth commented 3 years ago

I wasn't aware about that perseus tinker call could make any difference. Was that supposed to go before perseus deploy? At the moment I can't try that one.

When you do the client side bundle comparison on perseus docs website that then shows 1.2 MB optimized vs. 1.5 MB unoptimized, can you also look at the server side bundle and how much that shrinks? I feel like the detrimental effect on the server side binary caused by these 'optimizations' is worse than just adding ~300 KB client side.

From the top of my head, with a hello world website, the server side binary goes from ~11 MB to ~8.5 MB. I think the server binary should not be optimized for size at all, only for speed if possible. That's kind of one of the main issues here. Would you think this plugin could do any different than manual optimizations and leave the server side bundle intact?

arctic-hen7 commented 3 years ago

Yes definitely! There's a new section in the book about plugins that hopefully explains all that (under 0.3.x). As for the fact that client optimizations also affect the server, that's the fallout of a compile optimization I made about a month ago, putting the server and client crates into the same engine workspace, and you can only apply [profile.release] to a whole workspace, not its components. However, because the server no longer needs to import the user's code, I've optimized this in such a way that compile times should only be marginally increase by removing that workspace now (though CPU usage with multithreading goes up a little).

As of the latest commit to Perseus, that quirk is gone, and the optimizations for the server and client work independently.

phaleth commented 3 years ago

Awesome. Thanks @arctic-hen7 for looking at how to separate the server side bundle.

Regarding optimizations not being applied, essentially, what I did was replace perseus prep with perseus tinker. The main confusion here comes from the name tinker. Would you consider adjusting perseus prep to do the same thing perseus tinker does?

Anyways. I'm gonna close this one. Thank you.

arctic-hen7 commented 3 years ago

I think I'd rather not do that, because compiling tinkers takes a while, even if there are none that actually need to be run. For now at least, I think I'll just document that copiously in the plugins documentation. If you're still thinking of writing that docs page about using Perseus with Docker, that would probably also be a good place to add it. That said, I think a --tinker flag on prep is perfectly reasonable.

phaleth commented 3 years ago

You're right. Just now I paid attention to how long perseus tinker call takes and it's pretty much lenghty.

I still do think about contributing the Docker deployment guide to the docs, but since this new optimization plugin appeared I'm really just trying to wrap my head around it first. Once I get to see the plugin work properly I'll prolly try to document the use of this plugin in relation to Docker. Right now I'm still running into deployment related issues and I guess I should open another one.

As far as this 'No optimization effects' issue goes and since I was able to apply the perseus tinker call properly I still get a more or less unoptimized bundle.wasm. Bellow is the standalone Dockerfile and screenshot of the deployed simple example in a web browser. So, I'm reopening this issue.

Dockerfile

# get the base image
FROM rust:1.55-slim AS build

# install build dependencies
RUN apt update \
  && apt install -y --no-install-recommends lsb-release apt-transport-https \
  build-essential curl

# prepare root project dir
WORKDIR /app

# download the target for wasm
RUN rustup target add wasm32-unknown-unknown

# install wasm-pack
RUN cargo install wasm-pack

# retrieve the src dir
RUN curl https://codeload.github.com/arctic-hen7/perseus-size-opt/tar.gz/main | tar -xz --strip=2 perseus-size-opt-main/examples/simple

# go to src dir
WORKDIR /app/simple

# install perseus-cli
RUN cargo install perseus-cli --version 0.3.0-beta.13

# clean and prep app
RUN perseus clean && perseus prep

# specify deps in app config
RUN sed -i s'/perseus = .*/perseus = "0.3.0-beta.13"/' ./Cargo.toml \
  && sed -i s'/perseus-size-opt = .*/perseus-size-opt = "0.1.0"/' ./Cargo.toml \
  && cat ./Cargo.toml

# modify lib.rs
RUN sed -i s'/SizeOpts::default()/SizeOpts { wee_alloc: true, lto: false, opt_level: "s".to_string(), codegen_units: 1, }/' ./src/lib.rs \
  && sed -i s'/"Hello World!"/"世界您好 !"/' ./src/lib.rs \
  && cat ./src/lib.rs

# run plugin(s) to adjust app
RUN perseus tinker \
  && cat .perseus/Cargo.toml \
  && cat ./src/lib.rs

# deploy app
RUN perseus deploy

# prepare deployment image
FROM bitnami/minideb:buster

WORKDIR /app

COPY --from=build /app/simple/pkg /app/

ENV PERSEUS_STANDALONE=true

ENV HOST=0.0.0.0

CMD ["./server"]

image

arctic-hen7 commented 3 years ago

Yep, as I said before, this will still likely be a problem until Perseus can install a plugin only for tinker-time. This plugin only does stuff when you run perseus tinker, but I believe the problem is that it (and all its libraries etc.) are still being sent to the browser. I should have that fixed within the next hour or so.

phaleth commented 3 years ago

Oh, ok, @arctic-hen7. I already know well enough how to optimize for production manually, so, no hurry on this one.