 Hello and a very warm welcome to our session making Drupal fly fly through the sky Today we are going to present you the fastest Drupal ever It's actually here now Where here means it's not just near or somewhere else. It's here in core Where we've built some very nice things that are making Drupal fly and Making it continue to fly But before we start a little question to get to know you better as our audience Who of you has been at the session in LA? Okay, most of you haven't seen that that's good We still have some new things for that and I'm hope you have been at the session for the CDNs yesterday A lot more. Okay. We sparked your interest. So there might be some overlap, but many things should be new to you as well Okay Then we're going to start My name is Fabian France. I'm from Tecmon consulting. We are performance and scalability experts and this is from Akia and Akia has allowed us to Focus working on that. I got some grants from their office of CTO and Wim had been able to do that as part of his day job So let's start with a quote I've installed Drupal. However, it's running very very slowly hitting the front page or clicking on a link such as Administer can result in delays of 15 to 30 seconds Caching is enabled by the way and there's almost nothing in my installation very few users very little content That's not so good. But actually that's not Drupal 8. That's Drupal 4.7 And Then we have Drupal 5. Why is my Drupal side so slow with Drupal 6? Navigating between admin pages is slower than an a sweet six nail. We have Drupal 7 Drupal 7 is unacceptable snow So poor Drupal But what about Drupal 8? Will it be like a snail as well? The future is still open So the answer to all of that and we got that we had Twitter yesterday is keep calm and cash and Actually, that's what Dries had done already a long time ago. And we just figured that out this morning page cash in Drupal 3.00 There was edits in June 30 2001 So this was kind of how the first Drupal when the first page cash was added to Drupal how it was was looking like and Yeah, a lot has changed since then So another trend we are seeing is here We have a comparison of Drupal 4.7 with Drupal 5 and Dries in a blog post said so generating a page in Drupal 5 It's around 3% slower than in Drupal 4.7, but serving a cash page Drupal 5 is 73% faster and even 268% faster when the aggressive database cash is used so This is kind of an interesting thing we've seen again with Drupal 6 again with Drupal 7 that a Drupal has stopped to cash even more and more and has Provided better performance for enterprise, etc. But this non cash performance was always a little slower and Drupal 4.7 by the way looked like this then So overall we are starting to see a trend here Let's see what we are getting So Drupal 8 and that's me and this is linking to this very same slide So and I say Drupal 8 is a fast Drupal ever You are like what the fast Drupal ever are you serious? You are kidding, right? But you must be kidding but so Drupal 8 was slow. Everyone has told me that it must be true And beside that page catch was already in Drupal 7. I mean three So page catch really does not count Except it does and women show you later that it does So let's take a look at a very short demo to show you how we can Make a fastest Drupal ever so This is actually the demo The trees was almost to put in his keynote, but in the end it Unfortunately didn't make it, but it's on the blog post there So if you want to see it again once trees blog post comes out It will be there. So The big pipe here is what trees had said three times in his keynote and We'll take a look now how this will see So we have personalized slow and catchable content What you've most listened to then there's person is slow and uncashable content What you're currently listening to and then there's this comment form Which is even saying your name like you're an avid music fan, etc. And now let's compare and stop Oh, big peps already Finished why a traditional we already still wait so but what you might have seen When you were taking a close look it was that for big pipe that personalized uncashable blog was actually coming a little later So and this is kind of a trick on what we said in his keynote That we are going from we generate everything on the server and then send everything out to a kind of hybrid model Where we are sending out whatever is ready and everything that is not ready We are sending them So that might have been a little confusing a little fast So let us take that more slowly overall and analyze that a little more. So I'm gonna make that full screen Miss and play So this is our site um our today's site We're taking a look at the stem of site and taking a long time. So yeah, maybe that's cash But two thousand four hundred forty milliseconds. That's try again. It's not cash So this really takes a long to render why is that we have here again a very a block That's customized by user So that would mean It is very hard to cash together with the URL and we have a very dynamic timestamp than we have there Then we have a lot of those commands So and there's this awesome blog post that really is The content that I want you to see that you the comments are not that important It doesn't matter if they come directly or if they come a little later But that awesome blog post that is what want you to see So now I've activated a strategy called single flash and now we've kind of split up the page And we're gonna in a bit more detail later In time to deliver the page which was 600 milliseconds now and then flushing the placeholders which takes once two seconds And this was done by automatically place-holding that content but now if we reload it gets a little faster and Then it gets even faster even though if we are not yet seeing anything of that But it says clearly on there that the time to deliver the page is just 31 milliseconds and Depending on how fast my server reacts. It can be like 26 milliseconds or even less but the flushing placeholder time is always Kind of slowing us down because what Drupal is doing it still completely generating all of that on the server and It's also completely generating all of those comments on the server directly and That means we have to wait those two seconds, but that's not what we want We want people to see our awesome blog post directly And that's what we're going to do now and where we are now. I'm activating is small pipe So when we click now, then it's boom directly there and Small pipe is a technology that compared to big pipe does not need JavaScript enabled So it's completely transparent and maybe a better idea how to Name it would be aggressive flush. What you are seeing is That the time to deliver the page is really fast like 28 milliseconds And then this block was high Fabian is coming later and the reason for that is because and the dome order is like that that first comes the content then the comments and then the sidebar and With aggressive flush we are kind of sending whatever we have ready, but if it comes early in the dome we have to wait for it and Now we're gonna After testing that a few more times so that you can really see this block is coming later But maybe it has information We want the user to directly see and we just want the comments to come later because they're not that important to us And now we've enabled big pipe and that's now true the block is almost immediately there my awesome blog post It's always there and the comments come later and if you pay close attention You can even see the pager for a quick moment before the rest of the pages are there And what's nice about that is that in Drupal 8 and with a big pipe? No one forces you to To have that like this, but you have all the possibilities to do it And yeah, there was a demo a page delivered in just 28 milliseconds so what you just saw is General a part of the mission to make the whole web fast not just Drupal But the whole web and that's a challenge by Vimlius that I have taken on together with him and Everyone profits from this so it's an ambitious goal Let's see what what does fast mean in this fast means the user should have a great user experience So that part pages load fast for one user There should be also a great user experience so that pages load fast if there's several concurrent users and the user Experience should also be that the time to first bite what you've just seen this 28 milliseconds and depending on network speak You need to add another 20 milliseconds or so to that and the asset loading and the rendering and the JavaScript execution time that that's minimal and that's kind of what big pipe provides Because when the page is ready and just there's some little customized content or some unimportant content to send Then you've already loaded all the CSS all the JavaScript you've loaded already most of the page You've rendered almost all of the page and your JavaScript has executed We'll upload that later so you can take a look at the demo then again And if you pay close attention you will see that the home button in the small pipe example It's not turning white because the JavaScript is just executed when everything is done But for the big pipe Actually, it's very fast that you see that this is the active page because this is done in JavaScript and As those of you that had been at the CDN talk yesterday, so This great caching cash abilities even allow caching within CDNs So how do you achieve that to make the whole web fast? That's very very simple Use static HTML pages no CSS no JavaScript no images just text and links and then you have a fast side so seriously No, of course not There is however some truth to that that we have to see and That is that performance optimization means to optimize to do as little work as possible and To use as little resources as possible And so for the critical path, which is what you want the user to see which in our example Is the awesome blog post is can we avoid doing the work at all or can we avoid doing the work doing the critical path? for example doing Some other operation like doing saving Or can we cash it even permanently and if all that's not possible, maybe we can cash it temporarily like for 10 seconds You can't imagine what 10 seconds of Data can make for a difference that you're saying well, it's okay My content can be stale for 10 seconds But if then there's 1,000 users that are trying to get the cash at that time They're all getting the 10 second old data. That's not a big deal Unless you deal in real-time stocks or something. Yeah, you've got micro second precision But in most cases you can do some little kind of micro cash and that can help a lot But if you can't then the new kind of thing is to defer executing it after the main content And that's what big pipe small pike is all about so remember this little abbreviation ACD avoid cash defer if you're trying to build your applications in that way You will definitely succeed in having fast operations and applications So Caching avoiding is pretty simple work You don't have to do you don't have to do but caching overall has problems because your content should be as count as possible It should have a kai cash at ratio and it should have low cash in validation complexity But you choose to you can't have actually you need to choose to and That's a little problem because so far for low complexity cash in validation One of the examples would be time-based in validation So for example, you cash the pages unconditionally for here The content is not really current but cash at ratio is obviously great Or you cash pages never the content is always current But the cash at ratio is zero percent and that is Unfortunately the way how many many Drupal 8 a Drupal 7 sides operate that way right now and hopefully no Drupal 8 sides and Cash pages for for example 6 hours the content is quite current and cash at ratio is Kind of acceptable, but after six hours if you've got a lot storm of people coming in you've got a problem Then we have another example for low complexity cash in validation. That's a clear all in validation. So whoa Sorry So whenever a page changes clear the whole page cache and that's actually how Drupal 7's page cache operate like this by default It's like how it has worked in Drupal 5 and Drupal 6 and in Drupal 7 So whenever a page changes the whole page cash is cleared the block clash is cleared and That is a possibility, but it's not a very good one and In Drupal 7 contra a possibility to do that is to clear only what has changed So for example with the expire and varnish module in Drupal 7 You need to purge expire all the URLs that contain content from anything that was on the pages and you need a way to track that so example from the enterprise you have a List of related articles and it's on hundred thousand pages but now someone comes on and says well There's a misinformation there and it's a big boss from the company that says that we need to immediately change that and Now the problem is you of course in this case You would probably just clear all the cash, but in another scenario and you would need to figure out on which pages this wrong title was displayed so that really you are immediately expiring all that things and That is very very very difficult and that has a high invalidation cost Wim showed Showed yesterday from Ikea cloud edge Example where it was kind of showing a progress bar how it was gradually clearing the CDN So Drupal 8 shows high complexity The content is invalidated instantaneously It's cash permanently and the solution are cash tax as explained later But there's more problems to cash in because the content should be varied by user a group a special permission the face of the moon Yeah use cases are there Have high cash at ratio and have low complexity So the logic needed to ensure that the cashings are granularly varied because you can obviously Kind of take your page and then you go down into all objects all nodes and everything and try to figure out what everything Very is on and then you can obviously perfectly cash the page But that is very complex very Performance expensive and would not really solve that and again you need to choose to You can't have all three So either very good granularity or high cash at ratio, but or a low complexity What again? No Drupal 8 choose high complexity that means everything declares what it varies by This allows caching authenticate user content securely and actually at this point with dynamic Dynamic page cache and core which is activated by default In the current dropper late hat if you're using dropper you are using dynamic page cache, and you don't even see it it's just transparently there and As a solution our cash context as explained later and placeholders So wait a moment So what about kiss kiss principal keep it simple stupid? Hmm Counter-question who of you uses a database Okay, I think I saw someone there using some flat HTML files Databases are actually beasts of complexity But you don't see any of that and you still use them You just give hints like you give indexes and queries how you build them and the database does its magic Many know is no SQL folks have learned the hard way that all that magic that's in the database I need to then integrate in their own apps So database are giving you a lot that you never see and that's the same as dropper late Drupal 8 makes it as simple as possible for you for all of you and That's a huge huge opportunity Because that means if we all build our sites, right? We will all have fast dropper late sites. They will be perfectly cashable even in CDNs Because dropper late does all this caching logic this cash redirect logic this varying this bubbling It's all in turn. You don't see any of that. You don't even need to understand it You just need to understand that if you help to polite dropper late will help you So if you give trooper the information then it can be very very smart about this its decisions And when we last said this talk You could give that information but Drupal was not smarter now it is smarter and you will soon see why So Drupal 8 formalize those things in a kind of language to make your site fast and This language will show you in a moment So Drupal 7 could theoretically use the same language once it's finalized in Drupal 8 There's a render cache having two inch branch. It's at the moment not active. Sorry Drupal 8 took longer than expected and I've also worked hard to get it done Thanks to Drupal 8 accelerate But there's a service container module which allows to use the same code in Drupal 7 as in Drupal 8 and With that I'm pretty pretty positive that many of the code we've written together We can just copy to Drupal 7 and directly use But it's frozen at the moment. So how do I give such information? And that's what we'll show you now So something happened there I Have no idea There we go. Okay, so the thought process of how we actually make Drupal fast because Fabian was referring earlier to a language. Maybe that is a slightly too big of a word. There's a Handful three concepts that are really crucial and if you understand those you can tell Drupal What's it needs to know in order to do these smart caching things automatically? So the thought process is all about dependencies Because Drupal 7 and earlier versions and many other web frameworks and CMSs and so on do not know all dependencies Without dependencies, we don't know what to vary by when something is no longer Correct when it's outdated and so on and so it's all about making sure that Drupal knows the dependencies and Drupal 7 didn't track any dependencies and a very good and clear example is Drupal at CSS and Drupal at JS I'm sure most of you uses at some point hands up in the air who you did. Okay, you were all messing with global state Congratulations because this was what it was doing Recalling this function and it was putting data in some global state somewhere for the current page But it had no way of knowing what Piece of markup which render array which block which entity which whatever it was associated with So we were building global state to know all of the assets that were associated with that page Which is great, but that meant we weren't able to cache individual parts of the page and that is problematic And that's what attached libraries asset libraries solve So whenever you have a render array you specify pound attached and this existed in Drupal 7 as well But it was not enforced there in Drupal 8 There is this is the only way to attach metadata which can be assets which can be headers which can be all sorts of things but The important thing is we noted dependencies for a render away as in the attached assets that they need in order to function correctly So that's one example of a dependency that was previously hidden and now explicit another really good example Is a URL function? How many of you use that at some points? Also the majority that makes sense because we're on a web CMS, right? So the URLs output the URL functions output. I think this might frighten you It depended on the front page configuration the HTTPS configuration a clean URL configuration a current site in a multi-site The current host name and so many more things and so really what that meant was You you thought you were specifying some piece of input and you got some piece of output and You would think That it only depended on that piece of input that you provided but really depended on all these other things So really also dependent on global states. So it really was impossible to cash Well, we could cash it still but it would be impossible to invalidate correctly or to vary correctly and yet many of us probably all of us did it anyway and The reason we were able to get away with that is very simple as Fabian has demonstrated earlier We just cleared all the caches all the time and that's not great So in Drupal 8 this is kind of what solves that this is the language that Fabian was referring to earlier So we have three key concepts cash tax context and max age and cash tax are about capturing data dependencies It allows you to specify That for example a render array or anything else that is computed Depends on a certain bit of data for example Maybe a render array is showing the title of a node then you specify the cash deck for that node so that's when it's rendered We know that's hey this piece of rendered markup It actually depends on this node and if this node is modified this piece of rendered markup becomes invalid It becomes stale and this allows a student track such a kind of dependency another aspect of this is cash context cash context allow us to Capture the variations the request context dependencies So for example, we may be showing the title of a node But maybe that node is actually translated It's available in 10 different languages and if you were just specifying the cash deck We wouldn't know that it was actually possible to have 10 different titles We would always be reusing the same title So both the Dutch version of the site the English the French all of them would end up using the same one The first one that just happened to be Requested that's also not great of course and cash context allow us to capture that angle of information And finally max age is the right time dependencies because some information is not meant to be cashed Permanently you cannot cash it forever because it is Deeply intertwined with a certain period of time. So it's only valid for a very limited period of time This was probably the one you will use the least it defaults to permanent as in Distinct doesn't really have a max age is permanently cashable But tags and contexts are the things that you will use all the time because these are the things that are happening all the time And what's also absolutely crucial is that? For example at render rate that shows the title of the node that is only part of a bigger Bigger thing the page or maybe it's part of a block in the block is part of a region and the region is part of the page And so all of that cash ability metadata in the various parts of What is being rendered all bubble to the top level? So the contents of a block the cash ability metadata for those contacts bubble to the block level That bubbles to the region level that bubbles to the page level that bubbles to the response level and The fact that we therefore know comprehensively every dependency for that response and for every part of the page because overall a Render is nothing more than a tree representation that matches the tree representation of the DOM to sox to some extent There we also have JavaScript event bubbling. This is exactly like that So this allows us to know comprehensively for a response all of its dependencies Which things it varies by which things which data it actually depends on and how long that page can be cached so that that's the theory bit and that's Hopefully kind of clear, but how to put that into practice and there is just a simple series of steps that You should follow and then it it would be very easy to Automatically have all the cash ability metadata that is necessary So first of all you have to realize that you are rendering something It's just rating a render a and forgetting about the cash ability. That is a problem You have to realize I'm creating a render a I'm creating some output that will need to vary that needs to be Current at all times so it needs to be invalidated when the data depends upon changes So think of the fact that you have to think of cash ability in the first place the next question is Is this thing something worth caching on its own? Is it expensive to render if the answer is yes use cash keys just like in triple seven There's nothing new there if you've used render caching in triple seven show of hands who has I'm a fearing the number Is going to be low? Yeah, what five percent or so maybe So this actually already exists in triple seven this small part It allowed you to cash things a Certain sub three of the overall render array structure of the entire page And this is what causes that subtree to be cashed individually on its own so that it doesn't have to be regenerated on each ph load So that's cash keys the next thing is capturing variations does the thing I'm rendering vary by Permissions for the current user by the URL the negotiated interface language or maybe by something else you can specify your own custom cash context maybe Your website is is tailored to every country that your visitor may be from And therefore you would want a country cash context. Maybe you have a weekly deal a Weekly deal kind of thing because you're an e-commerce site then you can vary by that you can specify any cash Context needed for your specific use cases triple core ships with The ones that triple core needs, but you can specify your own And so when there is some kind of variation going on you specify the cash contexts that looks somewhat like that and It this should hopefully remind you of the HTTP very header because that is very very similar the HTTP very header allows you to specify that you Vary by certain aspects. These are aspects that are deeply internal to triple We cannot really expose that the HTTP level the current user permissions and so on that's a triple specific concept But this is kind of the very header inside triple at more granular levels and Then is there something in my render array that I depend on that may cause the render array that I generated to become Outstated so a data dependency if the answer to that is yes Then specify cash tax and every single entity every bit of configuration and all of the other most common things in Drupal 8 automatically have cash tax and are therefore You don't have to specify all of these things by hand because it can give you those things This is just a clear concise example. So for example, this render rate depends on node 5 user 3 and taxonomy term 23 So it's just a string-based syntax very simple And finally so we've had keys Contexts max a egg tags and now max age because sometimes the render array does become outdated Automatically after some period of time. So in that case specify a max age, which is a number of seconds or you can choose to specify Permanent which is a default which means that it's cashable forever So it's only going to be invalidated if there are cash tax associated with it So for example a no tile is not going to change after some period of time, right? It's only going to change if you actually change that node So there is no need to specify a max age in a number of seconds. It's fine to keep the default It's permanently cashable just until the node changes Then it becomes a validator. So we only need a cash tag for that particular example and that Obviously is super super similar to the cash control header in HTTP who which has a max age property. It's exactly like that and As I previously briefly mentioned all objects in Drupal core automatically provides cashability metadata So we have an interface that provides that allows you to catch the inherent metadata for that particular object And this is implemented and thus provided for just about everything that you use on a daily basis So for configuration all configuration all entities both content and config entities Every access result because access results can often be very expensive to compute But very often they're also very cashable Per permission caching for exact per permission access checking for example, that is perfectly cashable All sorts of things including block plugins context plugins condition plugins and many things you probably are Rarely going to touch they all provide cashability metadata And that's necessary because without if there is a gap then we don't know about a certain dependency and we cannot Ensure that everything keeps working correctly. We need to know the dependencies To make it a bit easier to deal with that so that you don't have to specify pound cash max age and so on specifically in every damn render array We have an API to make it much easier You specify the render array you want to add a cashable dependency to as in the render a depends on something that is cashable And you pass the dependency so for example the node object. So here is a concrete example We're talking to the configuration system. We're getting the the piece of configuration that contains a site name and we're creating a render array that says welcome to the site and The we then use this function to specify and pass in both the render array and the config objects And then the render array gets the necessary dependency information automatically So if Drupal pages were kind of like ships because Drupal rendering a page It's kind of like building a ship in the sense that you have this massive thing called a page because let's let's be honest It consists of so many small parts in Drupal So if it were like building a ship then in Drupal 8 it kind of looks like this the dependencies I've said that word how many times now The dependencies are very clear the components are very clear So we know very much how a ship is built how a page is rendered in Drupal 7 it is still a ship. We still are building pages, but it's all coming from everywhere We're calling into global state all the time, but it still is assembling pages in Drupal 8 things to do better structure We are able to do things we weren't able to do before So all those dependencies were really great and they're giving us a lot of information, but there was one remaining problem We had this dynamic page cache and then there were things on the page that were Uncacheable or things on the page like the toolbar that were varying by the current user and that was overall making our cache problematic because As we will see in a moment Too much cache variation is a problem So the remaining problem faced was that with all those dependencies the cache ability was not good and the things were slower than they could be So why that's a question and The answer is pages are static and dynamic in its nature. There's usually some static content that is used and There's some dynamic blocks like one dynamic block another dynamic block dynamic comment form like that big pipe example we've seen in the beginning and the problem is Those dynamic parts are slowing the whole page down But on the other hand those dynamic parts are in the web 3.0 What is providing value to the site to your site? It is now about personalized experiences. It is about giving nice things To your user that is dynamic that is giving them a great experience and with all that We cannot just remove that But that is what's making the pages slow and uncacheable and Uncacheable it makes them because if you have 100,000 pages and you have 100 users You have 10 million combinations with a very bad cache at ratio because every user just has that page for himself cached There's no Reusability at all. That's what we had first when we had dynamic page cache. I can call it smart cache before In the beginning stages. So how do we solve that? We just make pages less dynamic problem soft and no Fortunately to play test solution for that and it is already in core that is very very important It's placeholders and auto placeholder ring. So no more of this But instead what we are seeing this Drupal 8 due to all those dependencies you've provided is knowing your page You have a shopping cart which is user cached. You have a normal block which is just cached by the user permissions and you have Content which is user permissions and we are cached. That means obviously on every different article You have different URLs. So it's Differing by URL, but that normal block. We are seeing there It's user permissions cached and we can directly cache it with the rest because it doesn't matter if it's also cached by redundantly, but that shopping cart we can't and That's a problem, but droop late now. It just makes one little thing that placeholders it And with that little trick to make your sides faster One little trick, you know You have that placeholder and this is what is allowing all of that. So this is how it looks like to Drupal Just to give you the full picture There's all those placeholders on the page the HTML head placeholder CSS placeholder JavaScript placeholder Bottom placeholder because all those other placeholders could still have JavaScript CSS Whatever in there and you have the static content which is cacheable now But this is already huge because if your pages are simple Drupal can perfectly cache Then and if there's something complex Drupal will automatically throw it out or you can even customize as we merge how later So and that's all stored in in attached as independent lazy builders So you see on the right hand side Independent lazy builders and that's the next thing lazy builders. What are those things? We've never heard of those before Well, this is what it looks like. It's kind of like a pre-render function How many of you have heard of pre-render? How many of used pre-render? Yeah, okay about 10% I guess lazy builder is Kind of the successor to that in the sense that lazy builder is a more demanding more Specific version of that This is what it looks like you can specify only one lazy builder for a given subtree because Whenever you specify a level like this complex underscore thing, that's a new subtree for the render array structure You specify a callback which is going to render the thing which is going to lazily build a thing Hence the name and you can pass in some arguments But it's heavily restricted as we will see in a second So for example the common form that we all know and then that Fabian also done with in the very beginning is Rendered using a lazy builder. That's why that common form was actually also Rendered or was possible to send that via big pipe So we specify a callback and you pass in a number of arguments the things necessary to render that common form in the first place This should also be very familiar and similar to what you're already doing, but as I said, it's very restricted So a lazy builders callback context So the arguments that you pass into it may only contain scalar values or null So no objects and that allows us to easily cash That information so that we can easily pass it around so that we can cash the information to build this thing lazily So no objects also No children can exist. So remember this is an entire subtree So if the lazy builder is next to something that is also a render array, that means that we it's a conflict There is no way to know where it should appear then so Whenever you specify a lazy builder, nothing else can exist because we want to be able to render the entire subtree lazily And so also in that way it is heavily restricted And the cool thing is then that a lazy builder callback is a thing that builds the render a for that subtree and returns it And the output must solely depends on the input to the arguments that are given and these Restrictions together is what allows us to be able to render those things in isolation, and that's what allows big pipe That's what allows ESI rendering and so on And so Facebook Facebook Fabian. That's a strange Sorry Fabian Fabian also mentioned auto placeholder ring So we we encountered the lazy builder thing just now and that's a lot That's what allows us to pull something out and render it later because we have the arguments Which are just scalar values and that allows us to cash it which allows us to defer rendering it Remember the adage that Fabian just used avoid defer avoid cash defer So we want to defer in some cases and auto placeholder ring is what allows us to defer the rendering of something to a later time However, it's also configurable So this is what you will see in a services YAML file the auto placeholder Conditions and we see the three things that we're already familiar with max age context and tags and by default as soon as Drupal encounters a max age to zero on a render array that has a lazy builder It says, oh, this is way too dynamic. I'm not going to render this. I'm going to defer this So max age zero triggers it being deferred triggers it being placeholders that can be rendered later And the two other conditions are session and context session and user cash context So as soon as something is varying by session, which is as we all know very dynamic We chose to also defer the rendering if something varies by user We also choose to defer the rendering but know that this is configurable if your sites is for a very specific use case And you know it very well you can choose for example to omit the user in these settings So that would allow you to cash Per user anyway, because maybe your use case only has 10 different users many people logging in the same user I don't know. It's totally customizable and customizable and configurable to suit your needs But these should be very solid defaults. So that's auto place-holding at a conceptual level But let's make it a little bit more concrete So going back to the comment forum example that was using a lazy builder I've omitted the arguments for now to make it a bit more legible So let's assume that the user cash context is specified on there or that it was bubbled up automatically from The contents of the render rate that will be returned by the lazy builder later So let's assume it is varying by user that means the auto place-holding conditions are met and That means that what Drupal does is it specifies create place-holder error true And so just setting that flag means that Drupal will turn this thing into a place-holder So that it will be deferred later, but note that this is nothing Guarded off not something you can't you cannot do so if you know your specific use case very well And you think it should always be place-holder then you have the complete liberty to just specify create place-holder true yourself And it will always be place-holder it or you can specify false to avoid it ever being place-holder Not even when it meets the auto place-holder in conditions So once the place-holder create place-holder true flag is there during the rendering process Drupal will Pull out that information the deferring is what we're seeing now We will pull out the lazy builder and the cache property and instead put in a piece of markup over there Drupal render place-holder callback equals something something. It's just The markup could be completely arbitrary. It could even be a random number if you wish, but this just helps in Making the debugging process easier because when you encounter a place-holder it's not just this bit of gibberish It is something you can actually understand to find your way to figure out Oh this thing it will be replaced at a later time. It was deferred So we have a piece of markup instead We have an attachment as Fabian mentioned earlier the independent lazy builders So in the place-holders render in the place-holders in pound attached over there You see that the key is the markup for the place-holder. It could also be a random string as I mentioned It's just it matches With this so these things these two things match And then finally what it's going to be replaced with is in here So these two match as well and this level as in the fact that there is no place-holder markup and The original render rate is in here means that we are deferring it to a later time and that allows for the really really interesting Things because you can defer it to different stages and you can defer it to different places even depending on your Infrastructure and Fabian will show you that now Just to keep here at just one more moment The trick we are using here is because we have those lazy builders That's not much. We can just take this place-holder We put it in a key value store and then ESI is implemented You can implement ESI as I've shown yesterday in Generally less than 20 lines of code and have it working So the place-holder render strategies is something which allows you to totally customize all of that that's what big pipe users the ESI from the demo yesterday users and It's very simple. We have a chain place-holder strategy as kind of the default strategy but you could also overwrite that in your container file and chain place-holder strategy just means every Strategy gets a chance to replace place-holders and if they are not replacing them It just goes on and then there's a default strategy But it's kind of our fallback or default and which just means it returns all place-holders is they should be rendered directly There was kind of this is now matching with what you've seen at the very beginning of the talk when I said we're using this single flush strategy and This is kind of big pipe There's almost except the JavaScript library plus an emitter that is sending the data in chunked Things in storing the original place-holder somewhere else There's almost nothing more to that from a strategy perspective and you could now have your custom strategy and with your custom strategy you can say well if it's this block Then I want to do this or I want to use some state stale content Like you could decide well, I know this block is cached and I will always Deliver some stale content from that block Until that Delivery or you could say well here I wanted to use a react widget or something and you can dynamically do that even if the site's already built Because Drupal will tell you well those are the dynamic parts and that's So radically we could even build a graphical user interface if anyone want to volunteer on that Where you could kind of have like Drupal tell you well I've seen all of those placeholders in the last a few times and you can configure Oh, I need this library up front. This will always be cashed by user I need an additional context or I always want to small pipe this small pipe this big pipe this But I want to block the page rendering on this because that's really screwing up and making the page a little chunky or something So, but yeah, that's placeholder strategies So one final bit a few pitfalls on scenarios To help you get To help you get a slightly better understanding So we saw a bit a small example earlier where we're using the site name Site that name is in some piece of configuration. So when you're using some configuration Don't forget to add its cash tax, but you don't have to do it manually. You can reuse that handy helper function When you're depending on an entity, don't forget to add its cash tax When you're depending on a field of an entity, don't forget the app to add the entity's cash tax The field is part of the entity. So the entity's cash tax are what matters When you have un-cashable data, don't forget to set max H to zero which signals Drupal This is not ever cashable. It cannot be cashed periods and then Yeah, or if you're manually rendering a link, then you could either use trick That's very simple or you could use a render array and That's the best way to do that And then we have like a little scenario may vary by cookie Which means that for example, you have the username and a cookie and you want to vary by that You can just specify cash context cookies username and that's it. It will correctly vary And for example the scenario would there be to always vary by a device cookie that you've added for mobile Different things that was huge before Responsive came in but still used by some side So then you just add it to the required cash context the device cookie and Everything on the page will but vary by that It's also important if you have security sensitive information like you have a special group in your department Whatever yet, you need to vary on your credit cash context added to the required cash context You can be sure that everything varies correctly And that's it. I hope you liked it any questions I have a question about stampede protection. Would you implement that in the placeholder strategy or? There's two ways where stampede protection could now be implemented. I've played around a little bit that yesterday after our talk and One is directly in the renderer But you can have the renderer is now a class so you could override it and then you could do that But in this example Yes, you could actually say These are the hard parts. I want to stampede protect it So you could have like a special strategy that would protect your content and for example, even deliver outdated content Thank you about the strategies There's the the default group of strategy, which I can't understand it actually builds the page Plays replacing the placeholders Replacing the placeholders Before delivering the page there's big pipe that uses JavaScript. I guess Small pipe, but what does that do actually small pipe is sending the content junk? So you have to imagine you have a dome document like an HTML document. You usually have like Sections where you have a main section and then you have a sidebar While on the screen you are seeing it like this you have here the main section and here's a sidebar in the dome It's actually like this So what we are doing with small pipe is we are sending everything up to the first placeholder because all that content We know already perfectly so we are sending that we render the placeholder Just print it out flush again send the next parts of the page. So This is very useful and it's also but this depends on the dome order So if you have something in the sidebar that obviously wouldn't appear until all the placeholders in the main content have been sent That is by design because but it doesn't need JavaScript. That's a big advantage very big Yeah, in your code example when something was dependent on configuration like the site name You showed that you just passed the whole configuration objects now a Configuration object can contain a lot of things like the front page or you know a custom configuration object is 15 different things Isn't it kind of annoying that all of your caches are cleared when? For instance, you're changing your front page and not your site name and you have like 20 blocks dependent on the site name So the reason it works that way is because the configuration is stored at those levels So the answer to avoid that problem would be to make the configuration more granular So that the site name in the front page setting are stored in separate things But as long as it is changing As one hole so for example one bit of configuration contains both the site name and the front page setting As long as those are saved together There is no way we can possibly distinguish between what is actually being changed It is just being changed and that's all we know at that level. So there is no Other way than making it more granular at the conflict level. Yeah, okay, cool. Hi The beginning sorry for my English, you know, perfect. I'm gonna try explain the question as best as I can Thank you. The question is a few weeks ago in my company. We have that a little bit discussion about cash And the thing is in order you can use cash everywhere around the Drupal In your opinion the best way And what is the best way use the Drupal cash or cash your yourself? so I'm gonna explain in with with an example for example if you need a teaser information note and you can you know the Drupal It cash it already What the best way? use the what the Drupal cash or Use your own cash So you have to understand that within I assume this Drupal 7 was in Drupal 7 there's you could there's actually only two real cashers in core and the one is a page cash Which you can use but which has a problem that it gets invalidated very frequently when your content is added and then there is the Filter cash, which means everything that is displayed is kind of filtered from the format There's some other cashers for menu entries etc like that and blocks and there's block cash. Yes for sure and But that's kind of it What I would advise you is I've developed that so shameless plug But anyway that render cash in version 1.0 even it's used on Drupal.org For rendering the comments and entity comment Caching or entity render caching is already possible in Drupal 7 and that's probably the best way to To do caching what you could do also is to use entity cash That's a very stable contraption That you would do I would always First see what do panels views render cash etc The whole contraption space provide before I would do my own caching because I'm it's usually that they have solved some problems already That you didn't think about Thank you and one small addition to that It is very important to stress that Drupal 7 does not have all the set balancing information So no cash tax context and so on so it is absolutely crucial that you then Very very thoroughly analyze the information that you're caching with the render cash module Because on Drupal.org for example one tiny bit was forgotten the time zone And so the first person to visit the Drupal.org page The time zone for that user showed up for all users which could lead to very confusing situations So that is a down side you have to think of everything still Any more questions Doesn't look like it then. Thank you very much and have a great day