跪拜 Guibai
← Back to the summary

Front-End Judgment: Built From Production Incidents, Not Interview Questions

How Is Front-End Technical Judgment Built?

How is front-end technical judgment built?

During a design review, a colleague proposed a technical solution: after the user fills in the form and clicks submit, the front end first stores the data to localStorage, then asynchronously sends the request to the backend. The reasoning was so that even if the network is lost, the user's data won't be lost.

Everyone nodded after the presentation.

I asked one question: If the user opens two tabs and both write to the same localStorage key, the later write overwrites the earlier one. How do you handle that?

He froze for three seconds🤔.

Then I asked: localStorage throws an exception on write in Safari's private browsing mode. Where is your try/catch?

He froze for another three seconds🤔.

The solution was ultimately redesigned. Not because I'm smarter than him, but because I've actually stepped on both of these pitfalls; the first one while working on multi-tab synchronization, the second while building a mobile page for cross-border e-commerce.

Technical judgment doesn't come from interview cramming, technical blogs, or any course. It comes from the incidents you've been burned by in production, been yelled at for, and gotten up at 3 a.m. to fix🤷‍♂️.


What Exactly Is Technical Judgment?

Gemini_Generated_Image_wulk29wulk29wulk.jpg

When you see a technical proposal, your brain automatically runs a simulation of the scenarios in which it would die. Would it fail on a weak network? Would concurrency get messy? Would the user leaving mid-session leave dirty data? Are there Safari compatibility issues? Where is the security boundary?

This simulation isn't a deliberate analytical process; it's a nearly instinctive conditioned reflex. Like a driver with ten years of experience who sees the brake lights of the car ahead and already has their foot over the brake pedal, without going through the reasoning chain: the car ahead is slowing down, so I should slow down too.

The only source of this conditioned reflex is having personally experienced the crash scenario.


5 Real Judgment Scenarios

The following 👇 each scenario is something textbooks and interview questions won't tell you.

The design looks elegant, but it dies on a weak network. What now?

A colleague proposed an update design: after the user likes a post, the front end immediately changes the UI to the liked state, then sends the request in the background. If the request fails, the UI rolls back.

The design feels great on Wi-Fi; the user doesn't perceive any latency.

But on a weak network, such as in the subway, an elevator, or a meeting room with poor signal, the request doesn't succeed or fail; it hangs for a long time. The user taps like, the UI changes, they wait 30 seconds, the request times out, the UI rolls back, and the user sees the like mysteriously disappear. Worse, if the user did other things during those 30 seconds, the rollback can mess up the state of subsequent actions.

A front-end with judgment would add these to the design👇

Gemini_Generated_Image_ttph1rttph1rttph.jpg

These aren't in any tutorial. They come from having personally been complained about by users in a weak-network environment🤷‍♂️.

The API returns correct data?

The backend colleague said that in the user list returned by the API, the avatar field always has a value.

A front-end without judgment would directly write <img src={user.avatar} />.

Gemini_Generated_Image_88vj8s88vj8s88vj.jpg

A front-end with judgment would ask: Do legacy users migrated from historical data have avatar? What about users who logged in via a third party? Or users who registered but never uploaded an avatar?

Then they would write:

<img 
  src={user.avatar || DEFAULT_AVATAR} 
  onError={(e) => { e.currentTarget.src = DEFAULT_AVATAR }}
/>

This suspicion isn't distrust of the backend colleague; it's rigor about the complexity of real production data.

Is this solution only good in a demo?

A colleague researched a front-end Excel export solution: using SheetJS to generate .xlsx files in the browser. In the demo, exporting 100 rows was instant.

A front-end without judgment would say it's fine.

A front-end with judgment would ask:

Gemini_Generated_Image_6farm16farm16far.jpg

The final judgment: exports over 1000 rows must be generated on the backend, with the front end only handling the download. Front-end export is only for quick exports of small data volumes.

Is using setTimeout enough?

An autosave feature: each time the user modifies content, a setTimeout delays 3 seconds before calling the save API.

Seems fine.

But a front-end with judgment would think:

Gemini_Generated_Image_hd7bdmhd7bdmhd7b.jpg

The correct approach is debounce + a request queue + a beforeunload fallback before page close. But the more critical judgment is: the autosave feature itself needs to be aligned with the product manager; does the user expect every single change to be saved, or is saving most of the time sufficient? These two expectations lead to completely different technical solutions.

This library has many GitHub stars, so it must be reliable!

A colleague wanted to introduce a date picker component with 8000 stars on GitHub.

A front-end without judgment looks at the star count and the screenshots in the README.md, and thinks it's fine.

A front-end with judgment opens these things to look at👇

Gemini_Generated_Image_chmj7echmj7echmj.jpg


How Does Technical Judgment Grow?

There's been a lot of talk about scenarios, but the core question: if judgment comes from experience, does that mean you can only grow by waiting to get burned?

Not entirely. You can deliberately accelerate the process.

Review every production incident

I've kept a Markdown file locally since 2019, recording a line every time I experience or hear about a production incident. The format is simple:

### 2024-03-15 Product Detail Page White Screen
- Phenomenon: Some users see a white screen on the product detail page
- Cause: The `categoryPath` field returned by the API is `null` in some old products,
  and the front end directly calls `.split('/')` causing an error
- Lesson: Any string field from the API must be null-checked before use
- Related: The backend said this field always has a value, but legacy data doesn't

Over the years, my incident list has grown to over 100 entries. Every time I do a design review or Code Review, the data source my brain runs on is this list.

Or actively read about other people's incidents

You don't have to step on every pit yourself. You can read about others' falls.

When reading, don't just focus on how it was fixed; focus on why it wasn't caught in the first place. Every root-cause analysis contains a reusable judgment rule for the future.


What Is Judgment at Its Core?

After leading teams for so many years, I increasingly believe: distinguishing a front-end engineer with 3 years of experience from one with 8 years is not about who writes more elaborate code, but who has seen more incidents.

The more production incidents you've seen, the fewer blind spots your technical proposals have. Your code may not be the most polished, but it won't break in extreme scenarios, because you've already blocked those scenarios in advance😃.

Alright, that's it for today.

Suggestion (3).gif


If you like my articles, feel free to follow my WeChat public account: 【前端技术官】.

Main sharing: front-end architecture · AI programming · workplace cognition · developer growth

前端技术官-ErpanOmer

Scan the WeChat code to follow 👆

Occasional updates, no spam, talking about genuinely useful content.