تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Introducing Blaze folding0:00

Okay, I have re-recorded this episode more times than I care to admit. This is the last time. Is your thinking cap on? My thinking cap is on. It's a difficult concept to understand. It's an even more difficult concept to demonstrate, okay? This is what we're going to talk about. Blaze. We're going to talk about Blaze. Did you know that?

We're going to talk about Blaze. Did you know that? We folded a component, right? We had this option component in the last episode and we folded it and we made the whole page fast and everything was hunky-dory. It was perfect. But if you recall, when we did it, all of the option components on the page were hard-coded. They were static.

Dynamic props break folding0:40

were hard-coded. They were static. Value was US and whatever, right? That's what it was. Well, that's not a very realistic life scenario, right? Often in life, in the real world, you have dynamic things. Like colon value equals country code or something like that. That's actually invalid, okay? Like this, right? Like that's something that you would have in the real world.

Like this, right? Like that's something that you would have in the real world. And I am here to tell you that this breaks code-folding, dynamic props break code-folding. Let me show you, okay? We have fold true. This is the compiled file down below. It's working great. It's folding. Look, option value US is hard-coded.

It's folding. Look, option value US is hard-coded. It is frozen into our compiled file. We know that folding worked. Now, if I save it with this new dynamic one, look, it breaks. It's no longer folded. It goes back to the compiled, you know, functional compiler thing, right? So that seems like a deal-breaker kind of, like, isn't that, you know, bad if, like, if that's something you do all the time, dynamic properties, and it breaks

like, if that's something you do all the time, dynamic properties, and it breaks folding, is folding very useful at all? And the answer is no. It's a little useful. And when Blaze, when I first started writing Blaze, this is what it just did. It just, like, only worked a few, you know, sometimes. And I would even, like, have to keep in mind, oh, I should write my blade components in

Partial folding with safe2:02

And I would even, like, have to keep in mind, oh, I should write my blade components in such a way that there's only static props being passed in and not dynamic ones. But I knew we needed a way around this. We needed some technique that we could get around this, and we have a technique , okay? It's called partial folding in my head. I don't know. It's not labeled that or anything, but it's a technique where we can basically fold everything

It's not labeled that or anything, but it's a technique where we can basically fold everything except what you pass into a component. So watch this. Let's go back to the dynamic value. Let's see if it's still there. No, if it's not country code, right, okay, hit save. Now we broke folding. Now watch this. If I say safe value, so I'm saying the value prop is actually a safe value to

Now watch this. If I say safe value, so I'm saying the value prop is actually a safe value to fold, even with dynamic value, I had save and something interesting happened. We folded option value, but we preserved the echo E country code, right? We preserved the dynamic part. Pretty interesting. This is partial folding, okay? But there's a very important condition with partial folding. It only works when a value is passed through.

But there's a very important condition with partial folding. It only works when a value is passed through. What I mean is when something goes in the machine and it comes out unscathed, that is a pass through value. Slots are passed through by default. We always fold even with slots. We consider them safe. You think about it 99% of the time, you're literally just pulling a slot into the component

You think about it 99% of the time, you're literally just pulling a slot into the component and echoing it directly out. However, if you did something different, like I think size is a good example of a pro. I think most props are not passed through size is not passed through. Some value that you use to do like, you know, if size is small, do this, else do that, right? That's not just passed through. You're not taking something and spitting it back out.

That's not just passed through. You're not taking something and spitting it back out. You're taking something and using it to change the whole component, right? Okay. So to give you a clear picture of this, because this, you have the whole setup here. You have the whole setup. Folding works except when props are dynamic. However, some props are passed through and if you tell Blaze that they are, then Blaze

However, some props are passed through and if you tell Blaze that they are, then Blaze will do partial folding. It will do something special to still fold your component, even though a dynamic portion was passed in. Okay. You got that? So to understand this, I think I want to show you a visual representation of how Blaze

Tokenizer and AST overview4:23

So to understand this, I think I want to show you a visual representation of how Blaze works under the hood. Blaze is an entire tokenized parser that looks at something like this, takes a look, finds a component, analyzes it, and does this partial folding. I'm going to show you how this partial folding works visually. Are you ready for it? It's a very, very professional demonstration, okay? TL draw.

It's a very, very professional demonstration, okay? TL draw. I literally made it TL draw. The example in here is X button instead of X option, but it's the same thing, okay? X button, Class W full, all that is static, right? But this is dynamic, okay, and we're going to see how Blaze handles this, yep. And then we have user name is also dynamic into the slot. So when we built our toy Blaze, we used reg X to identify parts of a template and pull

So when we built our toy Blaze, we used reg X to identify parts of a template and pull the name out and things like that. That really does not work when you're doing something complicated like this. The reg X is start to break down. So you need something more sophisticated, like a tokenized parser. Most other templating engines use a tokenized parser. View, react, they all use tokenized parsers. And there's even a tokenized parser for blade called forte. I recommend you check it out.

And there's even a tokenized parser for blade called forte. I recommend you check it out. It's pretty new and I wish it existed when I was making Blaze. But check this out, okay? We take that string in and this is what Blaze does internally. It goes character by character. Tokenized parsers go character by character, literally a while loop of characters. And you classify them into tokens. Tokens are just types.

And you classify them into tokens. Tokens are just types. What type is this character, okay? They're little bundles of characters. So this is tag open start, okay? This one is tag name. Is the next one tag name? Yes. Is the next one tag name? Put it all into these little token bundles.

Is the next one tag name? Put it all into these little token bundles. They're character bundles, okay? Then you have all of those in a flat array, like a flat list of tokens. And this is what it actually looks like in the code. It's associative arrays. It's an array of arrays that says like type, tag open start, tag name, attribute name. And this has all of the information about your entire source file. It's just split up into tokens.

And this has all of the information about your entire source file. It's just split up into tokens. I think PHP also has a function because most programming languages use token ized parsers. PHP has a function called like token get all or something. And you can actually look at the tokens of your own PHP file, just like this, a flat array of tokens. But this isn't very helpful when trying to understand like what, you know, a component

But this isn't very helpful when trying to understand like what, you know, a component is. It's just a list of all of these tokens. You don't, you'd have to like put it all together to know that. So there's another step in a tokenized parser called an abstract syntax tree. You've probably heard that term before. It gets thrown around. It's very jargony, but basically what it is, is it's what you, you take these tokens which

It's very jargony, but basically what it is, is it's what you, you take these tokens which are a flat array and you turn them into a hierarchy, okay? Something more meaningful, a better structure, a structured array that has notes, okay? Each item is a note. So the whole root is a node that has things like what type of my, I'm component , what's my name, X button, what are my attributes. And then these are more notes like, I'm an attribute.

my name, X button, what are my attributes. And then these are more notes like, I'm an attribute. My name is class. My value is w full children, okay, because you can nest them. These are slots. There's a node called text. Here's the value, okay? This is an abstract syntax tree and in a tokenized parser, it's a closed loop. You start with source code in, you explode it into tokens, you compile those into an

You start with source code in, you explode it into tokens, you compile those into an abstract syntax tree, and you can take that abstract syntax tree and compile it right back into the original source code. That's the fun thing about them is the whole process is it preserves itself, okay? You can take source code, explode it, compile it, and then render it back into the original source code.

the original source code. And magic comes in when on this step, this AST step, you transform the abstract syntax tree with code, you do intelligent things like blaze does to look for static bits and change them, then it compiles back into source code, okay? So let's take a look at that. Now that we have the knowledge of the parser, now we can use that knowledge, and we can

Now that we have the knowledge of the parser, now we can use that knowledge, and we can understand how blaze pulls off something like pass through partial folding, right? Where we pass in a value like country code, but again, at compile time, you know, literally like blaze is trying to do something like this, blade render at compile time, okay? And it's going, all right, I'm going to pre-render this component because it's supposed to be

Placeholder replacement mechanism8:38

And it's going, all right, I'm going to pre-render this component because it's supposed to be folded. What's country? This could be auth user. What's auth user? I don't know the authenticated user, right? I have no idea. So how does blade pull this off or blaze, okay? Well, we analyze the abstract syntax tree, and we identify dynamic parts.

So how does blade pull this off or blaze, okay? Well, we analyze the abstract syntax tree, and we identify dynamic parts. We go, oop, this attribute value is dynamic. And so is this value. So we obviously, we can't fold it. We don't know what the current user is at compile time. We only know that at runtime, but what we can do is we can pop it out and we can replace it with a placeholder placeholder one and placeholder two, and then we have a look up

it with a placeholder placeholder one and placeholder two, and then we have a look up of the placeholders and their dynamic counterparts, right? We replace it with a string, so now the whole thing is static again, and take a look at the source code now. So this is the blade source code, except without those dynamic expressions. Now there's just these static placeholder strings. So keys, placeholder one, high placeholder two, okay? Now this is something we could pass in the blade render anytime we want.

So keys, placeholder one, high placeholder two, okay? Now this is something we could pass in the blade render anytime we want. We don't need runtime context. So we can take that and render it. And now blade has rendered it, PHP has processed it. It's done. If this was loaded on a page, button type button, class w full key placeholder and high placeholder two, perfect. But of course, we can't stop here because we need that dynamic expression back

placeholder two, perfect. But of course, we can't stop here because we need that dynamic expression back so we can literally use string replace to replace those pass through portions with the original dynamic expressions. And then you end up with something like this, where the component is gone, you 've deleted the component, but you've kept the dynamic portions that you passed into it. And that is what's happening with Blaze.

the component, but you've kept the dynamic portions that you passed into it. And that is what's happening with Blaze. When you say fold true, safe value, you're saying consider value if it is dynamic as a pass through component that you can literally put a placeholder in, okay, and render it and then replace the placeholder back with the original dynamic part. Does that make sense? I hope that makes sense. I want to show it to you a little bit more deeply in practice.

Debugging placeholders and pitfalls10:34

I hope that makes sense. I want to show it to you a little bit more deeply in practice. Okay. I guess to really drive the point home, I think you need to see the placeholder , okay? I think you need to witness it, right? So how would we do that? I think like, what's a good way to do it? Let me try if I just DD the placeholder, right, or DD the value. Let's try this.

Let me try if I just DD the placeholder, right, or DD the value. Let's try this. Let's just see what happens. I'm not sure what's going to happen. We're going to DD value, okay, and I'm going to hit save. What is going to happen? Well, I don't even think I'll be able to render the page, but I do have this benchmark. I have a benchmark loading in the terminal right here. So every time I hit save, this shows the output, okay?

I have a benchmark loading in the terminal right here. So every time I hit save, this shows the output, okay? So I think what's going to happen is, when it goes to compile it, we're going to see the DD here, right? So what is DD value? I think when I hit save, it is going to try to compile this file. Let's get rid of this, okay? I think it's going to try to compile this file. It's going to hit DD and the placeholder that it passed through is going to

I think it's going to try to compile this file. It's going to hit DD and the placeholder that it passed through is going to cause a dump. I'm not sure if it's even going to work. You'd think I would have tested this beforehand. Okay. Save, ha ha, check it out, blaze placeholder zero, isn't that pretty interesting? Because that's when this component is actually rendering, we are passing a placeholder string

Because that's when this component is actually rendering, we are passing a placeholder string in for value. I bet slot is the same. Let's say slot, okay, component slot, contents blaze placeholder one, ha ha. Pretty interesting, huh? I hope that helps kind of drive it home and really show you, you know, that there is a placeholder being passed in and it is being replaced. Now to like finish it off, let's, let's demonstrate something that is not

placeholder being passed in and it is being replaced. Now to like finish it off, let's, let's demonstrate something that is not passed through to see what kind of trouble you can get in. Like, let's do this. If I say echo string length of value, okay, and now I load the page, it all says 20, right? It all says 20. Well, they all say United States right now because that's hard code. Let's get rid of that.

Well, they all say United States right now because that's hard code. Let's get rid of that. To country name, okay. So everything else about this looks perfectly fine. You wouldn't know anything. You go option value AF Afghanistan, perfect. But if you use the value, the pass your value as something else, if you go, I want to know the string length of the value, well, it should be two, but it's 20 because blaze placeholder

the string length of the value, well, it should be two, but it's 20 because blaze placeholder zero is 20 characters long. So you can see how you can get into trouble here. Like if you were depending on something like size and you said, oh, size is safe. If size is SM and you say, if size equal SM, do something, when it runs, it's going to be if size equals placeholder zero, you know, that kind of thing, I could demonstrate these

be if size equals placeholder zero, you know, that kind of thing, I could demonstrate these types of things all day. I could do something like this, watch. If we do string to lower and then I render this page, look, because I mutated that placeholder, it won't replace itself. It can't, you know, if I turned into a hash or something, you're encoding that placeholder at that time, and it doesn't get replaced because we turned it into lowercase.

placeholder at that time, and it doesn't get replaced because we turned it into lowercase. So it didn't get replaced. Okay. That's the complicated thing that I was trying to demonstrate. Let me try to bring it all back together so that you understand folding. You can make any pure component like we talked about foldable. That's a safe thing to do. And blaze has some defaults. It goes, okay, you're passing a static things in.

And blaze has some defaults. It goes, okay, you're passing a static things in. We're good. We can fold it. You're passing dynamic things in. We can't fold it. We're going to be doing something that will cause some ruckus, right? But there are times where you go, well, value is actually a pass through dynamic property. So in theory, we could still fold around it.

dynamic property. So in theory, we could still fold around it. And when that's the case, you just say, safe, I say, this value is passed through. It's safe. Then blaze goes, okay, I'll use my partial folding trick with that placeholder to replace back in the dynamic parts and bring you back to a fast component. If this all feels like too much, it is. That's why we do this all in flux for you.

If this all feels like too much, it is. That's why we do this all in flux for you. When you use flux, we thought about each component and what's foldable and what 's safe and all that stuff. We've done that thinking for you and you don't have to do that. But we wanted to make this available because it is so powerful. And if you do have a big application that is mission critical, it is worth your time to understand some of these things and optimize a few critical path components.

time to understand some of these things and optimize a few critical path components. It will make your whole app much faster. It's that compelling that it's worth this mental, you know, complexity. All right. So that's the thing I've been trying to explain. I'm going to call it explained. Let's talk about a few more of the edges of it, a few more affordances you have to get blade to fold something or optimize something that it wouldn't otherwise

to get blade to fold something or optimize something that it wouldn't otherwise optimize. But we're over the hump. Now you've seen partial folding. You've seen where the blaze thinking gets crazy and you go, wait a minute. Why is it saying place holder zero on the page? Now you understand. All right. I'll see you in the next video.

All right. I'll see you in the next video.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟