 We did actual work and we produced something that we then shared with others, so let's start there. How I am and who I am and what I'm doing, so on. I'm doing polyprop for some years at least professionally, I hope for that as well. And it's about compression of CSS, so that's in itself rather simple. I did that at the optimizations in the bookings and that already gives an idea of, we've done it on a bigger scale. And that's how it's interesting. And it was, why we did it? Because there are already existing solutions for it. And we were dependent on the Yahoo's UA Compressor, which is using Java, so you have startup times that are not very fun. Apart from that, we wanted to do more things, like we actually wanted to do this at runtime. And at that point you start thinking, ow. Yeah, and we wanted to do this not only for the dynamic things, but also basically all the side sheets. All the things that we had because we were using the UA Compressor for this. And as mentioned, dynamic side sheets as well. And yeah, we wanted to be able to integrate it. So I was thinking, why can't I just have a simple call that does the compression and I immediately give it back, and then it should be fast so not too much latency. And how we did it before, we had pre-production phase one script that goes over the whole template tree. Oh, here are all the CSS files. When you do next, we want to produce multiple versions. We have multiple versions, we have multiple domains, so you need this for staging, and you need different host names and development versions of everything. And then in order to call the UA Compressor, you first need to write it on this, which is already pretty annoying because you could do it in memory if that wasn't interesting. And as you get multiple thousand files, you want to make this faster, and not in the sequential lines, so you start multiple JVMs in parallel, and overhead sketch as well. Some people don't really want to realize that, I think. As I increase the number of files into thousand, then it already starts working. Few JVMs in KVMs, nice, so virtualized, virtualization basically, and yeah, waste of time in my opinion. Well, I could have done instead of re-implementing this, write socket access for Java things. I actually did that before, and it worked sort of well, but you still need to maintain those, and I never really wanted to do that. I started JVM tuning probably because I don't care that much, but it should just work. And also I want to invest into infrastructure that I have already instead of spending time on something that's a single application, maybe it's worth it, but still, if it's part of the full stack, then we have already, it's supposedly easier to maintain. And also dependencies, and it's fun. It was a really fun project. So the plan was to have it fast from the start, so I basically always had NYT proof running aside, compiling everything, and then of course it has to produce correct resize, which is, well, the most important requirement to begin with, to be able to bring it in production or anything like that. And so, yeah, I started reading the source, and well, then at some point I should write some poll that does what I want. When reading the source, there were some interesting things. It's mostly regular expressions, actually. I was expecting them to have a proper parsing model and whatnot, but they don't. And how they're doing regular expression was also something that I, like if you're using code, you don't think about this, but because regular expressions are part of the core, it's just happening, it's fast, you don't need to worry about memory allocation. What they did, they were basically building regular expression objects over and over and over again in groups, and then using the result of the first one to set up the next, and yeah, so memory pressure, very high, so it was rather obvious that I couldn't get involved. And they also had a lot of tests that was also great. I had a lot of production files, but having their tests and being compatible with them upstream allowed me to be really sure that what I'm doing is correct in here. So over then, hacking it in code. Of course, I started with the tests from upstream, and then a few files and files we had in production just to have even more test cases. And then I took some time to understand how their whole concept of regular expressions work, and the fun part is in the end that the resulting file code, logically, what it does internally is pretty much the same than the Java code, even though it looks completely different. But if you follow the flow, it's understandable, even though it's using things like execution with irregular expressions and so on. But some of it is done for speed, some of it is just showing how compact you can do those things in code. That's one of the things I liked in the old project, as experienced from my side. So what we got, start-up times, not even going to talk about it. But runtime performance, that was still interesting. So the whole memory pressure resulted in roughly 50% performance improvement. So we were running this on our systems on 925. It does a bit more than just the CSS part. The weak compressor also has JavaScript compression, which I did not tackle because that actually was parsing it properly. I still would like to do it, but I'm not sure of this project. And we dropped the time down less than half. And we're processing almost half of the files, and the runtime dropped more than half. And for the dynamic style sheets, I had nothing to compare with. So just assuming runtime is good enough. And you could still ask why I didn't do that. Seriously, some people say, yeah, why don't you just use this or that module, the CSS packer. There are other modules. We went through a whole bunch of modules on C time, and none of them was as good as the weak compressor. And also testing all other modules just to find out that they are not reducing when we want didn't feel like that. And we know that it works reliably. It gives us exactly what we wanted, and we're quite happy with it. And on top of that, we can use it any imaginable way. And even right now we're using it in a customized version, but it's very simple to think that. One or two lines of changes. And I'm even thinking if I should plot that back, but I first need to find out if that's too specific or if it can be applied in general. It's something for left to right language change switching. So if anybody has a problem there and is interested, let me know then and you can figure that out. Of course, we'll be faster than C. There are XS implementations. Haven't really tested. What ability is also a question, and I like the fact that it's pure core because you can just run it everywhere. There are some examples of benchmarks that prove on this kind of things actually is faster than C and C++. I guess that also depends how it's implemented. Because a very cool influence memory access. Yes, exactly. And memory management is so good that I would doubt is there are benchmarks where C is slower than both? Well, like I'm mentioning some articles where people also discuss the performance and there are C versions which are faster, but then I'm still questioning the results. So, yeah, good job. And as mentioned, it should be easy to integrate and change. I think it is. So then we went into the integration phase, which I think is also interesting to mention. So we have this script that's always running with employee stuff and I just extended that script to also use the whole version of it in the background and then check for the differences and send the divs back to me by our mate so we can figure out what went wrong. And it was very good for that. I actually found a typo that was made upstream where left and right wasn't really matching and then I was actually improving on our side further than upstream and I sent the patches upstream and they took more than two years to release it with that. So we were ahead of time for some bit. Next step was to do active testing but still do the comparison to see if stuff goes wrong. And yeah, after that it was running for some weeks. We basically just made an announcement and put it into production and since then we're using it. Yeah, the mentioned dynamic sessions are now really simple because the more you just expose one function that you can import, you give it your CSS and you get back the minified version. And yeah, this test... Yeah, I tested it as well. So this actually works. So give it your CSS, you get it back and that's fast. How was it? No, I don't remember the times exactly. Yeah, and we run some experiments with those dynamic stat sheets but generally we actually had separate clusters for this and maintaining it was not really worth it. Maybe we should try it again in two years or something and it's used wherever we can. So that's already quite some success and I also found that external people noticed it and started using it. So I started myself with a blog post then it was mentioned on Hacker News where then were discussions how Perl is beating Java and whatnot which was related to the memory pressure point where the external pressure that we have or had at that point was that we can be Java. Which while screen processing that points to Brian and also was related for some time what was a nice discussion showed up in completely unrelated techniques which I also found cool points on Twitter as well but yeah, after some time I still wasn't really happy because that wasn't enough. I wanted more users, more users, something like that. Plugins, that was obvious. For black for example or more delicious, those are the two that I use sometimes. So I created a middleware for black which allows you to adjust a mini.css and pure css files just to be compressed on the fly and it's reusing the static black middleware so it's really just a few lines of code that basically wrap the css compressed function and you can hook it up to your builder like that and do that. Similar for more delicious just a lot of plugging and there you go for the light apps as well as for more and you can change the suffix to whatever you like. Somebody else, don't recall who it was but created this setup plugin as well so if you are creating web apps and you want to ship compressed files you just need to load the css compressor to the setup plugin and you're done. You can even do more compressions there where you're saying you just scan this specific file or this directory and only compress those but with that everything will be compressed directly. So what was big? Are there any questions or compresses? Other feedback? Involve xs. What kind of compression are you doing? White space trimming? It's white space trimming it's also looking at color codes and then for example if you have a hashtag in 6f that gets cut down to 3f and then those sort of things. So you know there will be inheritance of color values because that's inheritance. But it's also much harder. I'm going to follow up on this question if you have code that has a statement in the later and it's getting repeated because it also sent that out oh it's extraneous code it doesn't get used because... That's actually a very nice thing. But I don't know yet how to generalize it I would like to have that where you basically have a web page inline css and you would pass that out and somehow make the connection or compress it inline. Somebody has something called dust base selectors where it can find css that isn't being used and you could look at the code for that and see how it's determining that a later piece of code the total variety of previous piece of code says exactly the same thing because you see a lot of people or people write code that it doesn't do anything because you're missing some other property depending on so you know I actually code with like 10 lines or something like that one of those lines can do anything because the things in inline we have a block. We're working with tons of those we're even exceeding the limits of id67 and so on then you can only load a certain amount of roots and if you're exceeding that 32 Yeah Once I wrote in bars of css what's written in css and then you can solve these things that's extremely hard because you have so many different forms you need all the css tags some different syntax I would say the least of the problems how specific rules are you can operate them from elsewhere with not important rules like that's exactly what I'm afraid of different defaults and so on We're here to call the sort of a numbering system actually as far as what can override what and when it's like weights We can't even get them to that It's quite difficult Somebody wrote a little thing that actually was just looking at who overwrites what like an id had a weight of this a place selector or space had a weight of this and they could just say well this one is more weights than this one If you want to get a value and then you have to follow the rules it's easier than if you want to minimize the set of rules I think first you want to run through and get rid of everything that you know it's overridden anyway and then compress you have to do it in a new set of processes What would be a very nice step to have in front of the right PTO Next slide