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
planVacationand
requestPTOto 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
Appcalls
checkPTOBalanceand
makePlans, and it puts
planVacationand
requestPTOin 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
setTimeoutregisters 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.
setTimeoutis a way of delaying the execution of its callback. Hence,
planVacationand
requestPTO, the callbacks to
setTimeout, show up after
checkPTOBalanceand
makePlansin 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
planVacationand
requestPTO(callbacks to
setTimeout) don’t appear below
Appin 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
Appinto the call stack.
Appcalls
setTimeoutand
setTimeoutgets added to call stack. It schedules
planVacationto be added to the task queue after the specified delay and then returns and leaves the call stack. Repeat for the second timeout.
Appthen calls
checkPTOBalance, and
checkPTOBalancewill get pushed onto the call stack. After
checkPTOBalancereturns,
makePlanswill get pushed onto the call stack.
When
Appeventually 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
planVacationand run it.
Thus,
planVacationand
requestPTOwill never be part of the same call stack as
Appbecause 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
planVacationbe executed before or after
requestPTO? Maybe you’d think after, since the timeout has 0ms delay, and
planVacationhas to wait for
prepareBudgetto resolve.
In actuality though, we see:
Followed by:
The Promise callback
planVacationgets 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
planVacationis done and the microtask queue is empty, the event loop gains control of the program back and will push
requestPTOonto 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?
Let’s face it: errors are a reality of the programming process. Whether you’re an experienced developer or just getting started, facing errors and errors is important.