Good afternoon everybody. Is this too loud? Not loud enough? Good? I guess it's good. Okay. So my name is Wim Leers and this session is about building really fast websites. And I'm a speed freak. So I really hated my website slow slowly.  At least that's what I do. So my goal is really to have every website load fast. Some mobile devices are not. So I actually work for Acquia on the Spark project which you may know. But that doesn't mean that I work just on Spark stuff. I also work on related stuff in Drupal 8. Or in the past few months I've been spending some time working on performance improvement specifically in Drupal 8. And this talk is going to be about some of the improvements in Drupal 8 that should make your lives easier, your sites faster and your sites more scalable. These are not things that were built just by me. These are things that were built by community, by consensus. Lots of smart people collaborated on this. And these are just, this is not everything. This is just a few things that I find personally really interesting. So there are patterns that are applied in Drupal 8, some of which you can apply in Drupal 7 as well. And I hope that they are of use to you as well and that you can really leverage them. So hopefully you'll find it interesting. So what this talk is about, what Drupal 8 is better than 7, render caching, client-side caching, and pluggable CSS and JavaScript optimization, which is a whole lot of words. But you'll see that it's actually really interesting and not that hard anymore in Drupal 8. And of course some of the things that we should have and hopefully we'll have, but that aren't there yet. So some of the things that still need to happen. So let's get started. The first thing, my personal website was for a very long time on Drupal 5 until 2011 when Drupal 7 was already around for quite some time. And I didn't find the time to upgrade it to 6, so I skipped 6, went from 5 to 7. And since I am a speed freak, I really care about performance, I wanted to make sure that my website learned it as fast as possible. So it could be some sort of example of how you can make a simple website, of course, because it's not complex, how you can make it fast. And to my surprise, and I'm not sure if many of you have noticed this or if many of you have tried this, but if you try to make a website on Drupal 7, or even a single page, load with our JavaScript. Good luck, but it won't work because Drupal 7 will always load jQuery.js, Drupal.js, and Drupal settings. So that's not so great, of course. And in Drupal 7, we fixed that. So in Drupal 8, we fixed that, of course, not 7. So in Drupal 8, what we're doing is two important things. We're declaring all dependencies. So whenever you load a certain assets, you declare which things it depends upon.  And we're using pound attached or hash attached instead of Drupal at CSS, Drupal at JS, and Drupal at library. And I'll explain why that's much better in a second. And sadly, this problem, as in the problem of jQuery.js, Drupal.js, and Drupal settings always loading, is something that is utterly unfixable in Drupal 7 unless you break the API. And Attic, I'm not sure if he's here, Peter Druckmans, a Belgian guy. He's bravely working on a workaround, but it relies on a settings.php setting that essentially changes the API. So there is no way to make it work good in Drupal 7 out of the box without breaking the API, hence breaking all of contrib. So we can do that, but we can't, you can't fix it for individual size by applying his patch. Hopefully it will end in core. And then you can do it as well, but then you will have to declare all your dependencies. And if you use contributed modules that don't do that, you'll have to update those. In any case, let's take a look at the fix. So if you look at an example of a.js file, for example, table select.js in Drupal 8, there is some JavaScript in there, and we're using two things that aren't part of JavaScript itself. We're using Drupal. Drupal behaviors is what you see up there. And we're also using jQuery, the dollar sign, dollar context. So those are the two things we're using. And if we're using those, then we should import them into the current closure. So jQuery is used, Drupal is used, and you see these things at the top and at the bottom of the code example. What we're doing essentially is we're declaring, we're using jQuery, we're declaring we're using Drupal, the Drupal object that is available through Drupal.js, and we put them in the closure. So we rename jQuery to dollar sign, so that's easier to use. That's the convention. You can rename it to llama if you want. It doesn't matter. So if you use it, you declare it in the closure. I keep pressing the wrong key. This is the right one. So that's the JavaScript side. You declare your dependencies by putting them in the closure. The second step is to do the similar thing on the PHP side because Drupal needs to know which things it needs to load, so the PHP needs to know, right? So we have tables like.js in the library, but the library also declares two dependencies, one on jQuery, one on Drupal. Very simple. So the rule is jQuery and Drupal are in the closure of the JavaScript file, so we should also declare dependencies on the PHP side. Very simple. The next step is to abandon Drupal at CSS and JS because we don't want individual assets anymore because you can declare dependencies for those. So instead, you should use Drupal at library. You should always, always use libraries because then you can declare the dependencies properly. However, you should also abandon Drupal at library because you should be using bar in the touched. So what you're doing is essentially the same thing, but you're doing it in a slightly different way. And the reason you can't use a Drupal at functions anymore is because they use global state and that breaks caching. Because, for example, if you have a block and that block uses foo.css and you add it through Drupal at CSS and it's then cached in the render cache in the server, in the database, and then you retrieve it at later point in time because some other page wants to use that, then the Drupal at CSS call won't occur anymore because the code that generated the block won't be run because it's already cached, the HTML is cached in the database, you retrieve it, hence the CSS won't be added, hence your side breaks, or at least won't look as it should look. So don't use the Drupal at functions, you can do it in Drupal 7, you can use parent attached in Drupal 7 as well, because it breaks caching, just use parent attached always. The conclusion here is really simple, you should always load assets by attaching libraries. That's it. It results in better DX because there's less or no magic rather going on. You have cacheable render arrays, which you wouldn't have otherwise because if you use Drupal at functions, something is happening with lights. Okay. So you should always, an advantage is also that you have cacheable render arrays, which you wouldn't have otherwise because you would be calling Drupal at functions, only the required assets will be loading, so load it, so no more jQuery that is loaded while you don't even need it, and dynamic content, as in the one that you Ajax in, will also have the proper assets without having maybe the same asset loaded twice, or all sorts of weird things that can happen when you use a Drupal at functions. And all of this you can do in Drupal 7. So to prepare to move to Drupal 8, just do things correctly, or as well as you could in Drupal 7, and you'll be, asset wise, you'll be very, it'll be super easy to upgrade. So it's one thing, it's a tiny thing, but it can have a big impact. So the next thing, one of the things that has gotten much more expensive in Drupal 8 is the rendering of entities. And to get to Drupal 7 or better performance levels, we need to finally achieve render caching of entities. We've had the render cache API since 7, at least, maybe six, I don't think so, but we've had it in 7, but we aren't really putting it to use, because there are still too many things breaking the render cache, and that's what we're fixing in 8. So essentially what this means is, if render caching works for entities, then users with the same combinations of roles, for example, editor and authenticated, all those users, maybe 10, maybe 100, maybe 1,000, they will all get the same chunk of HTML without having to regenerate that HTML over and over and over again, which is pretty expensive. So the goal is essentially to really use render caching. It wasn't already available, but we weren't really using it. And the thing it was blocking it was we're not yet putting the right data in there, but we'll get to that in a second. So before, we're almost there. We're not yet there. We're almost there. While this conference was going on two days ago, the patch got committed that adds entity render caching, but it doesn't yet add the render caching for nos and comments, which are the most common entities, of course. So that's coming soon, but it's not there yet. We're almost there. But before we got there, we had to do quite a lot of things, and this is just a tiny selection of things. So cache tag support is something very cool, very interesting. You can do a lot of things with it, and it's useful for many things, not just for render caching. You should definitely look at it. Contextual links were fundamentally incompatible with the render cache. This is one of the reasons it couldn't work in Drupal 7. The new indicator, the new and updated indicators, the red small markers, they were also fundamentally incompatible. So that's another reason why Drupal 7 couldn't do that. So we're almost there, but still not yet. And that actually brings us to this nice quote that I'm sure most of you have already seen at some point in time. There are only two hard problems in computer science, naming things and cache invalidation. And naming things is irrelevant here. Cache invalidation, though, is very relevant, because caching itself is super easy. As in, you do this complex thing that is very expensive to do. You store it somewhere, and then you retrieve it later, so that you don't have to repeat the same expensive calculations over and over again. And that's easy. But once you start going to the point of invalidating things, as in determining when something in the cache should no longer be used, because it's inaccurate. Well, that's the hard part, because you can do it in a very efficient way, or you can do it in a very inefficient way. As in, you could clear everything if you change this, sorry, you could clear all the entries in the cache if you just change one thing. That works, but it's very inefficient, because then every cache entry has only a very short amount of time where it can make itself useful. Whereas if you clear just the things that are affected by changes on your website, it will be very efficient, because it needs to generate things far less often. So really, the reason for poor performance when you're using caching is poor cache invalidation. And that's the thing that we have to solve. So really, we want to first make sure the Drupal has solid cache invalidation, and only then we want to make sure that we fill the cache correctly. So, fill cache correctly and solid cache invalidation. Those are the two things that really matter. Before we continue, just a very small acronym, instead of me repeating it every time in full on the slides. Just like we have I18N for internationalization, you have also got P15N for personalization. So personalization, P15N. Let's start with the first one, cache invalidation. Cache invalidation is hard. I'm sure many, or if not all of you, have seen this particular page. It's a performance settings page in Drupal 7. And one thing is not blurred out. It's a thing that matters. It's a setting called cache pages for anonymous users. And I think most of you are familiar with this, but I'm not sure if most of you are familiar with the fact that if you enable this, which is fine in and of itself, but if you create any new node, or edit any node, or any anonymous user that creates a new comments, it will actually clear all of the cached pages. Everything. And that's not very great, is it? Because then you're not really using your cache properly. So it clears the entire page cache every single time. But the reason is that cache clearing in Drupal 7 only had a very limited API. So you could clear a specific cache entry, cache clear all, some ID, some cache bin. You could clear a course set of cache entries, meaning everything that is in the cache that matches a certain prefix. So everything that starts with full colon content colon, you can clear all those. And the final possibility that you have is clearing all cache entries in a cache bin. And that's, of course, the least efficient of all. So the question is, if I edit node 42, how can I clear all those cache entries just containing node 42? The answer is it's impossible in Drupal 7. You just don't have the API to do that because you can't know which cache entries all contain node 42. There is no way to predict all IDs, as in the cache IDs, that may contain node 42. Because any country module can create any sort of cache ID that it wants. And there is no way of figuring out which things it contains. So really, that's the crux of the problem. We couldn't do better cache invalidation in 7 because we didn't have the API for it. And now in Drupal 8, we have something new called cache tags. And that's really the thing that makes a lot of new things possible. So in Drupal 7, you had the cache underscore set function. This is the equivalent in Drupal 8. So you call the cache function, you specify a bin, you call the set method on it, you specify a cache ID, of course. You specify a value to be cached. You specify, for example, cache permanent, which means that it won't expire automatically. And then the new parameter tags. You can specify cache tags there. So they look somewhat like this. So if you want something in the page cache, you would specify the content cache tag. If it's just some HTML containing just a title of Node42 or maybe the author of Node42 or something of Node42, then you could tag it with Node42. And if it's a full node with, for example, two taxonomy terms, then it would look like this. A node, Node42, a user, the user's ID, which is the author. And then two taxonomy term IDs. And now you have all the information of the things that are embedded within the node, as in the things that are within the render cache entry. So really in Drupal 7, you could only clear one specific entry, all entries, or a core set of entries, which kind of is like this, but not really, because it doesn't allow you to find which specific entries contain a certain thing. This allows you to do that. And this is what enables much better cache handling. So using cache tags and render arrays in Drupal 8 looks somewhat like this. The keys and granularity parameters to the pound cache key already existed in 7. They are the things that make up the cache ID. They automatically generate a cache ID. But then the tags key is a new thing. And in this case, it's generic for all entities. So entity type expense to node, for example, in our example, entity ID expense 42. So this is tagged with Node42. But you may wonder, Node42, it does not contain just Node42, because also on the previous slide, what we saw up there was, for example, this. Node42, user 314, taxonomy term, do taxonomy term. So how do you do these two additional things get on there? Because this really only affects Node42. The answer is every field within a node is a child of the render array of the node. And what we're doing is we're traversing from the top level, which is the node itself, into the child levels, as in the fields themselves. And they also have cache tags. And we just collect them and put them at the top level. And that's what the triple render collect cache tags function does. It just merges, it collects all the cache tags that are relevant, puts them at the top level so we know which things are inside of the whole. And that's it, essentially. But clearing caches is what is what's called in Drupal 7. You can have the cache clear all. Now in 8, you have something slightly different. You have more granularity in what you can do. You can use delete tags, which means delete all cache entries that contain these tags immediately, which prevents still content because you delete stuff immediately. But there's also invalidated tags, which allows you to keep still content, because maybe your code doesn't really require you, or your use case maybe doesn't require you to have the very latest content. Maybe it's okay to serve slightly still content. In that case you can say invalidated tags, which merges them as outdated, but the cache entries are not deleted so you can still use them. So as you can see, you have more control of what you, depending on your use case. So we handled caching validation. I think, I hope it's pretty, you guys, that invalidation is a lot more flexible and fine grained and you can do a lot more with it in Drupal 8. So the next thing, caching is easy, right? That's what it feels like always. You just generate something, store it somewhere, that's caching. However, it'll be more interesting, I promise. Contextual links in Drupal 7, for example, it looked like this. It's a touch contextual links, but doesn't really matter. The thing in the top right hand corner is what the contextual links are in case you hadn't seen it yet. And that particular thing looks in the HTML somewhat like this. So there is a div containing a UL, containing links. Those links are access based, as in not every user has access to all these links. For example, an anonymous user doesn't have the ability to delete a node, right? So it's depending on the current user's permission. So it's role dependent. But not only that, you also see the query parameter to the URL. So there's question mark destination equals node. And that's path dependent. Because what it's doing is, it says, okay, if you click this link, you can go to the latest node. And then once that's done, you should be redirected to the destination is the node path, which is a front page in Drupal. So it's not only role dependent, but it's also path dependent. So really, there is a problem here because we have HTML that's embedded in the node's HTML. And it's adapted to the user's permissions and to the current page. And that just breaks render caching because this specific render cache entry, if it were to go into the render cache, would only be useful in very specific circumstances, which is this page. Imagine having 10,000 locations where this node appears. Then you would have 10,000 cache entries instead of just one. And that's of course not very ideal. So we have to figure out a way to make it work with render caching and still have the personalization because this is what personalization is, right? The links are to the specific current user. So in Drupal 8, what we did was instead of having the entire HTML like this, we made it look like this. Just a div that is an invisible placeholder with a data attribute that contains the relevant metadata that is used to generate the contextual links. It's also embedded in the node's HTML. However, it's an invisible placeholder that doesn't contain anything user specific, so it is compatible with the render cache. So how does this expand into the actual contextual links in Drupal 8? Well, we have the contextual IDs. That's what they are called. We have those in the HTML. We load some JavaScript that is only added to the page when the user actually has permission to use contextual links. And that JavaScript is going to make sure that the contextual links show up by posting those contextual IDs, the identifiers in the invisible placeholders to a certain path route in Drupal 8. And getting back the rendered contextual links. That's it. And the result is we have the same HTML for all users, so it can be served very fast immediately to all users. It's the same for everybody. And the personalization can be applied later. Yes? I wonder if there's anyone in the room that has a key to that. Okay. Can somebody turn off the lights because they were being turned off earlier? Thanks for saying that, by the way. Okay. I wish somebody gets spoken up sooner, though. In any case, I hope the explanations were sufficient in that case. So contextual links and contextual IDs in HTML, JavaScript loaded only if the current user can use contextual links, a request to the server to generate them, and then it's inserted into the page. Results, same HTML for all users. Personalization is applied later, as in not when the page is served, but only applied when the JavaScript is doing its thing. A similar story for the new comment marker. So you had the new marker and the updated marker for Drupal 8 comments, comments in general. And you see a small diff at the top of the slide. And before, it was really just printing the final result immediately. So it was calculating for every comment for the current user if the user had seen it already or not. And if so, apply a newer updated comment marker. And instead, what we're doing now is, again, a hidden placeholder with a data attribute that contains some useful metadata. That is the same for everybody. Another thing we're adding is because just a common timestamp, which is a data being added for each comments, is not sufficient to be able to figure out if the user has seen it already. We also need to know which node it is. So in HooknodeViewAlter, we're adding a data attribute to the node. So we can correlate the common timestamps with the node IDs and figure out what the appropriate marker is for the current user. So again, we have embedded stuff that's embedded in Node's HTML, again, an invisible placeholder, and again, compatible with the render cache. So the logic for this in AA is similar to what we just saw. Node ID, data attribute, common timestamp, data attribute, some JavaScript that is loaded only if authenticated because authenticated users are the only ones that can use or see rather in these markers. We've posted the node IDs in this case to a certain location on the server. We get the response back. The result is same HTML served to all users and the personalization is applied later through JavaScript. Tracker new and updated markers, which is similar, X New Commons links, it's all similar. The general gist is Drupal 7 user-specific data on HTML, which is problematic in Drupal 8. We have data attributes with universal truths, if you will, perhaps on invisible placeholders, perhaps somewhere else, like, for example, on the node. The node's HTML, of course. We load some JavaScript if the user has a proper permission. And only then we cache and then we cache user-specific data on the client side. And only if necessary, we talk to the server. So really, the conclusion here is to use cache tags precisely because if they're not the right ones or not granular enough, not specific enough, then they won't be of as much use as they could be. We tag render arrays with cache tags. You can delete cache tags to prevent still content, invalidate them to allow for still content, personalize via JavaScript and caching on the client side. That allows you to have cacheable render arrays, which can be served to everybody, at least to everybody with the same combination of roles. You apply universal truths through data attributes and you personalize through JavaScripts in combination with local storage, if you wish. So the upper half use cache tags precisely is about cache invalidation, which is a tricky part. And then cache filling, as long as you're not doing user-specific stuff, you're safe. And if you're doing user-specific stuff, use this approach. Now, that was render caching. The next thing is caching all the things on the client side. Because I think some of you, if not many of you, are thinking, didn't you make Drupal a whole lot slower? Well, the answer is so far from what you've seen so far. The answer is yes, because we have separate requests for the Drupal 8 toolbar to render the entire menu tree for the new and updated comment markers, for the contextual links and for in-place editing. So if you have all those things enabled, that's four separate requests, so from one request per page to five requests per page. And that's not great, of course. So let's take a step back and look at our goals. The goals are to make Drupal itself more scalable, as in more requests answered per second. The second thing is better perceived performance is what matters. Not better performance in general, but better perceived performance as in how fast the user sees things on his device. So what we're doing is, by serving HTML faster, because we don't need to personalize on the server side, we can just do very little computation on the server side and send HTML as fast as possible. We personalize via JavaScript, meaning that it doesn't have to happen on the server and we cache things on the client side. What we get then is, we get always a faster time to glass. And time to glass is really the time between requesting a page and actually seeing something appear on your screen. So it's always going to be faster because less calculations have to happen on the server side. And what we're doing is, we're just moving personalization from the server side to the client side. And then the personalization on the client side, what it's doing is, it's indeed making things slower if the cache is cold, meaning there is nothing in local storage, nothing in the client side cache, because now we would need five requests per page, which is not very great. But it won't happen every time because once the cache is warm, it will think things will be a lot faster because imagine that you have to send the entire toolbar menu tree, which is the entire admin menu tree, which can be quite large if you install additional contributed modules, which everybody does, right? And you have to send those many kilobytes of HTML with every single page request that will make things quite a bit slower. And if you can just cache it on the client side and use it from there, it will be a lot faster. So really, what this is about is about having an HTML skeleton contains the main contents of the page plus JavaScript personalization. That's going to be faster as long as the client side cache is warm. And another important fact that I think many of us in the Drupal world have forgotten is more personalization implies a slower website because how many of you did think of the fact that something simple, stupid, tiny, as the common new and updated markers were actually making your site slower? And there's many of these kind of subtle, small things that we are maybe forgetting about and that we really should take into account if we want to make our websites faster and as fast as possible, really. So the real question here is how to keep the cache warm? Because as long as the cache is nice and warm, things will be faster, especially on mobile devices. And that brings us to, again, the same quote, essentially. Cache invalidation is really hard. So not only do we have to solve it on the server side with cache tags, render arrays, and so on, but we also have to solve it on the client side because, again, caching is easy. Poor cache invalidation is hard and poor cache invalidation. That's what really leads to poor performance. So let's look at an example. An example is a toolbar in Drupal 8. Before the optimization that went in, I think, last week, we had one HTTP request per page to load the menu tree that you see on the left-hand side. And that's not good, of course. That's very, very bad. But now, after the optimization, we only have one setting per page. As in a one tiny string of information, that's it. That's the only overhead we have. And how do we do it there? Well, in the page build, which is kind of like hook in it in Drupal 7, what we're doing there is we're adding a setting that contains a hash, a hash that identifies the content that should be cached on the client side. And we make sure, of course, that calculating the hash itself is also fast because otherwise this is expensive and we're not really winning anything. And this hash is what identifies the toolbar menu tree that we should have on the client side cache. And it depends. It changes whenever a role's permissions change, a user's role change, a menu link in the admin menu, not just any menu, but the admin menu changes. And when any module is installed or uninstalled. So anything that might affect what is contained inside the admin menu tree. So the hash changes whenever anything changes in what it should look like, what it should contain. Now, combined effect that we're adding that setting to the page, combined it with this JavaScript. So this is somewhat simplified, but it gets to just across. So retrieving, the first thing we're doing in the load function, so we're renaming local storage to LS to keep things shorter, we're retrieving the hash from Drupal settings. It's Drupal settings, one word now instead of Drupal.settings in Drupal 7, but that's just a detail. We retrieve the hash. Now we look at the hash that is stored in client-side cache, because if those two are the same, which is the if test that comes up next, then that means that the thing that we have cached in the client side is exactly the same as the thing that we should be showing. So we don't have to do any work, except for getting the stuff, the menu tree from local storage, parse it to JSON again, and then just set it as in loaded, show it to the user. However, if the hashes are not the same, meaning that the thing that the server says we should be showing is different from the thing that we have cached on the client side, then we should remove the thing that is cached on the client side, do an Ajax callback to start loading it, and remember the hash that we are now supposed to be showing, and then once the Ajax callback fires, we have the save method that's at the bottom that's storing it in client-side cache and then showing it to the user. So as you can see, the overall logic is not hard at all. Most of the logic is that it sits on the server side where you determine this hash that you can use, which you can kind of view as a client-side cache tag like we have on the server side in Drupal. So that's it essentially. Another example is the new common market that I explained earlier. So I told you that it was doing additional HTTP requests, but that's not really the case. It's trying to be smart about it. It's applying heuristics to make sure that it's only doing HTTP requests when it's really, really necessary. For example, Drupal forever, or at least in seven, I think in six as well, has never shown updated or new common markers. Whenever the content was older than 30 days. So Drupal essentially assumes if content is older than 30 days, the user should have seen it already. I don't care if it's relative to that user new or updated, we just assume it's already been read. So that means that for anything that's older than 30 days, which on big websites is usually a lot, we just don't have to do any requests at all because Drupal already was assuming that it was read, so no work for us, great. That's a lot less things that we have to do. However, for those things that are newer, what we're doing is we're storing the last read timestamps in local storage for a node. So how the new and updated common markers work is essentially it tracks for each node when the last time is that a user has seen that node. Very simple. And what we're doing is we're caching that information on the client side as well to be able to determine based on the common timestamp that we were already embedding for each comments. And then we can compare that information with the last time a user has seen the node and then we can just match them and figure out if it's new or updated for the user. What's interesting in this case is that we don't need something like the toolbar where we had this hash that changed whenever some things on the server side configuration changed. And why is that the case? Because, well, what has been seen cannot be unseen in Drupal because you cannot mark something as unread. If you've seen something at point A in time, then if you're progressing a week, then that thing was still seen at point A in time, right? So any comments that was created before point A in time will by definition already have been seen. So that may sound very verbose, but it's actually really simple. So if you put it on paper, I'm sure you will find it very sensible. So in this case, no hash is necessary. So you can see that there is various use cases and they all have very different properties, but you can do very clever things to make sure that you have to do as few work as possible. As little work as possible. So ideally we would have many hashes, many client-side hashtags essentially. And today we only have one and it's not really even a hash. It's just the user ID so that you can, for example, in the case of the common new marker, that's what it uses it for. It knows which user has which reads timestamp. So you can do user-specific stuff and cache user-specific stuff on the client side so that you know which user it belongs to. One thing that we will probably have, but we don't have yet is a permissions hash, which is kind of similar to the toolbar hash that we saw earlier. And what it does is it is a hash that reflects all of the permissions that the current user has. So if any permission is added or removed or even renamed, I think, this hash will change, which means that anything that is permission dependent that is cached on the client side should be cleared on the client side whenever that hash changes. So anything that's permission dependent can use this specific hash. And that's something that we will use in getting rid of the additional HTTP requests for contextual links and in-place editing. And that's just the top of the iceberg. We can hopefully add more. And if not, you can easily add more yourself. It's just as simple as creating a Drupal setting, passing into the client side, then have JavaScript that leverages it. That's it. So conclusion for client-side caching. You should only cache slowly changing data because it doesn't make sense to cache data that changes every second, like stock information. You should probably use it for personalization and in general, really you should use it for anything that is expensive to send because it's a lot of bytes to put on the wire or anything that is expensive to calculate because it requires a lot of server CPU. And in general, what's also really, really important if you want things to remain fast and not have to do additional HTTP requests every single time is to minimize the number of HTTP requests, obviously. Try to apply heuristics like we're doing for the comments new and updated markers and use hashes as kind of client-side cache tags. So that's all about caching. This is the last thing I wanted to talk about, which I also find really interesting. So optimize away all the unnecessary bytes. This is about asset handling. For the longest time, we have had aggregation in Drupal core, but for also the longest time we haven't had JavaScript minification in core. And in Drupal 8, it should become trivial to write your own JavaScript minification or plug it in very easily without worries like you would have worries in Drupal 7 and before. So the API, if you could call it that in Drupal 7, looked like this for aggregation. You had an aggregates callback and a group callback and that was it. You could override the whole, implement both or nothing or apply hex and hex is the thing that most people chose because that was the only way to get something meaningful done. It felt at least in Drupal 7. So the end result is that you had incompatibility hell essentially because the Omega team, for example, is doing some special stuff with I believe CSS in the header to do, I don't know, maybe chassis stuff. Then there is the CDN module that also tries to do, well, it just tries to implement CDN integration but it uses the same technique and because there is not really an API for this, they conflicted and they just, it was a mess. It was impossible to get to work reliably. Now what we did in Drupal 8 was essentially made the API more explicit, so that you really know what's going on and more building blocks so that you can override individual building blocks and instead of overriding the whole. The logic is really identical. So don't expect JavaScript minification core just yet. Don't expect any special new features just yet. It's just restructuring, refactoring into building blocks and the building blocks look like this. The first one is the assets collection optimizer interface and it sounds like a mouthful but it's really simple essentially. So this is an interface that's implemented both for CSS and JavaScript. Those are the two different asset types that we have. A collection of CSS files is essentially, for example, all the CSS on your page is one CSS collection. So this is for implementing the optimizer for all the CSS files on the page. What it uses is the asset collection grouper interface. This is what groups the sites which CSS files to combine. So if you had 30 CSS files on your page probably would have something like maybe three groups. Each group contained three files and contained 10 files, three groups, 10 files each makes 30. And then those 10 files per bundle would be concatenated together and minified. That's what this does. This is the thing that decides which the groups are. Then you have the optimizer. So given a asset optimized, meaning minified, meaning, for example, strip out all the white space. And then there's the dumper, which is essentially for Drupal Core, write it to disk. As in to public colon slash slash files slash CSS, something like that. Just some location to write it down. And then finally the asset collection renderer interface. So given the optimized collection, so from our 30 files we went to three optimized files. Those three optimized files are passed to the asset collection renderer and that generates the renderer rate that will eventually result in, for example, the script tags on the page. So that's all it does. And really the nice thing about this approach is that you can override individual things at will. So in Drupal 8 we have this thing called services. And each of these aspects is a service. So you have the CSS optimizer, which optimizes an individual CSS file, but you also have a JavaScript optimizer, which optimizes an individual JavaScript file. And the things that we get with this are really cool, at least as a speed trick I find really interesting. So possibilities are amongst others. You can override just the asset number, retain everything else, and then write your files to an external server, a CDM, S3, whatever you want. So that's one class, one tiny, tiny class, it's one method, just implement that, override the service, that's it, and your files will be written to S3, for example. You can override just the JavaScript optimizer, because if you're a hipster, you might be using Node.js, and you might want to use Aglify.js, and then your JavaScript can be minified, again, by writing a single class. JS Collection Renderer, you could implement, you could override the way things are rendered, not just render to script tags, but use the Lab.js script loader, if you're into that. You could do really, really interesting and amazing things if you are collecting enough log data so that you can use a third party or write your own data mining thing. And then you can calculate globally optimal groups. That's something that has been a problem forever in Drupal. We group files together, but we don't really know enough to make sure that the files within a group won't appear in another group on another page, and then we might be ending up downloading the same files, but part of a different group over and over again. This is where you can solve that. You can override the entire collection optimizer, so that's the whole thing that receives all your CSS files on the page and returns the optimized ones. You could make it so that, for example, a new aggregate is generated whenever the M time changes of any of the files within the aggregates, or you could just do the really cool thing, which is say goodbye Drupal architecture for asset handling. I don't want any of you, so just override the asset collection optimizer and use your entire custom architecture. Just return the optimized files and that's it. You can do whatever you want without having to hack core. And that's really the conclusion. You can override individual asset services in Drupal 8 because you can then improve individual asset services and keep everything else as it is, just because, for example, you really need Jace minification, you can do just that, or you can apply your entire own architecture, which was unthinkable in Drupal 7. So, looking back at the things we covered, first up, asset loading. Always load assets by attaching libraries. Render caching, use cache tags precisely to do proper cache invalidation. Personalize via JavaScript and cache on the client side to do correct cache filling. Client-side caching only do that for slowly changing data and keep the cache warm if you want it to remain fast because otherwise you'll just make things slower. And asset handling, you can now override individual asset services. So things that still need to happen, this is just a tiny selection. Entity render caching just landed, so yay for that, but there is a follow-up issue for that to enable entity render caching for nodes and comments, so that still has to happen. It would be really, really cool if we could have views work with cache tags because imagine that views are really fast because they can be cached properly and only when things change, only then the views will be cleared and that means that views will be faster for everybody. We could even work on enabling CSS and JavaScript aggregation by default, out of the box finally in Drupal 8 because now it's much easier to reason about things so we can have Drupal core react to changed files automatically. And the permission-slash thing that I explained earlier, it would remove two HTTP requests per page as it currently stands in Drupal 8. And really in general, anything, if you're interested in this stuff, anything that is cached with D8, cacheability, we can use your help. Please join us. So that was it, I hope you liked it and if you have any questions, feel free to ask. That might be better, yeah. I noticed that the caching system at the moment doesn't look like it uses any kind of object orientation. Is it something we can expect that the caching system is gonna move to object-based things going forwards? So the question is, the caching API in Drupal 8 doesn't use object orientation yet, essentially, right? Yeah, so you end up with lots of arrays again, basically, it's a problem. Right, so are you specifically asking if the render system will change to being object-oriented, because that's why you have these giant arrays still? Well, I mean, for tags, we're talking about caching tags and things like that, and you're putting together a big array of tags and things. So the caching system itself more than the render system, but that's a good follow-up question as well. So the caching system itself is now object-oriented, essentially, but it's just the aspect of defining which things are within a render array, the cache tags for those. Those are still indeed array-based, but that's not really a problem, though, but ideally, eventually, we would move away, indeed, from an array-based render system. So I hope that kind of answers your question, but not really. So it's not now, but soon. What's that? You're saying not now, but soon, for render arrays. You're saying it's a long-term goal for render arrays. Yes, it's a long-term goal. It won't happen in Drupal 8. Okay, thanks. I wanted to ask if you say that there are tags for the client-side caching, also for the server side. So is there any API for altering these tags? I mean, if I have an entity cache and I want to calculate a different hash per language, is something that I can do in the language model? So is a question, can I alter cache tags or is a question, can I alter the hashes that we saw? Both, okay. So cache tags, yes, you can alter those because it's essentially render arrays. So anything, any hope that can alter the render array, you can modify the cache tags there. You can just add your own or remove some. Though I'd be very careful with removing some. And for the hash that's being generated, that's a very good question. It should be possible, but I'm not sure right now if it is because we only have one essentially in core. But that's a very good point. And please open an issue for that against Silver module so that we ensure that that's the case. Hi, so you discussed about using client-side cache with local storage, but I think local storage is quite limited right now. Like there are limits in some browsers that are about 2.5 megabytes, which is not bad, but it's not unlimited by far. I was wondering, did you discuss this? Are you worried about this? Because I mean, I know with the standard installation, it probably won't be a problem, but then I'm thinking with many modules, maybe everyone will use this client-side cache. That's a good question. So as far as I know, the limit across, the minimum limit across all browsers is five megabytes, so it's somewhat more, but indeed it's still very limited. So yes, if you're doing a lot of client-side caching, you might run into trouble, but at the same time, five megabytes worth of HTML, I think seems like quite a lot. So indeed with core, you wouldn't run into problems. And I think that you would only run into problems if you're either doing something super complex or super big, which kind of is the same thing maybe. But I think only then you will need to start looking into this and indeed it would need to be optimized on a per-side basis. And I think maybe in the future, once this is more common to do, and in Drupal 9 possibly we have a full API on the client-side to handle these things, then that API might be responsible for handling and detecting a full client-side cache and dealing with that. But for now, I think the current solution should be sufficient. And worst case, if we're really running into limits there, Drupal 8-contrib could just override parts of Drupal, so Drupal 8-contrib could override parts of Drupal 8-course JavaScript to make it work with a Contrib-developed API that handles this kind of thing. But I think we're very, very far away from that being a problem. And once that becomes a problem, we're probably in a good place. Thank you. I tried, it's 2.5 here. Okay, good to know. Okay, thank you. Thank you. This might be something very basic, but I just want to ask you, are we saying that if JavaScript is disabled, we may not see something? And because most of them, it looks like we are going towards the client-side. And it, okay, yeah. It's a good question. So the question is essentially, if we're depending on JavaScript, then aren't we risking that the end user doesn't see some important stuff, right? That's the question, yeah. So I didn't mention this in my talk and I should have, but the idea is, for now at least, that you should only be doing this kind of thing for not the basic, essential primary content on your websites. Things like new and common markers. It's fine to load a page without that initially, right? Because it's just these tiny additional things. Contextual links is another example. They're not visible. They're the primary content by default. So it's not bad if it loads only half a second after the page itself is loaded. For example, if an additional HTTP request has to be made. So yes, it's very important that you pay attention to not loading your primary content in this way unless you really are, you know what you're doing and you really have weighed all the benefits and downsides. But that's a really good point, yes. Do not do this for your main content unless you have a really compelling reason to do so. Okay, I have one more question. So you mentioned that we have a lot of sub requests after the main page load. Are we doing something like a symphony kind of thing, like not doing full bootstrap, just doing the things that we need? So the question is for those HTTP requests that we do for getting the additional metal data and stuff, do we do a full bootstrap which is slow or do we have something more efficient? And the goal is to have that. But as far as I know, and somebody in the room who knows is better than me, who's familiar with the BISCII internals and that's what's going on there, please correct me. But I don't think that's happening yet, but it will before Drupal 8 is released. So it will be or it should be at least. Right now, not yet. So it's part of another sub system of Drupal that is still in progress. Thank you. Could you expand a bit on cache tags and perhaps the performance impact they have in tracking an array of tags on a cached object? So that's a good question. So the question is essentially, we're using cache tags but doesn't that cause performance regressions essentially or doesn't that itself cause performance problems when you're clearing cache entries? I don't know the exact performance characteristics but the way it is implemented is we have similar cache tables like we had in all previous Drupal versions but now we have a new column called cache tags or just tags and in there we're listing all the cache tags and we can then just query by those, find the cache entries that contain those cache tags and delete them. It's possible that there are still performance improvements awaiting there, but for now that's how it works and I don't think it has major performance regressions and Mark Sullivan wanted to comment on that. Right now there is a bit of a performance problem on with cache tags with MySQL but there's an issue to, that prompted an issue to actually decouple the cache tags API from the cache API because there's not really a reason that you need to store cache tags for a certain bin along with whatever bin storage you have for that so the performance characteristics will improve but we will get them to a point where there won't be an impact. Thank you Mark. Any more questions? Okay, thank you. Hey. Thanks for your talk. I'm Stefan, one of the track chairs. Okay, I have. Yeah, I think we met in Munich. I think so too, yeah. Hey. It's a good talk. I like the slides, they were very good. Okay, great, thank you. I hope that they explained the performance patterns that we applied in Trueblade. We could talk a little slower again. Okay, that's good to know. But it was. It's nice in case there was one on the highest bracket. There's three out of three. Okay. Nice to meet you. Okay. Thank you.


general practice nursing student, ambassador, nursing network, nursing network, shiny way, workshops with shiny minds coaching, that was a mild course, thrown away, it's going to be amazing I think, we're not 100% sure it looks fair, we're thinking leadership, management skills, public speaking skills, that's what we're saying, personal and professional, so we're going to log in, obviously, to show you all, do you try it? Well, do you try it? Yeah, go and do the try it. I'm going into mine, this corridor is a little bit creepy, not going to lie. Are you ready? Here we go. So that's us finished our workshop, oh my god, well this is just stage one, we only had an hour and a half. And I don't even know what to say about it. When they said it was a mind spa, it is a mind spa. There's so much information that we've been given to think about and analyse about ourselves, about thoughts and feelings and our filter process and our brain and all of this and about being honest about ourselves and authenticity and all of that. It's just too much I think to put into one vlog, but it's given us something to work on and think about ready for tomorrow's full day session of workshops. But I think after tomorrow we can definitely update you on it properly and how it's gone and how amazing this workshop is because right now I'm feeling excited about it. I don't feel nervous anymore because I was feeling really nervous at the start, I think Kate was as well and the other girls that are attending and we were all sort of sat there not knowing what to expect, things like that. But now I think we're all a little bit excited and a little bit like actually we can do this, we can open our minds, we can public speak, we can do a lot of things if we put our minds to it and we're going to learn how to tomorrow. So tomorrow's a new day and I shall see you all tomorrow. So this is a message for our fellow ambassadors of the GPN Studentness Network. Hi! Kate and Claire here. So for those of you that missed the event we just wanted to show you how absolutely amazing this was and if this opportunity comes up again please, please, please go. I know it can't be helping sick and stuff but just try and go next time because it's been amazing and we have come out this so different. We feel, yeah. I don't know how you feel Claire but I feel like, I feel like a different person. Yeah, we are different people. It's so strange. Standing strange. Yeah, it's really strange. It's such a strange feeling but it's amazing. It's so powerful and liberated. We are liberated and empowered. I've got guns. I don't have fear. I've got these guns. Katie's just scoffing she's got guns. I've got the gun show. So yeah, so we just wanted to share that it's an absolutely amazing experience and the girls or guys, girls and guys that are going tonight and tomorrow please just keep your mind open and just get yourself thrown in because you are going to see such a transformation at the end. It's going to really, really shock you. Trey. And yeah, can we just say another massive thank you firstly to Karen Story who's made this possible. Thanks Karen. And to the lovely Beck and Danny. I've told you I was skeptical at first. I was not buying it. I thought it's not possible. It's not possible to gain any kind of confidence in however many hours we had together. Not many. It wasn't many. It wasn't many. But I am a true believer now. I'm a convert. It's really hard to convert Kate. Oh yeah. I know my own mind. It's a good one. My own mind. So thank you. Thank you from the bottom of my heart and I will be practicing and putting into practice all the tools that you've given us. Yeah. We're excited. Yeah. We've got this. We can do it. We can do this. So the past couple of days I've had two days off and I had a workshop for the general practice nursing ambassador leadership program. And to be honest we didn't know what to expect. We weren't sure what we were getting ourselves into. We didn't really know what was going to happen. We knew that we had sort of a challenge and we had to go there with something we wanted to improve and build on. And public speaking was my thing. This was what I wanted to gain from this. And it's actually what everyone in that room wanted to gain from this was be confident. Be confident in public speaking and presenting and getting that impact out there. So we went in and we... I don't even know where to start because the past two days, well it was a day and a little bit in the evening before. And these were just workshops to sort of build ourselves and deal with the emotions that we have whilst public speaking like the anxieties, the fears, the little voices in the head and how to control those and lower them so that we can concentrate on our presentation and not let it affect us. And before I went to this workshop I think I said this before in previous vlogs but I have a massive fear of public speaking. I really dread it. I don't look forward to it but it's something I physically want to do. It's something I want to do. I want to be able to stand in a room full of people and inspire them and motivate them and get my message across to those people in those seats listening to me. It's something I really wanted to do. I have a massive fear of it and people think oh my god but your vlog and stuff like that and you seem quite confident but actually I'm not. This is just me at home with my camera in my own comfort in my own skin but put me out on a stage talking in front of millions of eyes looking at me. No, it was a massive fear of mine. I dreaded it but I wanted to do it and I wanted changing myself to be able to do that. And guess what? The impossible became possible. I had no idea. I mean I thought I was just going to go and get the skills and tools to help me be able to sort of like body language and things like that to make me look confident but I never expected for the fear to be removed. Like I am cured. That's really strange. That is like massive. I am cured and I have no fear and this is weird. This is weird. I don't know what they did to me in those workshops. I don't know what happened but I'm not scared anymore. I've turned it into excitement. I'm really really excited to get up and talk in front of a room of people that fear's gone and I don't know how but it's magic and it's just the best feeling thinking do you know what? I can do this. I can do this and I can do it well now. Now that that fear's gone I can do it well. So bring me back to the room today. We had our poster presentations and instead of fear in it and instead of the dreading thing and another poster presentation I was excited. I thought I'm going to stand up and I'm going to present in front of the class and it's going to be amazing because I'm not going to have that fear holding me back anymore and yeah the nerves are still there obviously and that I think nerves are now a really good thing for me and it just shows that I care about what I'm talking about and that's okay but the fear that I had that was really holding me back has gone and I was able to stand today and present properly like I should and I think next week, next poster presentation, next week again I'm going to be able to do the same thing and it was just amazing and I said to my friend did you notice a difference last week and this week the way I was talking and things and she said there was like a massive difference so that's really really good, that's a really positive so it just shows that the workshop and everything helped it's not just in myself and my head but actually other people can see it as well which isn't big and it's going to be amazing and just on the back of all of this we have me and Kate have been asked to do a talk at a GPN conference I know next month on the 3rd of July I'm going to be hitting the doctors, the qualified nurses I'm going to show how amazing student nurses are and I'm going to get their minds thinking and I'm going to make an impact so that they leave that room taking something away from what I say on that day and I'm really really excited I can't wait, I'm not scared, I'm not nervous I'm going to go up there and smash it


ഇിതୋരുെഏിഛ്ന്പ്്ുല്ന്ര്്്ന്പ്പ്ര്യ്ം്ക്ക്ംര്ന്ലുമ്ര്ട്ന്ര്ച്ച്ക്ക്്ക്യ്ക്ക്ക്ല്ക്ക്ഘ് ആര്� On the stage, Congress leaders in the crowd, I would like to welcome all of you here today. I would like to congratulate you victory in the Pachayat elections. And I would also like to give my support to those who did not win the elections, but lost by a small margin. I think it is important that all our leaders, Pachayat leaders, MLAs, MPs, leaders across the board, go close to the people and merge with the people. A true Congress leader becomes the voice of the people he represents.  What is in the heart of your constituents should be in your heart. So the people of Kerala feel that the UDF and the Congress party truly represent them and are close to them. We have an assembly election ahead of us where we are fighting the left front. And you know the damage that Mr. Narendra Modi is doing to the fabric of this country. So it is important that we fight this election and sweep this election. It is not a normal election, it is an ideological election. And we are fighting for an ideology, a set of ideas. That is why when senior leaders from Kerala came to Delhi and met me, I put my views across to them. And as you are our soldiers, our fighters, I want to tell you what I told them. I said three things to them. The first thing I said is that this election we need to become an expression of the voice of the people of Kerala. And that means that we have to make certain commitments to them about what we are going to do for them. And so I said we should think about this election as a transformative election for Kerala. And we should build our manifesto and make it a people's manifesto. Not a manifesto built inside closed doors, but a manifesto built by the people of Kerala in the UDF. Our manifesto process should involve everybody. We should speak to farmers, labourers, small businesses, youngsters, women and we should ask them what it is exactly that they expect from us. And we should pledge to them that we will give them what they ask for, we will give them and honour our community. I also told the leaders that this election should be an election where we take the best advantage of our young leaders. I understand that there is a place for experience, but it is also very important that we build the congress and the UDF of the future. So we have to give representation to as many young fresh faces as possible. And they said they will put as many young people as possible into the assembly. And the final thing I said to them was that if we are going to choose candidates, we need to choose candidates who are close to the people, who are connected to the people, who are fighting local political battles and we need to give candidates in a transparent manner. And we need to make sure that we do not do this process inside closed rooms. And I said to them that I will give them my full support, I will go wherever the UDF wants me to go, I will fight whichever battle the UDF wants me to fight. And we will ensure that we do not just win the election, we will ensure that we sweep the election. So that was my message to the leaders and I thought I would tell you the conversation that we had. Finally I would like to say a little bit about the Prime Minister and what he is doing to our country. You would remember that he said that he has a 56 inch chest. And I am wondering what happened to the 56 inch chest when Chinese troops came and took 1000 km. I have been watching for the last 6 months the man with the 56 inch chest has not said the word China. I have been watching for the last few months and I am wondering what the Prime Minister is doing to the 56 inch chest. The word China is refusing to come out of the mouth of the Prime Minister. It is stuck inside his throat, he cannot take it out. And there is a reason for it. The reason is that he has weakened this country. He has destroyed the economy by doing demonetization and with a flawed GST. The highest level of unemployment in modern Indian history is today. The Prime Minister insists on doing everything for 5 or 6 of his friends. You look at every industry in India, every single industry is monopolized by those same 5 or 6 people. Whether it is mobile phones, airports, sports, power, agriculture, every single thing is monopolized by those same 5 people. In addition to this, he has divided the country and spread hatred everywhere. In addition to this, he has divided the country and spread hatred everywhere. And that is why the Chinese have decided to come inside our area. Because they know that the Prime Minister has fundamentally weakened India. And they have correctly assessed that the Prime Minister of India cannot stand up to them. So these are the forces that you are fighting. When you win a panchayat election, you are fighting and beating that force. When we win the election in Kerala, we will be defeating that force. And at the same time, you know better than me what the left front is about. You know what they have done to the future of Kerala. So we are fighting both these ideologies, one in Kerala and one in Delhi. And we are doing it non-violently, peacefully with love and affection and by bringing everybody together. We are not the force of anger, we are not the force of hatred, we are not the force of violence, we are the force of love, affection, kindness. So I thank all of you for carrying the flag of the Congress Party of Kindness and Compassion. Thank you very much.


Hi YouTube family, so today as the title told you I'm going to be going over a whole lot of newness at the drugstore. Keep in mind that I haven't done a what's new at the drugstore video for since way before my surgery and I'm like two months out from my surgery. So I do have quite a bit of new things here that I'm excited to share with you. Some things I've tested a ton and then there's other things that I haven't tested quite so much. Make sure I let you guys know whether or not it's really something I've tested. I did want to kind of acknowledge yes the big Texas hair I swear I should have been from there because I love big hair. But anyway let's get right into the video. Okay from NYX there's their Born to Glow Naturally Radiant Foundation. So I got this one I've worn it like three times I really love it. It does have a bit more radiance than another one but the coverage is really good on it. The wear time on it is not as long as I would like but it's really hot right now and really muggy. And so I'm finding that almost no foundations are holding up really really well during that especially not one that's glowy. So I'm kind of reaching for ones that are a little bit more matte. So I like this but I would really like to keep testing it further for the months when it cools down because I think it's going to be a really beautiful foundation in its you know radiance and how it just makes you give gives you that little bit of glow. One that I know has been on the market for quite some time so it's just new to me is from Hard Candy and this is their Glamoflage concealer full coverage concealer 16 hour wear it says. I felt like this one was really good coverage I felt like I could make it work but I felt like it was a tiny bit too heavy tiny bit too cakey for my aging skin that is on the normal to dry side. So I'm going to test that one out for you too I'm just trying to pair things up and figure things out a little bit so that I can make sure that I get a really good review and a really good video for you but this one is good if you're oily gals you might really like this and then from Makeup Revolution one of my favorite companies at the drug store is the Revolution Conceal and Hydrate Radiance Foundation with Hyaluronic Acid. Okay so I got this and I also got the concealer the Conceal and Hydrate concealer I really like them both I can't wait to do a wear test for you guys on these because I am wearing this one today I'm wearing the foundation today I do have a different concealer on but I'm really excited to share this with you because the other one was really a nice foundation but I felt like it was as heavy as the Urban Decay All Nighter and that's just a little bit too heavy and a little bit too cakey the older I get I used to love it when it first came out but as I get older and things get drier and things you know so I just feel like it's a little bit too cakey but this one I feel like they just did a really good job on so I'm really excited about both of these products this is a great concealer as far as not making you look like you're super dry under your eyes and it just it doesn't like accentuate any texture but it gives me the coverage I need because I have extremely deep dark circles and the other one was a bit too drying I had kind of shied away from wearing that one at all except for when it was really muggy because I didn't have to set it then so for me this new duo has been really good I also got yes this is still in the package because I have not had a chance to try this one out but this is the ultimate coverage crease proof concealer and it says contains hyaluronic acid collagen antioxidant accidents and peptides okay I really wanted to try this because I wanted to see what was going to be like the Laura Geller the real deal or if it was going to be like the Tarte creaseless and guess what guys it is I find that this is such a good coverage but I can even just put it on like right there hopefully you guys are going to be able to see that and it I mean I barely put a little teeny tiny dot on there and I can tell how good a coverage it's going to be now the real test will come with whether or not it's going to crease because it says that it's creaseless so that's really what I'm looking for like I said I haven't had a chance to try this yet but I'm going to revolution pro also came out with a couple of their powders they came up came out with the loose powder and the pressed powder I really have been enjoying this super duper fine you guys it's it's almost that same fineness that I feel when I feel the hourglass setting powder the the veil setting powder it really is a nice powder has a great delivery system it has the sifter so I really do like this but I don't like it for the under eyes I feel like it's way too drying for my under eyes make some look too dry like a desert and so I haven't been liking that at all as far as that goes but I like to set the rest of my face with it because it's been so muggy now what I've been doing with it though because any of you that have normal to dry skin realize that if you get too much powder on you're going to get to look and cakey what I have been doing a lot lately is just picking a little bit up on my beauty blender and then you know making sure there's not a ton on there tapping it off a little bit and either I'll start on my neck or you know download be able to kind of sheer it because I don't want a ton on and then just really you know pat it around my face with my damp beauty blender and it's been working so good with that so I do like that one but keep in mind that it is going to mattify you quite a bit they have a new blush out this one is one of the colors that I one of the only colors I could get but it's only six dollars I will say that when I stick my finger in here this does feel a little bit powdery this is probably and it's really bright so if you have if you love the pinks it's definitely a bright pink it will sheer out very nicely I will say though that it got a tiny bit patchy on me so I'm not super impressed with the blush they do have some highlighters that are like this and I felt like they were a little bit let me show you close up I felt like they were a little bit too drying so this is kind of along those same lines this is called blusher reloaded and it is in rose kiss and then this is their new bronzer reloaded so this is take a vacation sorry if I misspoke there because it might not be new to everybody like it is to me so this is a pretty bronzer I like it better than I liked the blush I think that the color might be just a little bit too yellow for me so I might have to get a little bit of a different color again this is take a vacation so I liked the product itself but the color was just a tiny bit off for me I didn't realize I had so much makeup revolution but this is called eyegliss and so it's two-sided liquid eyeshadow and so one side is just like a metallic color just super high shine and then the other side has tiny bit of particles of glitter in it and I will say that that side that has a little bit of glitter so down here is the sheen part or the metallic and then up here is the little tiny bit of glitter you can't really even see it but I will say that the top one with the little bit of glitter in it it does have to be built up some because you can't just swipe it across and it not be a little bit patchy so I really like the metallic part I've worn it a ton just on you know the center of my eyes to give a little bit of glisten but I think this is a really good product as far as its lasting power but you might get a little bit frustrated with the product that does have a little bit heavier metallic to it because you have to wait and then build it up wait and then build it up so I like this I think that they did a really good job on the one side but the other side was not one that I was like overjoyed for okay also from Nick's gosh this is the Nick's and make-up revolution show bear with me cannabis sativa seed oil radiant perfecting primer okay I wasn't expecting this to be a primer that was like high glow but it is and I it's okay it's not the greatest primer but basically it's not gonna do anything for you but give you a glow so there it is on my hand you can see the sheen of it I did use a quite a bit on there that was enough for like a face and a half that I use but I can tell you right now that it doesn't do like anything as far as keep your makeup on through the day or do the poor feeling or anything like that it's just for radiance so it would be really good to maybe mix into a matte foundation if you wanted to do that but this one wasn't my favorite okay from essence this is the you better work fixing spray it says it's gym proof so it and it says it's anti shine so this is a very mattifying you know hold your makeup on all day primer that does have alcohol in it so beware of that I wasn't highly impressed with this as compared to some other things that I've used before if you sweat a lot if you're a very active and you notice that you know even those personal summers for menopause that we get even those it will last through that so it is good as far as that goes but I have noticed on the days that it's been cooler and I've used this that it was just a little bit too drying for me so that's just a heads up on that one if you're oily you might really love it this one is from Elf and this is their primer for lips so this is just something that you're supposed to be able to paint on your lips outline your lips fill in your lips and then hold your lipstick on longer do I feel like it does that no but I do feel like it does good on if you have you know pretty good lip lines that it helps not have it bleed and I do I and I do appreciate that about it so this one for me even though it's not a necessity it really has helped that problem as far as when I'm wearing glosses when I'm wearing you know a little bit more emollient lipstick it's really good for that and then I also got from Elf this is the cooling under eye refresh it has a steel ball on the end of it and basically it's just kind of a roll-on serum or I don't exactly know what's in here but it's just kind of a roll-on that you use underneath your eyes so when I've woken up with puffy eyes from whatever the day before too much salt or a good ball or whatever you want to talk about this really does help I'll put this on let it set for a while it helps with those under eye bags and then I'll go in with one of my favorite products did put this in last month's monthly favorites but I'm gonna mention it again here too because it is fairly new this is from Catrice and it is the liquid camouflage under eye primer you guys this is so hydrating and it is so lovely I just I really really have come to love this product you just put it on underneath your eyes I do it as you know the step as I'm doing all my other primers and you just let it set there and it is very very hydrating and it's not like it hydrates and then disappears like some things that you put on it really seems to last quite a while and even you know rubbing it on here right now I can feel how hydrating it is and so I have been in love with this and I hope that they never can discontinue it because this is a really good good product and it's not a lot of money and I would highly recommend that if you have crepey cakey under eyes that look where you get so much creasing I get creasing anyway but this helps to reduce that a little bit and plump it up a little bit so that it keeps it at a minimum so really enjoying that okay last two things are two concealers and both of them I have liked but I do have a favorite so this is the new super stay full coverage long wear eye concealer from Maybelline this is a lot like their foundation I felt like it did a good coverage it's a little bit thinner product than I'm used to but it being thinner helps not create lines which is a good thing and it will build up so if you have really bad under eye circles like I do then you can go ahead and you can put that first coat on and just wait a second so it's better to do thin layers with your concealer than to do you know one really thick layer so you know wait a second and then put another layer on if you need it you might find that that little tiny bit you don't need at just a tiny drop goes a long way and it wears really really good I don't think that you know the super stay line that says it's like 16 24 hours I don't think it's that but it is really long wearing and really good in the summer too this one I don't have to set I can already feel that it's kind of set itself down on there I don't have to set that one it is again a little bit drier of formula but using the Catrice underneath it really does help and then lastly this is from Juvia's Place and this is their new concealer I wanted to get my hands on this when they launched the foundation but I didn't this is amazing you guys is what I have on today and it's what I've been wearing over and over again it's a lot like the Maybelline one as far as being thin like that but this one covers so so well and when I first got it I thought oh my gosh it's gonna be way too yellow for me you can see almost on my hand that it looks like it's almost too yellow but look at the coverage on that and that was like the same amount as right here on the Maybelline it the coverage is fantastic and I liked that I got this color this particular color and this is 20 so the color for me turned out to be really good because it had a lot of the cancellation properties that I like in a concealer so really have been loving that one anyway that's it for today's video I hope that you did enjoy it don't forget to please give me a thumbs up if you wouldn't mind I do appreciate that and if you're new here please consider subscribing I'd love to have you here as a part of our little family thank you for watching today I appreciate your time you guys have a wonderful day and I will see you all in my very next video take care of yourselves bye bye


The paper presents a novel hybrid metaheuristic algorithm, BAABC, for pre-processing skin lesion images prior to segmentation. The algorithm uses a statistical transformation function to enhance the contrast of the images, which is then used to estimate the optimal parameters for the search space. The algorithm was tested on three publicly available datasets and compared with other state-of-the-art segmentation algorithms. The results showed that the proposed model improved the dice coefficient to 94.6%, demonstrating its effectiveness in pre-processing skin lesion images. This article was authored by Shariah Malik, Taha Akram, Muhammeda Wise, and others.


Hi everyone, Joe for jaspyscasebreaks.com coming at you with a quick little pack of 18-19 status basketball fat pack break number 10 No vet commons ship and then one through eight on the randomizer at the very end. We'll do re-randomizer names We'll win spots in that court Kingsbreak big. Thanks everybody here for getting into the action There's the teams right there. Let's roll it. Let's randomize it four and a three seven times one two Three and a seventh and final time after seven times We got Kyle down to Kyle This is just for the break only four and a three seven times for the teams one two Three and a seventh and final time after seven we got okc down to Minnesota. All right. Here's the first half of the list right here There's the Dallas Mavericks Matthew Who knows a quick little pack right here? Hawks for Kyle. All right, no trade windows in these filler packs. I always remember folks if you See a break sold out just double check see if there's some sort of filler pack or a Extra number block R&B random number block to come accomplish before that break is done You can always check the break schedule too. That'll give you the latest filler information as well Hold the whole list right there. Let's see what we got over here Here in holiday. We've got Kata Bates D.O. DeMarta Rosen Jacob Evans Omari Spellman and Miles Bridges. This is actually I'm watching him play right now. He's actually all right Charlotte Tim Hess With the Hornets All right. Now of course the whole point of this Quick little pack break is not the break but just give away some spots So from Kyle and a shea. Let's get everybody in here Everybody in between we're gonna roll it and randomize that list Five and a six eleven times. It's gonna be top eight after eleven. We'll get spots in court kinks One and eleven the final time. Good luck So from nine on down my apologies. We'll get them next time Top eight you're in court kinks. Congrats Tim Eric Shea Kyle Robert Robert Matthew and Robert There you go. I'm Joe for jazby's case breaks calm. We'll see you next time for the next break. Bye


What is a chart? And how can a chart help for data analysis? Analysis. In this video, you will see what a chart is, the different types of charts available in DHS2, and what the chart interface looks like within the data visualizer app. Charts are graphical representations of data based on defined parameters. The data are represented by symbols, such as bars in a bar chart, lines in a line chart, or slices in a pie chart. Visualizing data through charts can help to uncover patterns, trends, and relationships in data. Different charts are better at communicating different types of data. For example, if you want to assess the difference between comparable data points, a bar or column chart would be the best option. Or if you want to track or compare changes over time, a line chart will help you visualize those changes or discover trends. In DHS2, you will find multiple graph styles in the data visualizer app. In this module, we'll cover some of the most common styles. You can access the data visualizer app in two ways. The first way is to go to the search app field n-type data visualizer, or you can scroll down to find the application within the search apps field. Click on the icon to open it. You can also open a chart from a dashboard. For example, in the immunization dashboard, we can see this chart EPI-AEFI cases last 12 months, representing the adverse events following immunization in the past 12 months for training land. Select the context menu and click open in data visualizer app. Here you can see the data visualizer interface. Let's examine the chart. The number of cases is represented in the y-axis, the period is in the x-axis, and the organization unit is in the filter. You can also use the layout to verify what has been selected. Do this by hovering over an item in the layout. Now that we have the chart open, there are various dimensions we could change to modify the chart produced by DHS2. Let's first alter the chart type. From the current column chart, let's open the drop-down menu and select bar graph. Click update to see the changes. We can now see the data are being displayed in a bar chart rather than a column chart. As with pivot tables, you will find the dimensions in the pane on the left hand side. You can alter these dimensions in the same way. For example, let's alter the period. You can do this by either selecting period from the layout or the left side pane, modifying the selection, and clicking update. The chart now shows the data for a different period. Let's see how we can alter the layout of this chart. First, you need to know that the layout is dynamic, meaning that the dimensions available will depend on the type of chart you have selected. For example, the column, stacked column, bar, stacked bar, line, area, stacked area, radar, and year-over-year charts all show series, category, and filter as the layout dimensions. The combination of series and category layout dimensions means that these chart types can be used to visualize multiple data dimensions simultaneously, making it easier to compare them. While pie, gauge, and single value charts have only one dimension to select, the rest of them go in the filter. This means that these chart types are not well suited for visualizing multiple data dimensions at once, but can be a good choice for highlighting one key dimension. What are the series and category dimensions? In this bar chart, we can see that the series dimension is showing the data items, and the category is showing the period along the vertical axis. As with the pivot tables, you can drag and drop the dimensions to alter the layout. Let's move the data to the category, the period to the series, and click update. Now we can see that while the underlying data has remained the same, the visualization has changed based on the way the dimensions are organized. Making layout changes like this can help uncover patterns or trends in the data. Now let's take a look at the options menu. As with the layout, the options available are also dynamic, depending on the type of chart selected. Under the data tab, you can choose how to display the data by ticking the options available. For example, with a bar chart, you can hide empty categories, add a target line, and add a trend line. Under the axes tab, you can customize the axes and their labels. For example, you can change and format the axes titles. And under the style tab, you can customize the look of your chart with colors and titles. All of these options are to be used to create a meaningful graphical representation of the data. Click update to view any changes made in the options menu. The file menu, as with the pivot tables, provides options to create a new chart, open a saved chart, save the current chart, share this output with other DHS2 users, or delete the current chart. Lastly, you can download your chart as a PNG or PDF file which preserves the graphic format, or you can also download the plain data source to use it outside of DHS2, including in other data visualization programs. In summary, charts are a graphical representation for data visualization. DHS2 provides several different types of charts within the Data Visualizer app to allow users to select the type that fits their data best. Charts can be altered by changing the dimensions and the layout, and you can customize how your charts look by using the different options available. Charts can also be saved, shared, or downloaded with just a couple of clicks.