Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static file compression & caching are broken #4278

Open
EZForever opened this issue Jan 7, 2025 · 1 comment
Open

Static file compression & caching are broken #4278

EZForever opened this issue Jan 7, 2025 · 1 comment
Labels
bug Something isn't working

Comments

@EZForever
Copy link

Describe the bug

This is a reopen of issue #4272, now as a bug report. I described the problem there (along with some personal rant; apologies for that), but in short, despite static file compression and caching are enabled via Echo middlewares in Memos code (here, if I understand it correctly), they do not actually come into effect, resulting in all static files are being served uncompressed and uncached, significantly wasting server and client bandwidth, and if the Internet connection is weak, resulting in seconds wasted every app launch.

I do not know enough Go to pinpoint the problem and provide a fix, but from what I currently understand, there are (at least) two things that have gone wrong:

1. Compression is not enabled on root route

https://github.com/usememos/memos/blob/v0.23.0/server/router/frontend/frontend.go#L50-L55

This is the obvious one; gzip middleware is never applied on /, only on /assets, while the biggest of the static files, app.XXX.js, is being served from /, thus not compressed.

2. Echo cannot handle static file caching if the file in question is embedded

This is the not-so-obvious, but still devastating one. Memos uses Static middleware provided by Echo to serve static files, and it, in theory, should correctly handle caching-related HTTP headers. However, digging into Echo's code, we could find that it handles caching by passing the file's ModTime to http.ServeContent() and call it a day.

https://github.com/labstack/echo/blob/v4.12.0/middleware/static.go#L243-L246

Memos releases pack all static files into the executable, and retrives them via the embed package. The problem is that embed does not provide ModTime info, and returns a zero value Time instance instead.

https://cs.opensource.google/go/go/+/refs/tags/go1.23.4:src/embed/embed.go;l=220

To quote from the documentation of http.ServeContent():

If modtime is not the zero time or Unix epoch, ServeContent includes it in a Last-Modified header in the response. If the request includes an If-Modified-Since header, ServeContent uses modtime to decide whether the content needs to be sent at all.

And since ModTime is zero, caching-related HTTP headers are entirely disabled.

Steps to reproduce

  1. Navigate to Memos front page with DevTools opened.
  2. (If your connection is good enough to hinder the problem) Hit refresh a few times for a more visible effect.
  3. Observe that as the page loads, the same set of static files are being repeatly downloaded, and the app.XXX.js file, despite being static and large enough to enable server-side compression, does not gets compressed.

The version of Memos you're using

v0.23.0

Screenshots or additional context

Copying a screenshot from the aforementioned issue:

image

This happens every single time you open Memos or hit refresh.

@EZForever EZForever added the bug Something isn't working label Jan 7, 2025
pransh62390 added a commit to pransh62390/memos that referenced this issue Jan 11, 2025
@pransh62390
Copy link
Contributor

@EZForever I have fixed the issue. please review it once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants