A Go Package for Building Progressive Web Apps
go-app.dev
go-app.dev
0. This site: 14.9MB, 3.4MB gzipped;
1. 13.5MB, 3.2MB gzipped;
2. 15.4MB, 3.2MB gzipped;
3. 4.7MB, 1.2MB gzipped (this is an extremely bare bones demo);
4. 25.0MB, 5.4MB gzipped.
You can save a bit more with brotli, but not much more. I built an app with golang wasm last year, but ended up rewriting everything in good old TS since I couldn't justify the ~15MB raw, ~2.7MB brotli'ed payload.
I guess you can make some huge savings if tinygo has enough capabilities to cover all your needs. Not sure if it's possible with this library, but if it is, they certainly haven't explored it, hence the 3.4MB gzipped wasm for a documentation site.
On an arbitrary fairly weak phone, 15MB of WASM might take two seconds to compile, but it can do that while downloading, so that in practice your network link will probably be the limiting factor. So the transfer size is typically the figure to care about and the uncompressed size actually doesn’t matter all that much.
15MB of JavaScript on that same device might take ten seconds or even more to compile, and it largely can’t even start until it’s finished downloading it. Consequently, you need to care about both the transfer size and the uncompressed size, in different ways.
(My figures are super dodgy as I can’t find any recent concrete figures, but they should be in vaguely the right ballpark.)
This is all about comparing just the cost to the CPU; data transfer costs money too and takes time, and several megabytes transferred is inconvenient to many for reasons of cost or time, and decidedly wasteful.
Multiple megabytes even of WASM is still madness and folly for simple stuff like this, severely restricting its potential usefulness. Thank you for deciding not to ship something like that yourself.
Also, in my experience, a 15MB wasm blob has shit caching characteristics; it gets evicted all the time. An immutable few hundred KB js blob, on the other hand, can remain cached for much longer. Sure, you can use a service worker and its Cache API to make caching large blobs more predictable, but then shipping new code / cache invalidation becomes more annoying.
Of course it’s partially a function of your target audience. Notion and Retool (for example) are able to ship massive multi megabyte bundles because they’re productivity apps targeted mostly towards people with desktops and high speed internet connections. If HN were to ship a 15MB bundle it’d be virtually unusable on mobile for a lot of people (myself included, and I live in Seattle!).
Of course if the development benefits for your team outweigh it, it makes sense to do it. Just mean to say advertised cellphone connection speeds are not a reliable benchmark to hit.
https://www.statista.com/statistics/185532/us-household-dial...
(URL says 2009, but it was updated with statistics for 2019)
> If present trends continue, there is the real chance that articles warning about page bloat could exceed 5 megabytes in size by 2020.
> The problem with picking any particular size as a threshold is that it encourages us to define deviancy down. Today’s egregiously bloated site becomes tomorrow’s typical page, and next year’s elegantly slim design.
A lot of modern web is a nightmare to use if you have a ~$50 android phone and are lucky if you have a decent 3G connection.
Genuine question: how did you manage to forget something so huge?
Most LLVM generated binaries, including Rust by default from memory, turn out pretty small.
Really wish Go had some kind of parameter that let it take extra time compiling "production" builds, such that it would significantly optimise their resulting size.
What were the size improvements?
I don't know how somebody keeps a straight face clainming their 14 meg page is SEO-friendly.
https://stackoverflow.com/a/46159048
Not sure if anything's changed since then
GOOS=js GOARCH=wasm go build -ldflags='-s -w'
comes in at 1.2M raw, 362K gzipped, 276K brotli'ed (default compression levels).For the syntax, it is a matter of tastes but things that people like about it is that its full Go and everything is discoverable from your editor with auto completion.
At the end what’s matter is that it’s good enough to build beautiful UI only by using Go and it’s ecosystem.
func (h *hello) Render() app.UI {
return app.H1().Text("Hello World!")
}
Using a template would have been easier and more clear.I did it in previous version and since there is no code check/lint on HTML templates within strings, debugging HTML was a pain in the ass.
More clear is a matter of taste and you can do pretty clear code with this syntax.
Main issues:
- the size of your build: you need to check what packages you import and possible trim them down
- resource usage and performance(due the lack of DOM).
- bugs/implementation: the browser may stop working/freeze after a while. There were some issues with the scheduler, I'm not sure if it's still the case. If you develop an UI for an embedded device this is a big issue.
It may work for Desktop apps (electron based) or some enterprise apps so it has its niche but you definitely can "feel" the difference between a wasm implementation and a pure JS implementation. As a client you will prefer the JS version. As a developer you will love the Go version
All that being said it's great to be able to use Go in browser and as the devices are getting faster along with the network I guess it will work just fine once 5G becomes mainstream.
Hint: If you process HTML, always use the DOM/JS interface. Any processing of HTML (i.e. via x/net/html) in Go will make your app VERY slow.
At least have a demo that warrants a package that large.
You monster!
It’s been a while since I’ve seen a documentation site with a loader that goes multiple seconds.
Personally I'm still not a fan of PWA. I don't see what they give me as a user, other than a worse experience than a native application would have.
Installs aren’t really an issue, and less so if you like the app store. I can see the point about wall gardens, but you can still just install non-app store programs on all operating systems. Regarding the 30% I not convienced that saving are directly passed on to the end users.
Edit: It just occurred to me that you might be think about software on phones. I don’t exactly care about mobile, but yes, then your argument makes more sense.
The ServiceWorker API has been supported by iOS Safari for years: https://caniuse.com/mdn-api_serviceworker. When people complain about lack of PWA support on iOS Safari, usually the #1 complaint is lack of Web Push: https://caniuse.com/push-api.
In this specific case, the site is working fine on iOS Safari 14, and Safari 15 TP on macOS Big Sur. I'm not sure if there are problems specific to Safari 15 on not-yet-released iOS 15 or macOS Monterey, I don't have an installation of either.
Good, web push is horrible and 99.9% of use cases are malicious. Take a look at your grandma's Android phone and she probably has 12 Chrome notifications saying she won a free iPad because she went on a site that asked to send notifications, and users are so used to user-hostile UX's that force you to agree to everything to use the site, they just hit "allow" so they can get to the content.
I'm not surprised Apple doesn't want that on the iPhone.