Chapter 35 — Performance: Loading and Rendering
Section 1 — What performance means
Performance is how quickly a page becomes usable and how smoothly it responds afterwards, as experienced by a real user on a real device and connection. It is not a single number, but a set of experiences: loading, responding, and staying smooth. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet what performance means, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If what performance means is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
import('./HeavyChart.js');
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of what performance means, and when would you use it?
Section 2 — Why performance matters
Slow pages cost users time, patience, and sometimes money on limited data plans, and many visitors simply leave rather than wait. Performance is therefore a matter of respect for users and of whether the page achieves its purpose at all. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet why performance matters, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If why performance matters is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
<img src="photo.jpg" loading="lazy" alt="A market scene" width="800" height="600">
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of why performance matters, and when would you use it?
Section 3 — Measuring before optimising
Measure before you optimise, because guessing at the cause of slowness often leads to work on the wrong thing. A baseline measurement tells you what is actually slow and lets you prove later whether a change helped. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet measuring before optimising, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If measuring before optimising is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const img = new Image();
img.srcset = 'small.jpg 480w, large.jpg 960w';
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of measuring before optimising, and when would you use it?
Section 4 — The critical rendering path
The critical rendering path is the sequence of steps the browser takes before it can first paint: parse the HTML, build the document and style models, run blocking scripts and styles, then lay out and paint. Shortening that path speeds up the first view. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet the critical rendering path, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If the critical rendering path is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
window.addEventListener('scroll', onScroll, { passive: true });
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
Check: In your own words, what is the key idea of the critical rendering path, and when would you use it?
Section 5 — First paint and first contentful paint
First paint is when anything first appears, and first contentful paint is when the first text or image appears. They mark the moment a page stops looking blank, which matters because a blank screen feels broken even if the page is working. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet first paint and first contentful paint, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If first paint and first contentful paint is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const list = items.filter(i => i.visible);
const visible = list.slice(start, start + 50);
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
Check: In your own words, what is the key idea of first paint and first contentful paint, and when would you use it?
Section 6 — Largest contentful paint
Largest contentful paint measures when the largest visible piece of content, such as a hero image or heading, has rendered. It is a useful proxy for when the main content feels loaded, and it is sensitive to slow images and blocking resources. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet largest contentful paint, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If largest contentful paint is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
import('./HeavyChart.js');
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of largest contentful paint, and when would you use it?
Section 7 — Interaction to next paint
Interaction to next paint measures how quickly the page responds visually after a user interacts, such as a click or a key press. It captures the responsiveness users feel after loading, not just how fast the page first appeared. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet interaction to next paint, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If interaction to next paint is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
<img src="photo.jpg" loading="lazy" alt="A market scene" width="800" height="600">
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of interaction to next paint, and when would you use it?
Section 8 — Cumulative layout shift
Cumulative layout shift measures how much visible content moves unexpectedly after it first appears, such as text jumping when an image loads late. Unexpected movement is annoying and can cause users to click the wrong thing. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet cumulative layout shift, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If cumulative layout shift is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const img = new Image();
img.srcset = 'small.jpg 480w, large.jpg 960w';
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of cumulative layout shift, and when would you use it?
Section 9 — Time to first byte
Time to first byte measures how long it takes for the server to start responding after a request. A slow first byte delays everything else, so it points to server, hosting, or network problems rather than to page weight alone. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet time to first byte, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If time to first byte is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
window.addEventListener('scroll', onScroll, { passive: true });
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of time to first byte, and when would you use it?
Section 10 — Total blocking time
Total blocking time measures how long the main thread is blocked by long tasks during loading, preventing the page from responding to input. Long JavaScript tasks are the usual cause, and breaking them up restores responsiveness. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet total blocking time, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If total blocking time is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const list = items.filter(i => i.visible);
const visible = list.slice(start, start + 50);
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of total blocking time, and when would you use it?
Section 11 — Page weight
Page weight is the total size of everything a page downloads: HTML, styles, scripts, images, and fonts. Every byte must travel over the network and often be parsed, so weight is a direct tax on loading, especially on slow connections. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet page weight, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If page weight is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
import('./HeavyChart.js');
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of page weight, and when would you use it?
Section 12 — Network conditions vary
Visitors do not all share your connection: some are on slow mobile networks, some on shared Wi-Fi, and some on fast broadband. Testing only on a fast office connection hides the experience of the visitors who suffer most from weight. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet network conditions vary, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If network conditions vary is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
<img src="photo.jpg" loading="lazy" alt="A market scene" width="800" height="600">
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of network conditions vary, and when would you use it?
Section 13 — Devices vary
Devices vary in processing power and memory, so a page that feels instant on a new laptop may stutter on an older phone. The main thread, memory, and battery are all scarcer on low-end devices, which is where optimisation matters most. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet devices vary, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If devices vary is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const img = new Image();
img.srcset = 'small.jpg 480w, large.jpg 960w';
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of devices vary, and when would you use it?
Section 14 — Reducing HTML size
HTML size can be reduced by removing duplicated markup, avoiding deeply nested wrappers that add nothing, and letting the server compress the response. Small HTML also parses faster, which helps the first paint. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet reducing html size, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If reducing html size is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
window.addEventListener('scroll', onScroll, { passive: true });
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of reducing html size, and when would you use it?
Section 15 — Minification
Minification removes unnecessary characters from code, such as whitespace and comments, without changing what it does. It is done by a build tool, not by hand, and it makes files smaller to download while keeping the source readable in development. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet minification, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If minification is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const list = items.filter(i => i.visible);
const visible = list.slice(start, start + 50);
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of minification, and when would you use it?
Section 16 — Compression
Compression shrinks files during transfer, so the browser receives far fewer bytes than the file's original size. Text files such as HTML, CSS, and JavaScript compress very well, while already-compressed images and videos gain little. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet compression, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If compression is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
import('./HeavyChart.js');
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of compression, and when would you use it?
Section 17 — Bundling JavaScript
Bundling combines many JavaScript files into fewer files, reducing the number of requests a page must make. Too much bundling, however, creates one huge file that delays the first interaction, so bundling must be balanced with splitting. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet bundling javascript, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If bundling javascript is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
<img src="photo.jpg" loading="lazy" alt="A market scene" width="800" height="600">
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of bundling javascript, and when would you use it?
Section 18 — Code splitting
Code splitting divides JavaScript into smaller chunks that load when needed, such as one chunk per route. The first page then loads only the code it needs, and the rest arrives when the user actually navigates there. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet code splitting, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If code splitting is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const img = new Image();
img.srcset = 'small.jpg 480w, large.jpg 960w';
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of code splitting, and when would you use it?
Section 19 — Lazy loading routes
Lazy loading a route means its code is fetched only when the user navigates to it, not on the first visit. This is one of the largest wins available to multi-page applications, because most visitors never visit every route. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet lazy loading routes, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If lazy loading routes is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
window.addEventListener('scroll', onScroll, { passive: true });
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of lazy loading routes, and when would you use it?
Section 20 — Lazy loading components
Lazy loading a component means loading it only when it is about to appear, such as a heavy chart below the fold or a dialog that opens on click. The initial page stays light, and the cost is paid only by users who need that part. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet lazy loading components, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If lazy loading components is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const list = items.filter(i => i.visible);
const visible = list.slice(start, start + 50);
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
Check: In your own words, what is the key idea of lazy loading components, and when would you use it?
Section 21 — Tree shaking
Tree shaking removes exported code that is never imported or used, so a library contributes only the parts the page actually needs. It depends on the code being written in a form the build tool can analyse, with side effects declared honestly. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet tree shaking, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If tree shaking is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
import('./HeavyChart.js');
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of tree shaking, and when would you use it?
Section 22 — Removing unused code
Unused code accumulates as features change: old components, old styles, and old dependencies that nothing imports any more. Auditing the bundle regularly and deleting dead code is unglamorous work with a direct effect on loading. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet removing unused code, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If removing unused code is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
<img src="photo.jpg" loading="lazy" alt="A market scene" width="800" height="600">
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of removing unused code, and when would you use it?
Section 23 — Choosing dependencies carefully
Every dependency adds weight, maintenance, and risk, so a library should earn its place by solving a real problem better than a small amount of your own code would. A large library imported for one small helper is a common and avoidable cost. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet choosing dependencies carefully, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If choosing dependencies carefully is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const img = new Image();
img.srcset = 'small.jpg 480w, large.jpg 960w';
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
Check: In your own words, what is the key idea of choosing dependencies carefully, and when would you use it?
Section 24 — Image formats
Image formats differ in how well they compress different kinds of pictures: photographs compress well in lossy formats, while graphics with sharp edges and few colours suit lossless formats. Choosing the right format can halve an image's size with no visible loss. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet image formats, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If image formats is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
window.addEventListener('scroll', onScroll, { passive: true });
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of image formats, and when would you use it?
Section 25 — Resizing images
An image should be served close to the size at which it is displayed, not many times larger. A photograph displayed at a small width but downloaded at full camera resolution wastes most of its bytes for no visible benefit. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet resizing images, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If resizing images is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const list = items.filter(i => i.visible);
const visible = list.slice(start, start + 50);
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
Check: In your own words, what is the key idea of resizing images, and when would you use it?
Section 26 — Responsive images
Responsive images let the browser choose among several sizes of the same picture, picking the one that fits the screen and its pixel density. This gives small phones a small file and large screens a sharp one, without serving everyone the largest file. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet responsive images, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If responsive images is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
import('./HeavyChart.js');
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of responsive images, and when would you use it?
Section 27 — Lazy loading images
Lazy loading an image means deferring it until it is near the viewport, so images below the fold do not compete with the content the user can actually see. The browser provides this natively, and it is one of the simplest performance wins. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet lazy loading images, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If lazy loading images is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
<img src="photo.jpg" loading="lazy" alt="A market scene" width="800" height="600">
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
Check: In your own words, what is the key idea of lazy loading images, and when would you use it?
Section 28 — Image dimensions and layout shift
Giving images their width and height in advance lets the browser reserve the right amount of space before the image arrives, so surrounding text does not jump when it loads. That reserved space is what prevents a common kind of layout shift. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet image dimensions and layout shift, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If image dimensions and layout shift is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const img = new Image();
img.srcset = 'small.jpg 480w, large.jpg 960w';
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
Check: In your own words, what is the key idea of image dimensions and layout shift, and when would you use it?
Section 29 — Fonts and loading
Web fonts can delay text rendering, because the browser may wait for a font before showing text, or swap fonts mid-read. Limiting the number of fonts and weights, and using a sensible display strategy, keeps text readable without a long wait. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet fonts and loading, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If fonts and loading is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
window.addEventListener('scroll', onScroll, { passive: true });
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of fonts and loading, and when would you use it?
Section 30 — Font display strategies
A font display strategy decides what happens while a web font loads: show a fallback immediately and swap later, or hide text briefly. Showing a fallback promptly is usually kinder, because users came to read, not to wait for a typeface. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet font display strategies, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If font display strategies is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const list = items.filter(i => i.visible);
const visible = list.slice(start, start + 50);
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
Check: In your own words, what is the key idea of font display strategies, and when would you use it?
Section 31 — Caching basics
Caching lets the browser reuse a previously downloaded file instead of fetching it again, which makes repeat visits far faster. It works because most files, such as styles and scripts, change rarely compared with how often they are requested. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet caching basics, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If caching basics is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
import('./HeavyChart.js');
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of caching basics, and when would you use it?
Section 32 — Cache headers
Cache headers tell the browser how long a file may be reused and when it must be revalidated. Files that change rarely can be cached for a long time, provided their filenames change when their contents change. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet cache headers, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If cache headers is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
<img src="photo.jpg" loading="lazy" alt="A market scene" width="800" height="600">
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of cache headers, and when would you use it?
Section 33 — Content hashes in filenames
A content hash in a filename changes whenever the file's contents change, so a cached old version is never mistaken for a new one. This is what makes long caching safe: the name itself announces whether the file is new. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet content hashes in filenames, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If content hashes in filenames is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const img = new Image();
img.srcset = 'small.jpg 480w, large.jpg 960w';
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
Check: In your own words, what is the key idea of content hashes in filenames, and when would you use it?
Section 34 — Service workers and caching
A service worker is a script that can intercept requests and serve cached responses, enabling offline use and very fast repeat visits. It is powerful, so its cache must be updated carefully, or users can be stuck with an old version. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet service workers and caching, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If service workers and caching is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
window.addEventListener('scroll', onScroll, { passive: true });
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of service workers and caching, and when would you use it?
Section 35 — Render-blocking CSS
A stylesheet in the head blocks rendering until it loads, because the browser does not want to paint unstyled content. Keeping stylesheets small, and splitting off styles needed only later, reduces that initial block. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet render-blocking css, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If render-blocking css is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const list = items.filter(i => i.visible);
const visible = list.slice(start, start + 50);
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of render-blocking css, and when would you use it?
Section 36 — Critical CSS
Critical CSS is the small set of styles needed for the visible top of the page, inlined so it is available immediately, while the rest of the stylesheet loads afterwards. It speeds up the first paint, but it must be kept in sync with the page. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet critical css, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If critical css is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
import('./HeavyChart.js');
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of critical css, and when would you use it?
Section 37 — Deferring JavaScript
Deferring a script means letting the HTML parse first and running the script afterwards, in order, which avoids blocking the first paint. Scripts that do not need to run before the page appears should usually be deferred. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet deferring javascript, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If deferring javascript is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
<img src="photo.jpg" loading="lazy" alt="A market scene" width="800" height="600">
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of deferring javascript, and when would you use it?
Section 38 — Async JavaScript
An async script loads in parallel and runs as soon as it arrives, without waiting for the rest of the page. It suits independent scripts such as analytics, but not scripts that depend on order or on the document being ready. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet async javascript, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If async javascript is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const img = new Image();
img.srcset = 'small.jpg 480w, large.jpg 960w';
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of async javascript, and when would you use it?
Section 39 — Reflow and repaint
Reflow is the browser recalculating layout, and repaint is it drawing pixels again; both cost work, and reflow is usually the more expensive. Reading layout values in a loop that also writes them forces repeated reflows and is a classic slowdown. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet reflow and repaint, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If reflow and repaint is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
window.addEventListener('scroll', onScroll, { passive: true });
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of reflow and repaint, and when would you use it?
Section 40 — Avoiding layout thrashing
Layout thrashing happens when code alternates between reading and writing layout in a tight loop, forcing the browser to recalculate after each write. Batching reads together and writes together avoids most of the wasted work. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet avoiding layout thrashing, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If avoiding layout thrashing is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const list = items.filter(i => i.visible);
const visible = list.slice(start, start + 50);
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of avoiding layout thrashing, and when would you use it?
Section 41 — Virtualising long lists
Virtualisation renders only the rows of a long list that are currently visible, plus a small buffer, instead of thousands of rows at once. It turns a list that would freeze the page into one that scrolls smoothly. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet virtualising long lists, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If virtualising long lists is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
import('./HeavyChart.js');
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of virtualising long lists, and when would you use it?
Section 42 — Debouncing input
Debouncing waits until the user pauses typing before acting, such as sending a search request, instead of acting on every keystroke. It reduces wasted requests and wasted rendering while still feeling responsive. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet debouncing input, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If debouncing input is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
<img src="photo.jpg" loading="lazy" alt="A market scene" width="800" height="600">
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of debouncing input, and when would you use it?
Section 43 — Throttling scroll and resize
Throttling limits how often a handler runs during continuous events such as scrolling or resizing, for example to once per animation frame. Without it, a handler can run hundreds of times a second and starve the page. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet throttling scroll and resize, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If throttling scroll and resize is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const img = new Image();
img.srcset = 'small.jpg 480w, large.jpg 960w';
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of throttling scroll and resize, and when would you use it?
Section 44 — Animations on the compositor
Animations of transform and opacity can often run on the compositor thread without involving layout or painting, which keeps them smooth. Animating layout properties such as width, by contrast, forces expensive recalculation on every frame. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet animations on the compositor, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If animations on the compositor is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
window.addEventListener('scroll', onScroll, { passive: true });
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of animations on the compositor, and when would you use it?
Section 45 — Keeping the main thread free
The main thread runs JavaScript, layout, and painting, so long tasks on it block everything else, including clicks. Breaking long work into smaller chunks, or moving heavy work off the thread, keeps the page responsive. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet keeping the main thread free, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If keeping the main thread free is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const list = items.filter(i => i.visible);
const visible = list.slice(start, start + 50);
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
Check: In your own words, what is the key idea of keeping the main thread free, and when would you use it?
Section 46 — Web workers for heavy work
A web worker runs JavaScript on a separate thread, away from the page's main thread, which suits heavy computation that does not need the document. Results are sent back by message, so the interface stays responsive while the work runs. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet web workers for heavy work, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If web workers for heavy work is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
import('./HeavyChart.js');
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of web workers for heavy work, and when would you use it?
Section 47 — Prefetching and preloading
Prefetching hints that a resource will probably be needed soon, while preloading marks a resource as needed for the current page. Used sparingly, they hide latency; used carelessly, they waste bandwidth on resources the user never needs. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet prefetching and preloading, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If prefetching and preloading is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
<img src="photo.jpg" loading="lazy" alt="A market scene" width="800" height="600">
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of prefetching and preloading, and when would you use it?
Section 48 — Reducing third-party cost
Third-party scripts, such as trackers, chat widgets, and embeds, add weight, network requests, and main-thread work that you do not control. Auditing them, lazy-loading them, and removing the ones that earn nothing is often the fastest performance win. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet reducing third-party cost, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If reducing third-party cost is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const img = new Image();
img.srcset = 'small.jpg 480w, large.jpg 960w';
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of reducing third-party cost, and when would you use it?
Section 49 — Performance budgets
A performance budget is a limit you set, such as a maximum bundle size or a maximum time to interactive, and a build that exceeds it fails. Budgets turn performance from a vague wish into a rule that is enforced before regressions ship. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet performance budgets, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If performance budgets is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
window.addEventListener('scroll', onScroll, { passive: true });
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
When a page feels slow, find the largest cost first instead of tuning small details, because one heavy image or one large script often outweighs many tiny savings.
Check: In your own words, what is the key idea of performance budgets, and when would you use it?
Section 50 — Testing on real devices
Real devices reveal problems that emulators and fast development machines hide, from slow processors to real network conditions. Testing key journeys on a modest phone, on a real connection, is the most honest performance check available. In plain terms, what the user sees should follow from a value you can point to and name, rather than from a hidden side effect in several places at once. When you first meet testing on real devices, it can look like a small detail, but it shapes how the rest of the work behaves, so it is worth understanding before the code around it grows.
Why does this matter in real work? Because front-end code is judged by what users experience. If testing on real devices is handled carelessly, the symptoms are familiar: stale information, a button that works once and then stops, or a form that loses what was typed. Users rarely report the underlying cause; they report that the site feels broken, and they leave. Getting this idea right saves the user's time and your own time when you return to the code later.
How do you apply it in practice? Start by naming the thing you are working with, then state what should happen in a single sentence before you write code. Next, make the smallest change that produces that behaviour, and look at the result in the browser rather than assuming it worked. Then try the awkward cases: an empty value, a very long value, and a rapid repeated action. Those cases are where most front-end ideas fail, not in the happy path where everything is typed correctly and the network is fast.
Here is a short example to make the idea concrete:
const list = items.filter(i => i.visible);
const visible = list.slice(start, start + 50);
Read the example slowly and notice what each part contributes. The point is not to memorise the snippet, but to see the pattern: a named value, an action that changes it, and a visible result that follows from it. Try changing one part in your head and predicting the result before you run anything, because a wrong prediction tells you exactly which part of your mental model needs correcting.
A common mistake is to rush past this idea and treat it as obvious, then to improvise a different approach in each part of a project. That is how inconsistency creeps in, and nobody can say which approach is correct. Another common mistake is to add complexity before the simple version has been tried. To check your own work, explain the idea aloud, demonstrate it with a tiny example, and try one case that should fail gracefully.
A useful habit is to measure before and after a change on the same device and connection, because a change that feels faster in development may not help real visitors.
Check: In your own words, what is the key idea of testing on real devices, and when would you use it?
Practical task
Build a small page that puts this chapter into practice. For Chapter 35, performance: loading and rendering, create one page with a clear example of the chapter's main ideas, try it in the browser, break one thing deliberately and fix it, and write a short note explaining what you learned and what you would do differently next time. Keep the page small, test it on a narrow screen as well as a wide one, and check that every interaction still behaves as you intended.
Chapter questions
- Explain, in plain words, the central idea of Chapter 35 and why it matters to users, not just to developers.
- Give an example where doing this chapter's topic badly would be visible to a user, and describe what the user would experience.
- Compare two approaches from this chapter and explain when you would choose each one.
- Describe a mistake a beginner commonly makes with this chapter's topic, how you would spot it, and how you would fix it.
- Build a tiny example that demonstrates one idea from this chapter, and explain, step by step, how you would check that it works correctly.