Frontend's 90% Invisible Complexity
In the programmer circle's hierarchy of contempt, frontend seems to be perpetually at the bottom.
In the eyes of many backend developers, frontend is nothing more than a presentation layer for drawing buttons and calling APIs; in bootcamp advertisements, frontend is packaged as a quick shortcut to learn in three months and easily earn over ten thousand a month. Even many newcomers to frontend, after spending two days throwing together a complete backend management system using Vue and Element Plus, will develop an illusion: frontend stuff, you really just need hands😢.
Why is the outside world's misunderstanding of frontend so deep?
Because what the vast majority of people see is always only the most ideal, shortest perfect path of frontend. And in real large-scale engineering, the simplicity of frontend only lasts for that one second when the screen is rendered.
The thrill brought by What You See Is What You Get?
The low barrier to entry for frontend is an objective fact. This low barrier stems from frontend's extremely short and fast visual feedback loop.
If you write low-level storage or complex distributed locks, you might write for a week and only see a cold line of Log in the terminal. But frontend is different: type a few lines of HTML, and the browser immediately pops out a colorful card; introduce a Tailwind CSS, and instantly the page gains a premium texture.
This thrill design massively shields the underlying complexity. Modern frameworks (like React and Vue) and the extremely rich open-source component libraries wrap up all the dirty work of the DOM layer.
This leads many people to a fatal logical fallacy: Since I can draw the page so quickly, frontend engineering must be simple.
They have no idea that drawing the page only accounts for 10% of the workload in modern frontend engineering. The remaining 90% is a frantic battle in places invisible to the naked eye.
A harsh environment backend engineers will never experience🤷♂️
Many people think backend is hard because it faces high concurrency. But backend engineers often overlook an extremely superior premise: the backend's host environment is absolutely controllable.
Backend code runs on Linux clusters the company spent heavily to purchase, with unified Docker containers, predictable CPU and physical memory, and rock-solid intranet bandwidth. As long as the machine can't handle it, throwing money at more machines solves most problems.
And frontend? The host environment for frontend code is completely out of control.
Your code might run on a five-year-old cheap Android phone belonging to an elderly man in the northeast, with a half-shattered screen, only 2GB of memory, and stuffed full of junk cache; it might run on a subway during the extremely congested morning rush hour, with the network frantically oscillating between 4G and complete disconnection; it might even be forcibly injected with malicious code by users' various ad-blocking plugins and translation plugins, tampering with your native DOM.
Frontend engineers are the only group in the entire business chain who need to directly use their physical bodies to confront the bizarre fragmented environments of the real physical world. You must ensure that the business not only runs through but runs smoothly in this extremely harsh sandbox full of uncontrollable variables. How can this complexity be summarized by drawing a button?
A disaster in the dimension of state
What pushes frontend into the abyss of extreme complexity, besides the uncontrolled environment, is the elongated lifecycle.
Most backend interfaces are stateless: receive an HTTP request, query the database, assemble data, return to the client, and then this request's lifecycle is completely over (instant creation and destruction).
But frontend is a super-long-standby state machine.
When a user opens an SPA (Single Page Application), they might stay on this page for half an hour. During this process, you not only need to manage local component state and global Redux state, but also synchronize the state of the remote server, and even cover for the user's extremely brutal operating habits.
Let's look at a most common real-world scenario. When a user, in a weak network environment, frantically clicks the Submit Order button ten times in a row out of impatience, or frantically switches the left navigation Tab before the API returns.
In the eyes of a junior frontend developer, this is just a simple fetch request. But in the eyes of a senior frontend developer, this is an asynchronous race condition disaster that must be brutally suppressed.
// Simple frontend in a newbie's eyes 👉 casually send requests
async function submitData() {
await fetch('/api/submit', { method: 'POST' });
}
// A veteran's defense line against the real physical world 👉 request queue, race condition lock, and memory cleanup
const pendingRequests = new Map<string, AbortController>();
export async function safeSubmitData(payload: Record<string, any>) {
// Convert complex business payload into a unique request fingerprint
const requestKey = JSON.stringify(payload);
// If an extremely identical request exists, immediately violently kill the previous one using the underlying Signal
// Resolutely prevent the backend from processing dirty data simultaneously, always taking the user's last intent as final
if (pendingRequests.has(requestKey)) {
console.warn('Detected extremely aggressive repeated clicks, forcibly canceled the previous request');
pendingRequests.get(requestKey)!.abort();
}
const controller = new AbortController();
pendingRequests.set(requestKey, controller);
try {
const response = await fetch('/api/submit', {
method: 'POST',
body: JSON.stringify(payload),
signal: controller.signal,
headers: { 'Content-Type': 'application/json' }
});
if (!response.ok) throw new Error(`HTTP Error: ${response.status}`);
return await response.json();
} catch (err: unknown) {
// For race condition cancellations we actively triggered, silently swallow the error, absolutely not allowing the page to throw inexplicable red error text
if (err instanceof Error && err.name === 'AbortError') {
return;
}
// Encountering a real physical network disconnection, must throw upwards for Error Boundary to handle
throw err;
} finally {
// Regardless of success, failure, or being forcibly killed, must precisely clean up the Map reference, strictly preventing memory overflow caused by long page tab stays
pendingRequests.delete(requestKey);
}
}
Behind this code lies the prevention of memory leaks, the suppression of underlying network stack concurrency, and fault tolerance for extremely harsh interactions. Those who think frontend is simple will never see that beneath the seemingly calm page, this mechanism is intercepting various crashes hundreds or thousands of times per second🤔.
So, why do so many people think frontend is simple?
Because frontend frameworks and those veteran frontend engineers frantically patching leaks beneath the iceberg have disguised this world as very simple. They have encapsulated the intricate exception handling, network degradation, and memory scheduling all beneath buttons that look utterly harmless👇
Frontend has never been just about writing code. The core mission of a frontend engineer is to forcibly build an indestructible bridge between the extremely cold and harsh machine code and the extremely chaotic and unpredictable human behavior🫡
What do you think? Do you agree with my point of view😁
Top 5 of 9 from juejin.cn, machine-translated. The original thread is authoritative.
I don't quite agree. From an environmental perspective, although the frontend host environment is complex, you usually only need to support mainstream host environments, and the impact on the business is not fatal. The backend host environment is stable, but upstream and downstream dependencies are unstable. You need to consider rate limiting, circuit breaking, and flow control. Once the thread pool is full, the service becomes directly unavailable, which is fatal to the business. From a state perspective: the backend generally has more state than the frontend, and the state machine is more complex than the frontend, for example, needing to handle state jumps and reconciliation. Many people think the frontend is simple, but the underlying belief is that the frontend's impact on the business is small, and it can still run even if the code is a bit rough. Looking at it another way, even if the frontend is really complex, most companies won't give you a promotion or a raise just because a frontend engineer wrote a silky-smooth interactive animation or solved a button's rapid-click problem.
Whether it's simple or not depends on how many users there are and whether it's profitable. If it's profitable or has many users, it's quite not simple. If it's just an internal enterprise CRUD management system, then... you don't even need a frontend [facepalm]
Yes
It's just that getting started is simple.
Yes
The simplest example: people who say the frontend is simple can go look at the source code of claudecode [polite smile]
Good idea 👍
It's because they are all fools who have high standards but low ability.
[grin][grin][grin]