Designing Responsive WordPress Pages with HTML and CSS
In this article, we'll explore how developers can design responsive WordPress pages using HTML and CSS, providing practical tips for both new and experienced developers.
Event loop clearly explained
Profiling is commonly associated with performance optimization, but its applications extend far beyond that. For example, I had previously written on how profiling data can help estimate latency impact of infrastructure downsizing.
Increasingly, one of the things I’m starting to appreciate more about profiling is that it can help you understand how a language works.
As the title suggests, let’s look at Javascript. I have this block of code in a simple React app.
function App() {
setTimeout(planVacation, 0);
setTimeout(requestPTO, 0);
checkPTOBalance();
makePlans();
return (
...
);
}
Here, we put planVacation
and requestPTO
to be within setTimeout
, to be executed after a 0ms delay. Note: There’s no guarantee the timer will run exactly on schedule, so the actual delay will be ≥ 0ms.
How do you think the Flame Chart for this code will look like?
First, a little background on profiling. The Chrome DevTools profiler is a wall time profiler. A wall time profiler samples the call stack at a set interval, e.g. every 1ms or 10ms.
If you have some code that looks like this:
const apple = () => {
banana();
beer();
}
const banana = () => {
carrot();
}
const beer = () => {
carrot();
}
The Flame Chart would look like
Now, let’s go back to our slightly more complicated example.
function App() {
setTimeout(planVacation, 0);
setTimeout(requestPTO, 0);
checkPTOBalance();
makePlans();
return (
...
);
}
Here, the main App
calls checkPTOBalance
and makePlans
, and it puts planVacation
and requestPTO
in setTimeouts to be executed after a ≥ 0ms delays.
If you’re not familiar with Javascript, you might think the Flame Chart would look like:
If you are familiar with Javascript, maybe you think it’d look like:
Javascript is asynchronous and it’s common knowledge that setTimeout
registers its callback to be executed later, after the specified delay.
However, actually, the Flame Chart would look more like this:
The timeout callbacks appear separately from App
, even though they’re registered within App
.
Here are actual screenshots from Chrome DevTools:
Followed by:
Note: setTimeout may not always appear as a frame. In the screenshot below, it does appear. This is because setTimeout’s execution time is short, so the probability of hitting it while sampling is low.
What do these observations say about Javascript?
If you’ve worked with Javascript, you’re probably familiar with the phrase:
“Javascript uses an event-loop to handle asynchronous executions.”
Profiling Javascript code reveals precisely how this works and what this means.
As mentioned already, asynchronous means the execution of some functions can be delayed. setTimeout
is a way of delaying the execution of its callback. Hence, planVacation
and requestPTO
, the callbacks to setTimeout
, show up after checkPTOBalance
and makePlans
in the Flame Chart.
If the callbacks to setTimeouts can be delayed, it means they’re not immediately put onto the call stack. Thus, they must go somewhere else. This somewhere else is called the task queue.
Here’s our example again:
function App() {
setTimeout(planVacation, 0);
setTimeout(requestPTO, 0);
checkPTOBalance();
makePlans();
return (
...
);
}
Notice how planVacation
and requestPTO
(callbacks to setTimeout
) don’t appear below App
in the Flame Chart even though they’re registered there and the timer is set with a 0ms delay.
This is due to how the event loop works.
An event loop is, as its name suggests, a loop. Very simplified, it’s like:
while (true) { // loop
const nextTask = taskQueue.pop()
nextTask.run()
}
The event loop dequeues a task from the task queue and runs it. When the task is running, the control of the program is given to the call stack. When the task itself returns, the control of the program is given back to the loop. The loop will then dequeue the next task and invoke it, and so on and so forth.*
In our example, we first push App
into the call stack. App
calls setTimeout
and setTimeout
gets added to call stack. It schedules planVacation
to be added to the task queue after the specified delay and then returns and leaves the call stack. Repeat for the second timeout. App
then calls checkPTOBalance
, and checkPTOBalance
will get pushed onto the call stack. After checkPTOBalance
returns, makePlans
will get pushed onto the call stack.
When App
eventually returns and is removed from the call stack, the control of the program is given to the event loop, and the event loop will dequeue planVacation
and run it.
Thus, planVacation
and requestPTO
will never be part of the same call stack as App
because the event loop will only dequeue these tasks when the existing call stack is empty.
Let’s make our example slightly more complex and add in a Promise.
function App() {
setTimeout(requestPTO, 0);
prepareBudget().then(planVacation);
checkPTOBalance();
makePlans();
return (
...
);
}
const prepareBudget = () => {
return new Promise((resolve) => {
...
});
}
Will planVacation
be executed before or after requestPTO
? Maybe you’d think after, since the timeout has 0ms delay, and planVacation
has to wait for prepareBudget
to resolve.
In actuality though, we see:
Followed by:
The Promise callback planVacation
gets executed before the timeout callback requestPTO
. That’s unexpected?
If Promises are put into the same queue as the timeout callbacks, and if queues operate on a first-in-first-out principle, then we’d see the Promise execute after the timeout callbacks. This means Promises have to be put into a separate queue than the timeout callbacks.
In Javascript, Promises are put into the microtask queue. You might have noticed from the screenshot above the “Run Microtasks” frame.
Both the call stack and the microtask queue are part of the Javascript V8 engine. The event loop and the task queue are not. Tasks in the microtask queue will get executed before the control of the program is passed back to the event loop.
Once planVacation
is done and the microtask queue is empty, the event loop gains control of the program back and will push requestPTO
onto the call stack.
Profiling has many use cases other than performance optimization. Cost saving is one of them. As illustrated in this article, the Chrome Profiler reveals many insights into the internal workings of Javascript. Thus, understanding how a language works under the hood is another use case of profilin
Originally published at medium.com.
In this article, we'll explore how developers can design responsive WordPress pages using HTML and CSS, providing practical tips for both new and experienced developers.
Why did we bother building all these fancy web interfaces, when all we ever needed was a text box?
Did you visit a website and think, “I could build something cooler than that”? Yes, we have all been there. However, if you don’t have a strategy ready to develop your idea into a real, working website, that first spark of inspiration will