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

Implement brotli compression data-format for faster loading of websites. #525

Closed
nmabhinandan opened this issue Jan 21, 2016 · 32 comments
Closed
Labels
feature ⚙️ New feature or request
Milestone

Comments

@nmabhinandan
Copy link

References:

@mholt
Copy link
Member

mholt commented Jan 21, 2016

Yeah, brotli looks cool. Waiting for a good pure Go library that implements brotli.

@mholt mholt added feature ⚙️ New feature or request good first issue 🐤 Good for newcomers labels Jan 21, 2016
@mholt
Copy link
Member

mholt commented Jan 22, 2016

Going to mark this "good for newbies" since implementing an algorithm from spec is a great exercise for anyone who knows Go.

Here's one that was started but is incomplete: https://godoc.org/github.com/dsnet/compress/brotli

@humboldtux
Copy link

I would like to work on this.

@mholt
Copy link
Member

mholt commented Jan 24, 2016

Awesome, let the author know and it looks like this would be a good place to start: https://github.com/dsnet/compress/blob/master/brotli/writer.go

@humboldtux
Copy link

Which author, @mholt ?

@mholt
Copy link
Member

mholt commented Jan 25, 2016

I mean @dsnet ;)

@dsnet
Copy link

dsnet commented Jan 25, 2016

Hello.

The current state of my brotli package is that the Reader is 100% functional. There are still many performance tweaks to be made, but I am not aware of any bugs that make it non-compliant with the RFC draft. In fact, as I was implementing it a few months back, a few PRs were made to the draft to clarify certain points.

As for the Writer, there is still work to be done. I have completed an implementation of a bit writer and a entropy encoder. The major remaining piece, is writing a LZ77-style string matcher. For that reason, I'm actually currently working on finishing my own implementation of a RFC 1951 DEFLATE compressor. The components built to implement DEFLATE will make implementing Brotli significantly easier.

Given that I work on my compression library as a personal side project, I don't anticipate getting this all done for a few months. Follow the project for updates on progress. Also, I can ping this issue when the Writer is in a functional state.

@humboldtux
Copy link

Thank you for explanations @dsnet

Should we put this on hold @mholt?

@mholt
Copy link
Member

mholt commented Jan 26, 2016

Yeah, I guess. But at least now Joe knows there is great interest in his work - so please do let us know, Joe, when you're ready for others to help or use it.

Or if anyone finds another pure Go brotli package before then, we could look at that too.

@mathwhiz1212
Copy link

I would like to see this included in caddy as well.

@mholt mholt added the help wanted 🆘 Extra attention is needed label Mar 21, 2016
@mholt
Copy link
Member

mholt commented Apr 9, 2016

@dsnet By the way, I just realized I don't think I thanked you for chiming in a few months back. Thank you! 😄 Looking forward to your progress in the coming weeks/months. Looks like really great code so far.

@faddat
Copy link
Contributor

faddat commented Apr 22, 2016

I am not entirely sure this is the kind of thing you're looking for but:

https://github.com/Nelson69/izip/

@mholt
Copy link
Member

mholt commented Apr 22, 2016

No, unfortunately that package requires heavy amounts of cgo.

@faddat
Copy link
Contributor

faddat commented Apr 22, 2016

Gotcha-- well, I'll keep my eyes open :)

@wendigo
Copy link

wendigo commented Oct 12, 2016

Anyone want to implement golang version of brotli from scratch?

@faddat
Copy link
Contributor

faddat commented Oct 12, 2016

out of curiosity, what is gained by purging one's go of cgo?

Pride? performance? Stability?

Thanks :)

Jacob Gadikian
E-mail: [email protected]
SKYPE: faddat
Phone/SMS: +84 167 789 6421

On Thu, Oct 13, 2016 at 12:21 AM, Mateusz Gajewski <[email protected]

wrote:

Anyone want to implement golang version of brotli from scratch?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#525 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AGz6iTV8to4EllN8cVbxWpLS4v-HdqrKks5qzRcWgaJpZM4HJhl_
.

@dsnet
Copy link

dsnet commented Oct 12, 2016

@faddat

It is incredibly hard to get cgo to work properly with stability on all platforms and across versions of Go. Even carefully reading the documentation, its easy to miss something. [0] [1] [2]

In my job, one of my tasks is to do the release of the next version of Go. Issues coming from cgo are probably among the most common failures (and also the most painful to debug). What worked in one version may not work in the next version because the cgo code made subtle assumptions about the runtime environment that happened to be true in one version, but not the next. After a release, it is common to see bug reports (some from popular projects) about cgo breaking after a release and IIRC a majority of them is due to faulty assumptions.

As an example of an upcoming change in Go1.8, SSA is getting smarter and no longer keeps variables live until the end of the function. This can cause failure in cgo when a pointer is passed to C, but ends up being the last reference of it. The GC may come and clear the backing memory. It is the programmer's responsibility to call runtime.KeepAlive to ensure that the variable is live in the duration of the cgo call (see golang/go#15843). Changes like this are not covered by the compatibility agreement.

Fundamentally, some packages must depend on cgo, but hopefully they have been battle tested by many users and carefully reviewed by experts.

(This isn't a smack on cgo, but to say that foreign function interfacing is always hard in any language)

@MisterDuval
Copy link

Hi folks,
I found this package: https://github.com/kothar/brotli-go
Could it be usefull in Brotli implementation?

@elcore
Copy link
Collaborator

elcore commented Oct 19, 2016

Hello @devil1591,

sorry but no :( -- We want to use clean/pure Go (see above)

@mholt
Copy link
Member

mholt commented Jan 1, 2017

Well, since a brotli reader has been implemented in pure Go, Caddy now serves up pre-compressed brotli (and gzip) files if they are on disk with a .br extension. This went out with 0.9.4. I still don't know of a brotli writer in pure Go and I'm not sure if we'd want that anyway since, AFAIK, brotli compresses way slower than gzip. So maybe what we've got for now is good enough. Thanks everyone! And especially thanks to @dsnet. Happy New Year.

@mholt mholt closed this as completed Jan 1, 2017
@mholt mholt removed the help wanted 🆘 Extra attention is needed label Jan 1, 2017
@Bechrissed
Copy link

Hi Matt, i'm not sure if it's the best choice to not look further into a pure go brotli writer. Akamai has written a nice article about brotli versus gzip. It seems brotli is only slower then gzip if you use them both with default settings. When using quality level 4 brotly is compresses 21% faster with 9% better compression on average. For more info please read: https://blogs.akamai.com/2016/02/understanding-brotlis-potential.html

@wendigo
Copy link

wendigo commented Feb 20, 2017

@Bechrissed If you run caddy to serve static files you can always serve pre-compressed files (.br for brotli and .gz for gzip - brotli is preferred if both are present). If you use caddy as a frontend for other backends (fastcgi/proxy) you can always use brotli there with whatever implementation you would like. From my perspective - compressing files in the flight is bad solution and should be avoided.

@Bechrissed
Copy link

Yes, that might be true. I'll look for a build solution. Thanks

@Bechrissed
Copy link

I'm working on a fly package to generate the brotli compressed files. Will release when finished.

@vladbondarenko
Copy link

If you run something on backend that can brotli support (like nginx + ngx_brotli module) you can use caddy and caddy will send your Accept-Encoding header to backend. Backend will send compressed on-fly with brotli (content-encoding:br) and caddy will proxy it to you.

No need any support for this in proxy mode.

@Jabher
Copy link

Jabher commented Oct 27, 2017

@wendigo

(.br for brotli and .gz for gzip - brotli is preferred if both are present)

why not to prefer the one with the smaller file size?

@vladbondarenko
Copy link

what about proxy mode? how will you check which is smaller? brotli is smaller in most cases so it should be prefered.

@faradaytrs
Copy link

Yeah it would be cool to have brotli built-in support, at least as a plugin.

@faradaytrs
Copy link

Hi is a pure Go encoder and decoder @mholt , https://github.com/andybalholm/brotli
Any way to implement that? I know your opinion about brotli, that sometimes it can be even slower, but maybe it's better to let user to choose?

@whitestrake
Copy link
Collaborator

Not really an opinion - the facts are pretty well covered further up the thread regarding speed, no need to rehash. We'd love to see a PR, but I suspect Matt will be too busy with Caddy 2 efforts to look into this himself.

@mholt
Copy link
Member

mholt commented Jun 12, 2019

Thanks @faradaytrs - will consider that. @whitestrake you are right, but I might as well look into putting it into Caddy 2

@mholt
Copy link
Member

mholt commented Jul 16, 2019

We added it to Caddy 2, but it's unbearably slow when used with network requests. Might not make it a standard module for now. (But, hey, Caddy 2 has a good zstandard encoder instead.)

@mholt mholt added this to the 2.0 milestone Jul 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature ⚙️ New feature or request
Projects
None yet
Development

No branches or pull requests