 Good afternoon everybody. Everyone here is here to hear for the aesthetic talk. Okay, yes. Thanks for coming. I'm Chris Wallsmith, the lead developer of aesthetic. I come to Drupal from the symphony side. I've been working with the symphony community for six or seven years, working with PHP for about 10 years or so. I just want to say what a real pleasure it is to be able to speak here at DrupalCon. I've been in such amazement of the Drupal community. First of all, how large it is. Just the sheer size of the community and everyone who comes together. And secondly, the feeling of the community. It's a very welcoming community, very cooperative community, very friendly. Lots of hugs. So I wanted to say good job, you guys. It's a real pleasure to be here. So on that note, I think it's important to start by acknowledging that things are pretty good, that the web can do some really awesome things. And you can do a lot of really awesome things without aesthetic. You don't need it. We can build fancy web applications that don't have a refresh the page, but keep changing continuously, updating things on the server and spreading across multiple apps. And oh my gosh, technology just blows my mind if you think about where we were 10 years ago. So things are really good. But at the same time, we have to acknowledge that things could be a lot better, right? That's why we're here. That's why there's going to be a Drupal 8. I mean, we could stop at Drupal 7, but things could be better. So we strive for ways to improve what we have. And that's kind of the way that I'm going to frame this talk today. I'm going to talk about problems and issues that are out there with the web, issues that are out there with aesthetic, and then talk about solutions, either solutions that aesthetic provides or attempts to provide or solutions for problems to aesthetic that might be coming in the future. So over the course of the next hour, we're going to talk a little bit about the past, the history, not really much history, but how things have been on the web, how things are now on the web and with aesthetic. And we're also going to be talking about the future and about what's going to happen with aesthetic in the next major release. So this is the program, the application, or excuse me, the library. It's available on Composer. Is everyone familiar with Composer? Composer and Packagist? This is also where it's available on GitHub. If you go to github.com, slash Chris Wallsman, slash aesthetic. The library, I started the aesthetic and I think I started working on it at the end of 2010. And the first code was pushed up to GitHub at the beginning of 2011. I'm not sure when the first stable release came, but there have been two major releases, 1.0 and 1.1. In the beginning, the library was inspired by a Python library called Web Assets. You can see a link there. The aesthetic project on GitHub has over 2,500 stars. It's been forked over 400 times and on Packagist, it's been installed over 2.4 million times. So it's a library that a lot of people are using, I guess I can put it that way. Right now, I realize that aesthetic is in the Drupal Composer.json, but it's not actually being used and there's a patch underway. So soon Drupal will be among the projects that use aesthetic and all these numbers will go up, I hope. This is the team. Me and then three other guys here, these are their GitHub names and their GitHub pictures. All around the world, of course, and they help with maintenance of the application and merging new features and bug fixes and work on new development. And then outside of the four of us, there have also been 88 other contributors who have put code into aesthetic. So that's really quick stat sheet on aesthetic. And the first problem that I want to talk about is boring. When the web first started, it was kind of boring. And I guess boring might not be the right word because I was looking around the internet in the past few days trying to find sites that represent kind of how the web used to be before all these new awesome things that we're just talking about or just alluding to came about. And I found this site and it doesn't look very nice, but I spent some time on it. And it's actually, I really like this site. So I feel a little disingenuous calling it boring, but maybe the visual aspects of it are not too compelling. But it's a site by a guy who is talking about how he remodeled his basement and turned it into a home theater and put a time capsule in there. You can't read it now, but he's talking about all the different things that he put into this time capsule. And he's got a nice photo gallery here. This is an aside, but I think one of the things I like about this is that it's got that maker feel to it where someone opens up his tax editor and starts writing HTML. He's not posting photos to Facebook or it's got that real maker vibe to it. So I like this site, but visually it's not so compelling. So there have been some things that have come along over the years. We've added CSS. You can now style your sites in very amazing ways, provide style sheets, reusable styles that cascade down across your site. If you've been to the CSS Zen Garden, this is an excellent example of everything that you can do with CSS. It's still going. And here's one of the ones that I liked more when I visited their home page. So we have CSS now, and you can load in CSS files into your website and make it much more attractive, much more visually compelling experience. And we've also added some JavaScript. So now your site can be much more interactive, it can be much more involved and capture your attention, become much more sticky. So something like New Relic. I saw the head of booth downstairs in the exhibit hall. These sorts of sites where the page is continually updating with live data from your infrastructure, it's great. Thing is, as we start adding all these style sheets and these JavaScripts, you'll notice that your browser needs to pull in more and more and more just to give you a simple single page. And once you add up all of these assets, all these images, these style sheets, these JavaScripts, you start seeing this a lot. Right? Sorry, we have to wait for the next slide. It's going to be a really good slide, but lots and lots of assets get loaded in this slow down your site. So this is a problem, right? There's so many assets being loaded into the page and then slow it down. You start loading up script tags up at the top of your page and that HTML head tag and every script tag, it hits the browser stops. It's got to stop everything it's doing, go out, open up a connection to the server, wait for a response, download that response, close the connection, keep it open, whatever. And then it starts on the next script tag, one at a time at a time. So each one of those that you add adds more and more overhead and really degrades the user's experience on your site. We all had fun spending that minute together, but when it's just you and your computer, it's not so much fun. So what do we do about it? Let's start by modeling the problem. This is where Ascetic comes in. We have these things called assets. And in the eyes of Ascetic, there's just some generic thing called an asset, which typically can be either an image, a style sheet, or a JavaScript. But Ascetic doesn't really care what they are. Ascetic only looks at them in terms of assets. And each of those assets has a few different properties. An asset has a path. It has a timestamp when it was last modified. It has some content. It has some other things too. But this is where we start. We start by taking this problem of assets and wrapping it in an object-oriented API. Because we work in an object-oriented world, there are objects around us. This is how it makes sense to model things. An asset is an object. So that's where we start. It's a good start. Ascetic provides an asset interface. It has mostly getter methods. You can see here a few getters for some of the things we just looked at. You can ask an asset for its content. You can ask it for where it came from. You can ask it where it's going. You can ask it when it was last changed. And a few other things. You can ask the asset to load its content from wherever it's coming from. And then you can ask it to dump that content out so you can do something with it. It's part of the interface. There are more methods defined on there. Ascetic provides a few basic implementations of that asset interface. As you can see here, we can define an asset from a string. We can define an asset from a file. Or you can define an asset from an HTTP request. So here, this is an example of defining an asset from a string. The first argument in the constructor for the string asset is the content of the asset itself. So as you can see, we're defining a JavaScript asset here. A very simple one that says alert the string high. Very friendly. As I said before, there's this loading process and there's this dumping process that each asset goes through. The load is actually implied by calling dump. So I'm going to get rid of that for the rest of the talk and we're just going to talk in terms of dumping the content out. When you call dump, it'll check to see if the content has been loaded from the source. If not, it'll go ahead and do that for you. So that's the string asset. It's pretty straightforward. Not very exciting. Then we have the file asset. This is an asset which is defined on your file system. So you provide the path to that asset in the constructor and then you can dump out the contents of that to the browser or however you want to use it. So it's pretty straightforward. What we have here is pretty much the same as calling echo file get contents. But we are doing it in an object-oriented way. We've modeled the problem of assets in the browser as objects in PHP. And now we have different implementations of that interface. And then the third one that we just talked about, HTTP asset, we can reference a JavaScript file that is up on a server somewhere on the great big worldwide web. Load that in and then call dump and we'll get the contents from that. So those are the three basic implementations of the asset interface. There are some other special ones as well. As you can see here, the collection, the glob, the cache and the reference. So these are all four of these implement the same interface as the first three that we just looked at. But they do slightly different things. But once you have an asset, once you instantiate one of these implementations of the asset interface, you can treat it like an asset. It doesn't matter where it came from anymore. It's an asset. It fulfills this interface, the asset interface. So once everything comes into one of these objects, again, they're all the same in the eyes of a static because they implement the asset interface. The asset collection, first of these special implementations, this is how you would take multiple assets and merge them together into one asset. So one asset collection is a composition of multiple assets. Each of these assets inside of it, the string asset and the file asset both implement the asset interface. Asset collection itself implements the asset interface. So you can imagine having a much deeper tree of assets than this. If you wanted, you could have an asset collection that wraps an asset collection with other assets in addition to a single string asset, etc., etc. Since everything implements the asset interface, they can be used interchangeably, and they all work very well together. The glob asset is an extension of the asset collection. It works using the php glob functions pretty straightforward on the inside. So you can see here that we have one asset, which is loading up everything from inside the JavaScript directory there that ends with the js extension. So one object, it'll take all of those assets, all of those JavaScript files, merge them into one big blob of content, and that becomes one asset. Then the cache, this is an asset. The asset cache implements the asset interface, although it also accepts a cache argument. So if you don't want to access the files, if you don't want to access open an HTTP connection every time you need that, we take the HTTP asset, we wrap it in the asset cache, provide a caching back end, in this case APC, and then when we access the A object, the A variable here, we interact with it as an implementation of the asset interface. It doesn't matter to us whether it's an asset cache or an HTTP asset, it behaves the same way because it fulfills that contract. And the last one that we were just of those special ones is the asset reference here. In this one, you can create an object, a proxy that references an asset that's available somewhere else in your system. So we have a class which you can add assets to and assign a name to each asset, and then using an asset reference, you pass in that asset manager which is more of a registry, and the name of the asset which is registered to the asset manager there. So using this, the asset reference implements the asset interface, and you can interact with it in the same way as you would any other asset implementation. So far, so good? Am I talking too fast? Okay. So asset reference is, the asset reference is an implementation of the asset interface. So it has all those methods on it, and has get content, and has get last modified, but it is not itself an asset. So it's one object here, and it is referencing another asset over here via the asset manager. So if you want to use an asset by name, what this allows you to do is to say, give me the, it provides another layer of abstraction, you can say, give me the asset by the name of high. And then you don't even need to worry about where it came from. You can just use the high asset, you can use the jQuery asset, and then behind that it can be an HTTP request to the Google CDN or it can be access from your file system. So it's another layer of abstraction. You can reference an asset by its name. Excuse me. Okay, so we have things modeled. We've taken this idea of an asset of a CSS or a JavaScript and modeled it in PHP using objects. So we're part of the way there. We have some something to work with, but the problem still persists that we're experiencing a lot of slowness by the, all of these assets being loaded into your web page. Here's a screenshot of the Yahoo page about speeding up your website. There's some very good information here. If you install Y Slow on your browser, then you'll get this on a page by page basis, and you can see how you're performing. And then this is the developer site details the principles behind it and how you might improve your site. What it comes down to is fewer requests. So as you saw earlier, we had the asset collection interface that'll take multiple assets, which would otherwise be multiple script tags on your site, and it'll combine them into one asset. And then you can dump that whole blob of the multiple JavaScripts into one asset, one HTTP request, instead of multiple requests. There's a question back here. Yeah, there are other ways to do it. You can get into asynchronous JavaScript requests using something like require.js as a loader, which is a pattern that I'm very fond of. I don't know. I've been mulling over that a lot and trying to figure out where Ascetic fits into that way of doing things, but in my experience, it's hard to get the two of them to work together, so you have to pick an approach up front and say, are you going to go with the more traditional synchronous approach, or you can go with the asynchronous JavaScript through require.js or some other sort of asynchronous loader? Does Ascetic work? What is bless? Sorry, could you come to the microphone? You're speaking very... I'll sum this up. It sounds like there's a tool called bless, which will help you prevent you from hitting the limit of the number of CSS selectors, i.e. what version? And we'll get to that. I wasn't familiar with that particular tool, but you'll see how Ascetic helps you integrate with those sorts of tools. So back to the problem of things being slow, fewer requests, and then also smaller responses. So much like you were just talking about Ryan, there are a lot of tools out there that allow us to do things like take one JavaScript file and make it much smaller, a smaller response, something like an Uglify or the UE compressor, a lot of tools out there. So what we do in Ascetic is try to help get you to those tools. Make it easy to use them inside of a PHP application. If you look at all of these tools here, here is just a selection of some of the tools that Ascetic supports, CSS embed. You can, this is a, I think, a Java tool that will allow you to take images that are referenced, excuse me, from a CSS file and move them in line. So if they're smaller than a certain number of bytes, CSS embed will take those and move them in line, so it doesn't cause another HTTP request. Google closure, JPEG, Optum JPEG trail, there's a few tools here for taking your images and making them smaller, stripping out a lot of metadata that's not necessary. Ping out. PHP CSS embed is a PHP implementation of the CSS embed tool. UE compressor, which has actually been deprecated in favor of Uglify. And a few other tools here. I think JSmin is a PHP tool for minifying your assets. So there's a lot of tools out there. We don't need to, Ascetic doesn't need to spend time and waste developers time reinventing this wheel of how to take a response and make it smaller. There's a lot of tools out there that we can use. Or in the case of CSS embed to reduce the number of HTTP requests. So instead of reinventing the wheel, we provide an API for accessing these third party tools that are already used and very successful at what they do. Another problem I want to touch on is that development can be kind of tedious sometimes. I love CSS, but I really can't stand it. There are tools out there that make it a much more pleasant experience. Same with JavaScript, I get along better with JavaScript than I do with CSS, but still there are tools out there that help to speed up your workflow, make it easier to use more modern patterns and these tools, which are now kind of old CSS and JavaScript. So of course, Ascetic solves that by bringing you closer to even more tools. Some of those being CoffeeScript. This is a JavaScript pre-compilation. So you take something you write in and this syntax that looks more like Ruby or Python or something other than JavaScript and then it'll compile it into JavaScript. Compass, which is an extension of SAS. Dart, less-pactured TypeScript. Rule. So these are all tools that will make development a little less tedious and allow you to do things much easier. And then they, so they provide a special syntax that you write your styles or your JavaScript in and then it takes care of compiling it down to JavaScript or CSS. So you can see one of the main principles of Ascetic is that we don't want to reinvent the wheel. Ascetic is trying to help you reach out and grab the wheel, but we're not going to reinvent it for you. There's a lot of wheels out there that work perfectly well. And the way we do that, similar to what we did with Assettox, excuse me, assets, we're going to start by modeling the problem. In the world of Ascetic, all these tools are accessible to you through what are called filters. This is the filter interface. Different filters will interact with the asset at different times. If you remember earlier, we talked about an asset having a load where it pulls the content from whatever the source is and then having a dump where the content leaves the asset. So when you're working with a filter, sometimes you're going to want to filter as it's loading. In the case of something like CoffeeScript or SAS, you're going to want to filter that third-party syntax into the normalized version into JavaScript or CSS so that your asset includes the CSS and it can work well together with other CSS assets. And in other cases, you're going to want to act on your assets when it's being dumped. In the case of minification, you're not going to want to load in to have an asset that is full of minified JavaScript. If you can avoid it, you're going to want to minify it as that content is leaving the asset. So something like Uglify or UE Compressor, the other minification tools would act on an asset during the dump phase. So I have this nice little demonstration here. So this is another asset, as you can see. And you'll remember it has the load and the dump. And what we can do with filters is intercept that load process so that we have CoffeeScript coming in from the source. And once that content comes into the asset, it's now JavaScript. And we can add many filters up in the front there. We can add more and more and more. Say we want to have something that compiles down to CoffeeScript, for some reason, I don't know. And then if you wanted to compile down from CoffeeScript to JavaScript, et cetera, et cetera. So you can have multiple filters on each of your assets. So the content inside of your asset here is JavaScript. And then when you go to dump the asset, you can filter it again through something like Aglifieds.js or another minification tool. And whereas in the content of the asset, you would have something like my variable, it would now be minified to var underscore a. And it's that dumped content which would then come out of the asset for use. The asset itself is not minified, but the content is minified on the way out of the asset. So we have a number of filters inside of the ascetic core. I've categorized them here. So these are the filters that act when you load in JavaScript. You can do CoffeeScript, Dart, Precompile, Ember templates, Handlebarr templates, TypeScript, Sprockets. This is Sprockets v1 where they have a little syntax where you can say this JavaScript file should also include this JavaScript file and it'll get merged in there. So we wrap around Sprockets. You can use that similar to Packager. This is Packager or something that came out of the MooTools community. We have filters for acting on the load of CSS files. These are the pre-compliation tools that we're talking about. GSS, Google CSS. You've probably never heard of it. It's another successful Google project. Compass, CSS import, rule, SAS, SCSS, PHP, stylus. Question back here? Have you heard of CSS min? CSS min? It's designed to basically go out, go around, and look for unused CSS. It sounds like we have something called CSS min. It's a pretty generic name, so I don't know if it's the same project you're talking about. I think it's called... So there are a lot of tools. Also tools on the dumping side for dumping JS. This is mostly going to minify what you have. And then for dumping CSS, CSS embed is the one that merges image data into your style sheet. And that happens on the dump when you dump that CSS file. And we've been talking a lot about JavaScript and CSS, but there are also filters that allow you to act on your images to take an image that is a lot bigger than it needs to be because it includes a lot of metadata. There's a lot of metadata that can be added to JPEGs, and most cameras these days will add a ton. And by sending it through something like JPEG Optum for a JPEG or a PingOut or OptiPing for Pings, it will dramatically reduce the size of those image files. This is how you're going to be using filters with assets in the PHP code. Another method on the asset interface is ensure filter. So just like the name suggests, the filter can be added to an asset if it's not there already. If it's already there, then we don't add it again. That's why it's called ensure. Ensure that that filter is applied to that asset, pass the filter in. So it's something like we were talking about earlier, CoffeeScript becoming JavaScript, becoming minified JavaScript. That might look like this in your PHP code. You open up a new file, an asset that's loaded from the file app.coffee, add the CoffeeScript filter, and then add the AglifyJS version 2 filter. Each of the asset implementations also includes their own constructor. So if you check the documentation, most of those implementations will accept an array of filters when you're first creating that object. So this is the same as that previous slide of the call to ensure filter. You're showing them right next to each other. One is described as a load filter and one is a dump filter. Do the filters know which one they are? Yeah, if you go back to the filter interface, there are two methods on the filter interface. One for filtering the load and one for filtering the dump. So it is possible for a filter to do work on both sides. There are none on the core that do that. But the filter gets to choose what it does. Okay, next problem. So we have these assets. We have this nice API for modeling assets and this nice API for modeling the tools that we want to use to work on those assets to do various things to them. The question now is, now what? We have them. We need to serve them. So one option would be to have an app.php inside of the JavaScript directory that creates these asset objects, adds the filters to them, and then dumps out that content to the web with an appropriate content type. Does anyone see any issues with this approach? Excuse me? Well, it's an app.php, I don't know how to do it. Well, you would have source, script tag source is js slash app.php. This is not what I'm suggesting. I'm trying to figure out what's wrong with it. Anyone see? Every time that you're, every time that the browser hits app.php, it's going to access that asset from the file system. It's going to load up coffee script and ugly files. So you're going to be running, you're going to be shelling out two commands, because that's what happens in the background in order to work with these two node.js libraries. We go through the command line through the symphony process component. That's going to happen every time. So you're going to quickly see your servers crashing into nothingness. You had a question back there? You could certainly add HTTP caching headers to it, cache control, and then if you're behind a proxy or if you're behind a CDN, even better, that would provide good caching. But if you're not behind one of those, if you're not behind a public cache, then relying on the private cache, that'd still be a lot of requests coming in in the server having to work with these to shell out a lot of work to node. But I think what you might have been suggesting is to use the asset cache object here. So we can do that. We can take the asset that we created, what was it app.coffee or whatever, pass it into the asset cache, wrap it in an asset cache object, provide an APC backend, and then it'll, the first time it will compile the asset, run it through those filters, and then it'll store the results to APC so that the next time it is faster. But this is still not ideal because your assets come in and then it loads up PHP, and PHP is not the lightest thing in the world, so it doesn't make sense to serve PHP, to open up PHP every time you need to serve an asset. Coming back to the idea of not reinventing the wheel, there are a lot of tools out there that do really well, a really good job at serving flat files. So what we need to do is take our assets and compile them down, dump them to flat files, and then serve them up with IngenX or Apache or something that knows how to do this in its sleep. PHP doesn't need to be involved. So inside of Ascetic, we have something called the asset writer. You can take all of your assets, add them to an asset manager, this is the same registry object that we were looking at earlier, pass the assets in, provide a name for each asset, and then load up an asset writer. You can see when we create the asset, we set a target path on it so that the asset knows where it should, where it needs to end up. It'll end up in the js slash app.js file inside of down here, the writer knows where its base directory is. So after running this, you would see a js app.js file inside of the web directory. And of course, you can load up all of the assets necessary, all of the assets that your site requires, and add them to the asset manager and then just ask this little helper object called the asset writer to write all of those to the file system. And then once they're there, PHP doesn't need to be involved anymore because your web server will serve those up. You can configure your web server with caching headers for js files or css files if you'd like or image files, you could run images through this in a similar way as well. Okay, so we're pretty good in terms of how to serve these assets. The problem, the next problem, this is a complicated problem. There's this asset management is not simple. Once you think you solved one thing, another thing comes up. So in this case, the problem is how to reference these files that were just generated and are now dumped to your file system. How do we reference them? We could do, well, for the first solution on how to serve up these assets, if we're going to do it in PHP, then we just reference it like this. That's not a good solution. So we could do this and reference it with js slash app.js in a script tag. This works, but say in development that you're working in this template here and you realize that you want to start using underscore.js, maybe you have jQuery and they're already and you want to do some groovy functional things. So you want to load an underscore.js. So how would you do that? You'd have to stop and think and say, okay, so there's app.js there. And I need to add underscore js to it. So I should go over to the file where I define all of my assets, I should add an asset collection and put. So it's not, it comes up the gears, right? Everything is not right there in front of you. So you could do something like this. You could reference we have another little layer of abstraction here an asset function that you could use inside of PHP referencing an asset by name. So it does provide some abstraction if you went to your configuration and added underscore to it and then wanted to change the name that of the file that gets created to js slash app app v2 or whatever. You could do that and not have to mess with your template code just deal with where your asset assets are created and then dump them out to the file system. But still it doesn't solve that problem of it doesn't solve the disconnect that you as a developer are going to be facing when you are working in your template and want to get underscore in there, you have to stop and think that, okay, I need to go back to this other file. So I want to fix that I want I want everything to be right here in the template. I want if I want to add underscore dot js, I just want to add add something to the code up here to the script tag. And then I want underscore dot js to be there. Okay. So the way ascetic solves this is somewhat unique. It actually looks at your template files as configuration files. So we're kind of getting into the, you know, the second tier, a more advanced side of ascetic. Let me be clear that the core of ascetic is this idea of assets and filters and how they interact together. And you can do anything you can take those two concepts and run with them use some of the filters that we have or add new filters of your own. What we've done inside of ascetic and is take those two concepts and and try to smooth out the process of development by having this configuration be in the context of your template. So what ascetic actually does is it parses whatever template files you configure as configuration. So what we have here is this is a function that actually exists inside of ascetic. You can see that we're asking ascetic to create a JavaScript asset. And in it, we're going to include app dot coffee. So that's that first array is telling ascetic what assets we want to include in this asset we're creating. Second argument is a list of filters that we want to have applied to that asset. And the third argument is an array of options. So we want to specify where the file should be output when ascetic goes to create it. So loading this particular file, if this this file now serves two purposes, it will be interpreted by PHP and rendered as a template file on the one hand. On the other hand, ascetic is going to process parse this file as a configuration file in a static context. It doesn't actually run the file. It tokenizes it looks at it pulls out the asset that you've configured by using this function adds it to the asset manager. And then it knows that it needs to create that asset on your file system. So you can see we're trying to tie it all together here. There's a new concept behind that slide we just looked at. There's something called a filter manager where you can reference a filter by name. You can see here that we're creating the coffee script filter and assigning it the name coffee, and adding it to the filter manager. So now we have an abstraction between filter, a filter object, and we can reference it by a name. So we could have multiple coffee script filters, perhaps one that's configured to change all the variable names to underscore a or whatever it does. And then another that's configured to leave the variable names alone, but still do the other modification processes. So we can have each of those assigned to the filter manager with different names. And then when we want to run an asset through different filters, we would reference it by the correct name. The other concept that we've added is an asset factory, because as you saw on that first line of the ascetic JavaScript function in the template file, we're loading assets in by by name, we're not actually instantiating asset objects in our templates, we're referencing an asset by name. So quote j s slash app dot coffee is a string, and we need something that's going to turn that string into an object. And that's where the asset factory comes in. asset factory needs to be aware of the filter manager because it's also going to receive that array of filters that you want this asset to go through. So we have an asset factory, which knows how to take a string and turn it into an asset. So if it's a string that starts with HTTP, then it's going to use an HTTP asset to give you that. If the string starts with, we have a little notation that starts with an at. So if it's at and then a name, it knows that that's an asset reference, and it will provide an asset reference object for you. And then the classes that actually do the static evaluation of your template files to extract those assets. This is really advanced an advanced part of a static, but this is what it would look like. You have a concept of a loader and then you have a concept of a resource. And you put those together inside of a lazy asset manager. And the asset manager will then load take each of the resources it's been given and run them through the appropriate loaders. And those loaders know how to extract asset definitions from those resources. And then the asset manager will know the full suite of assets that are available to it. All right, so that was really a whistle-stop tour through the current state of aesthetic. I do want to talk a little bit about the future of aesthetic, because like I said earlier, there are problems that aesthetic has solved and there are also problems that aesthetic has created. A lot of those problems that it's created have to do with the development process. Centering around this question of how when you're in the process of development, what is the fastest way for aesthetic to detect that a change has been made to one of your source assets and then recompile that asset and present it to you in development so that you don't have to, whenever you make a change, go back to the command line and say recompile or whatever. So the way it gets kind of complicated, because you can see here that we have a profile sass, and that profile sass file includes color sass. This is a sass partial. So whenever the colors sass file is changed, we don't recompile the partial, we need to recompile a profile and aesthetic needs to be smart enough to know that there is this relationship, that profile sass includes colors.sass. And there's another relationship here, you can see profile.sass might have some background images, background.gif or logo.ping, and aesthetic doesn't know about this. We'll get to the references later. So let's say we're able to go out and just check each asset. We load up the asset manager, loop through each asset, see if it's changed, and then rebuild it if necessary and then sleep. You can see how this might be too much. If you have a couple hundred assets, I don't know, that's a lot, but the more assets that you have, the longer it's going to take aesthetic to go through each of these runs. What's more, if you're using the template files as configuration files trick, every time it starts this loop, it has to scan each of those files to see if you've made any changes to your asset ecosystem. It has to include any of those changes and then second, it needs to go through the file system and see if there have been any changes. So this is a problem, right? It can take, it can really bog down your system. And if you're running on something like Vagrant, which is going through a shared directory, it can be a huge headache. So the solution that I'm very interested in is pushing. Instead of pulling, instead of pulling the file system or pulling your template files, for it to have the file system notify aesthetic that something has changed. And there are tools out there that issue events from the file system. So this is a nice PHP library. Right now it only wraps iNotify, which is a Linux, which is the Linux file system notification tool. Check this out. The version one was just released a few weeks ago, but this is a PHP abstraction on top of file system events. So in development with aesthetic, this would be very handy to have it tell aesthetic that this file has changed. Instead of aesthetic having to, you know, every five seconds, every two seconds, however, however often you tell it to do it, to go out and check every single template file and have it go out and check every single asset. And most of the time, nothing's changing. So that's a lot of wasted work. And it slows things down. So we can just take that whole system and throw it out the window and ask the file system to notify us if something changes. So this is a little chunk of code off of the lurker site, you have a resource watcher, you ask it to track anything in the views directory, and then you add a listener to that event. So if we have any, if this directory wanted, we want to call any change that's made inside of this directory, a twig change, and we can listen for any twig changes. And if we see one, then we can act accordingly. So you set up the watcher, you call start, and it's just running in the background waiting to hear from the file system. It's not, it's not doing much. It's just sitting there. Much nicer. So then the problem that that creates, now that we're listening to these events, and we have this nice notification that says, Hey, colors dot sass just changed. So that comes into ascetic and ascetic says, Great. Now what? Okay, how does ascetic know what to do if this sass partial was changed? colors dot sass, let's call that it. So we could, once this event comes in, we could loop over all of the assets that we have in our little asset manager here. We have a nice whole asset ecosystem encapsulated in one object called the asset manager. And we can loop through that and somehow figure out if the asset that were, if each individual asset is affected by this change to the colors partial. So we're going to have to know if, if this, if asset a includes that colors partial, and then if it does, then we'll go ahead and recompile it. But how does ascetic know that we'd have to do some something like this, which again, looping over your entire set of assets is less than ideal. It's a lot better than looping over everything every two seconds. But still, this is a nasty loop, we can get rid of it. So what I've been talking about is how assets are related. And the best way to model relationships is through a graph, through something like Neo4j, that's a very nice graphing database out there. So is there some way that ascetic can take the universe, the ecosystem of assets loaded into the ascetic, into a graph in a tool like Neo4j or perhaps a file system implementation of a graph database, and use that graph to determine what to do when change is notified. So we get the notifications from the file system. If we have a graph that represents all the, how all of our assets are related, then we'll be able to do something like that. So here's one graph, we've got profile sass, which includes color sass. Color sass is included by profile sass. Profile sass references background gif. Background gif is referenced by profile sass. So if you're not familiar with graphing databases or this concept of an object graph, it's composed of nodes. In our case, nodes are the assets. So each asset is a node inside of the graph. And then the relationships between those assets, one asset including another asset, those are edges. So nodes and edges. Here's one way that we might be able to use this graph. Say that we want to know when the profile.sass asset, this object inside of ascetic was last modified, we can ask the graph to give us all of the assets that are included by profile.sass, or I should say all the assets that profile.sass includes. So it's a very simple query. When you're dealing with graph database, it can go a lot farther than what you see here. This is just one hop. But if this asset then includes another asset, which includes three assets, a graphing database knows how to deal with it and knows how to deal with it fast. So it can pull up all of those assets that are included by your top level asset, loop over them and figure out which one was most recently modified. And then you have a last modified time for that asset and ascetic will know. It can use that time stamp when it's serving up a cash control header, or a last modified header, excuse me. And it can also determine whether or not a certain hard copy of that compiled asset is fresh or stale. Another use of the graph database is what we're just talking about. If color.sass is changed, what do we do? We got this notification from Lurker from iNotify. Now what do we do with it? Well, in the database, we can ask for any assets which include the colors, partial, and then recompile each of those. So we just ask the database, it gives us a list, and then we loop through that list and do what we need to do. Lastly, coming back to this idea of references, if profile.sass references background.gif, let's say that you have all of your assets, all of your sass files in a directory that is outside of the web directory, but you want to take the profile.sass and compile it down to CSS and then put that CSS file in your web directory. What happens to that reference from the profile.sass to background.gif? Assettock doesn't take background.gif and move it. It only takes profile.sass and moves it, so now you have a broken URL. If the ecosystem of your assets is saved into a graphing database, then you can ask the database for all of the assets which this asset references, and then when you're installing that asset to the file system, you can also pick up all of those referenced assets and move them as well. You can move any assets that that asset references. If you have an app import in your CSS and the imported asset includes references to other images, then the graphing database will traverse the entire graph of your assets and it will give you everything you need. We're running a little short on time, but I also wanted to talk a little bit about the design of Assettock. It's a little game of thrones to me right now. This asset object wants to do everything at once at all, at once all seven realms. So much happens inside of the asset object. If you take a look at the HTTP asset, so inside of this there's just a call to file get contents. So that's hard coded in there. If you want to use another means to get your HTTP assets, you'd have to implement your own asset object. So how do we configure the HTTP asset to go through a proxy? How do we configure authentication? How do we mock out the HTTP connection so we can unit test this object? How do we log whenever an HTTP request is made in this object? How do we profile it? What if we want to switch to curl? What if we want to use a service like Guzzle? There's a lot of problems. So the role, the responsibility of the asset object, which is where we started, is to represent an asset and it's doing a lot more than that right now. So that presents problems in the library, which in the next version it's going to be a much more paired down asset object is mostly just a bag because an asset, if an asset is a node in a graph database, a node contains parameters, it's a bag. So the asset will be very much more simpler. And all these concerns that are currently jammed in to the asset object will be separated to other services. So instead of something like Game of Thrones, we'll have more of this pleasant experience of everyone working well together for the most part and getting something, getting it done in a very clean manner. We'll have services that are responsible for loading the asset from whatever the source is, services that are responsible for determining what filters should be applied to an asset, services responsible for reflecting an asset so we can figure out what relationships there are responsible for the optimization. Another problem is this issue of maintenance. The asset ascetic core, like we saw earlier, these are neat slides to be able to throw up. So you look at all these libraries we support, but who's going to maintain all these filters? There's about 40 of them crammed into the core right now. Most of them I don't use. So a pull request comes in for a particular filter and it, I don't know, like I don't use this filter. Why am I responsible for maintaining changes to this filter? Which I have no idea why it's there. I mean, I guess I merge it, but so it ends up just getting in a lot of pings and I just kind of sit in the stair and then, okay, I'll learn about what this third party tool is and decide if this is a good change or not. So maintenance, there's a lot of problems there. The solution is going to be making the library a little more opinionated. So we're not going to support all of these, any tool that you can imagine. You saw earlier there was CSS embed and then there's PHP CSS embed, but that's not the name of the project. The name of the PHP project is also CSS embed. So if we're loading all of these into one library, then we have all these naming problems that come up because we're trying to fit them all into one namespace and we have to start putting prefixes on them or sub namespaces. So ascetic is going to become much more opinionated. We know the kinds of things that you're probably going to want to do and we're going to provide one solution for each of those things. If you want to optimize your JavaScript, then we'll provide one solution for that, not 12. Engines for pre-compilation, optimizing CSS and JPEG will make a decision. You can go with it or you can change it and choose your own tool or swap out a PHP implementation for a node implementation if you want. All of this is vapor. I have some code, nothing is up, but I felt like I should get up here and talk a little bit about it. I just want to make sure this disclaimer is up there. So I'm a widowed father of three and I don't have a lot of time. So there are a lot of things to do and not a lot of time to do it. So if anyone out there wants to get involved, you can of course come into the projects and start working with us. Or if you have a company that wants to sponsor aesthetic and actually get some momentum going again, please contact me. Please follow me and please hire me. I do all of these things. I'm working as a consultant right now. If you want to know more about symphony, we can connect over Google Hangouts or Skype or what not and I can walk you through a training, a workshop. We can work with your code. I can work with your team. Work on performance, any of these tools here and more. Any questions? I'll just repeat it. You were wondering why. Well, they're separate. It makes sense to me that there should be a kind of normalized state. So he was asking why filters are separated between this load phase and the dump phase. One of the things that you might want to do in development, say you're not going to want to minify all of your JavaScripts in development because it makes debugging really hard. So you might say just switch off all of those dump filters. So they're mostly for that reason for having assets in a kind of common normalized state in the object so you can work with them if you want to and then dumping them out. Any other questions? Right, that doesn't apply. We're using Louis asking about the new Zend optimizer cache. So it's my understanding and correct me if I'm wrong that APC, the ops code caching of APC is now deprecated. If you're on PHP 5.5, you'll use the new Zend cache optimizer or optimizer. But APC will still be around to as a key value store. And that's how we use it. Any more questions? Okay. Thank you everybody.