storj / edge

Storj edge services (including multi-tenant, S3-compatible server to interact with the Storj network)
GNU Affero General Public License v3.0
54 stars 18 forks source link

Optimize Error Pages - Reduce content size #361

Open ferristocrat opened 1 year ago

ferristocrat commented 1 year ago

Summary

Acceptance Criteria

Possible Solutions

storj-gerrit[bot] commented 1 year ago

Change pkg/linksharing/sharing: optimize 429 responses mentions this issue.

storj-gerrit[bot] commented 1 year ago

Change pkg/linksharing/web: serve bootstrap from CDN mentions this issue.

halkyon commented 1 year ago

Should we keep this open for a few more improvements? The static background could be another thing to optimize.

@amwolff, did you intend for it to close after that change?

egonelbre commented 1 year ago

Are we missing caching headers for the content? I don't see a reason why they should be such a big impact.

Also, are we missing compression for the assets?

halkyon commented 1 year ago

Few other points mentioned in a Slack thread:

See the PageSpeed report here: https://pagespeed.web.dev/analysis/https-link-storjshare-io-s-jwur4oa5atf5ireddlrxtk4g7yqq-uptime-checks-hello-world-txt/kny8inzxcm?form_factor=mobile

Generally it might be good to check out the network tab in the browser and see if we can spot anything else that looks like a big download or not optimal.

storj-gerrit[bot] commented 1 year ago

Change pkg/linksharing: enable caching for static files mentions this issue.

halkyon commented 1 year ago

I found https://github.com/vearutop/statigz that looked good, but it didn't have cache busting features.

Egon had a great idea (thanks!), that looks something like this:

type StaticCache struct {
    prefix string // if needed
    data fs.FS
    mu   sync.Mutex
    comp map[string]Entry
}

type Entry struct {
    Path        string
    Etag        string
    ContentType string

    Data []byte
    Gzip []byte
}

func (cache *StaticCache) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Allow", http.MethodGet + "," + http.MethodHead)
    if r.Method != http.MethodGet || r.Method != http.MethodHead {
        http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
        return
    }

    entry, ok := cache.Entry(r.URL.Path)
    if !ok {
        http.Error(...)
        return
    }

    w.Header().Add("Content-Type", entry.ContentType)
    w.Header().Add("Etag", entry.Etag)
    // add caching header

    data := entry.Data
    if acceptsGzip(r) && len(entry.Gzip) > 0 {
        w.Header().Add("Content-Encoding", "gzip")
        data = entry.Gzip
    }

    if r.Method == http.MethodHead {
        return
    }

    w.Write(data)
}

func (cache *StaticCache) Link(urlpath string) template.HTML {
    // return canonicallink + "?etag" + etag
}

func (cache *StaticCache) Entry(urlpath string) (Entry, bool) {
    target := path.Clean(urlpath)

    cache.mu.Lock()
    entry, ok := cache.comp[target]
    cache.mu.Unlock()

    if !ok {
        entry, ok = cache.load(target)
        if !ok {
            return Entry{}, false
        }

        cache.mu.Lock()
        cache.comp[target] = entry
        cache.mu.Unlock()
    }

    return entry, true
}

func (cache *StaticCache) load(target string) (Entry, bool) {
    // load data
    // compute some hash for etag
    // compress gzip
    // determine content type based on ext
}

func acceptsGzip(r *http.Request) bool {
    // todo:
}
ferristocrat commented 1 year ago

@boshevski - let's take a look at the Linksharing UI and discuss if it needs a refresh to make it more consistent with the Satellite UI.

boshevski commented 1 year ago

@ferristocrat I made a pr that optimizes the logo and the background image 3x. I'm working on updating the ui designs next

egonelbre commented 1 year ago

AFAIK, https://github.com/storj/gateway-mt/issues/361#issuecomment-1718344528 has not yet been implemented or will that be handled in a separate issue?

halkyon commented 1 year ago

yes, this isn't complete. I reopened it.