How We Tamed Vue SSR Under Massive Traffic: Caching, CDN, and Auto‑Degrade Strategies

This article recounts how a Vue‑SSR e‑commerce site was repeatedly overloaded during three promotional phases and how the team applied static‑dynamic data separation, CDN integration, application‑level caching, auto‑degrade rendering, rate‑limited APIs, and hydration fixes to achieve stable high‑traffic performance.

WeDoctor Frontend Technology
WeDoctor Frontend Technology
WeDoctor Frontend Technology
How We Tamed Vue SSR Under Massive Traffic: Caching, CDN, and Auto‑Degrade Strategies

Preface

In March we launched a promotional activity for a bank that instantly drove CPU usage to 100% and caused 502 errors. After an emergency fix for the first phase, we faced two more phases and decided to document the performance problems and solutions.

Phase 1–3: What We Did

Technical Background & Bottlenecks

The project uses a Vue + SSR architecture without any caching. Because the rendered pages contain user‑specific data and server timestamps, they cannot be cached without redesign, so high concurrency quickly maxed out CPU.

During the first phase we added more servers, then introduced caching. We considered page‑level and component‑level caching, but the product‑detail component contained dynamic data, making component caching costly. We therefore cached the whole page after stripping non‑essential dynamic content and served it via CDN.

After the activity we identified four major optimization measures:

Static‑Dynamic Data Separation – Classify data as static (unchanging over time) or dynamic (user‑specific or time‑dependent). Fetch static data on the server, let the client retrieve dynamic data during lifecycle hooks, keeping the server‑rendered HTML clean.

CDN Integration – After separating static content, push the page URLs to a CDN, ensuring query parameters that affect rendering are handled client‑side and setting appropriate expiration times.

Application‑Level Caching – Prepare for CDN failures by adding in‑memory or Redis caches for fallback.

Automatic Degrade – When all caching layers fail, return an empty template and let the browser render the page, avoiding any server load. Degrade can be triggered by monitoring CPU/load or by a special query flag.

These steps allowed us to pass load testing and launch successfully.

Phase 2 Improvements

We added traffic‑related interfaces and friendly prompts. For a few special products we needed temporary copy that was not returned by APIs. We implemented a low‑code solution that injects copy based on product IDs, accepting the risk of manual rollout and delay.

Phase 3 Enhancements

We moved product‑specific copy to a configuration service, eliminating low‑code. We also limited high‑traffic API endpoints by returning HTTP 429 when TPS thresholds are exceeded, and displayed a busy message to users.

// Unified 429 handling in getResponseErrorInterceptor
export const getResponseErrorInterceptor = ({ errorCallback }) => (error) => {
  if (!isClient) {
    // server side handling
  } else {
    // 429 handling for rate‑limited APIs
    if (+error.response.status === 429) {
      // add busy message when needed
      errorCallback(error.config.needBusyMsg ? 'Activity is too popular, please try again later' : null);
    } else {
      // other errors
    }
  }
  return throwError(error);
};

Real‑World Coding Questions

In a Vue‑SSR project a server‑side request determines whether a user is a VIP and toggles a button with v-if. This works locally but produces hydration warnings and runtime errors in production.

Analysis shows that mismatched HTML, differing server/client state, nondeterministic values (dates, random numbers), third‑party scripts, and authentication checks can cause hydration failures.

Solutions include:

Ensure valid HTML markup.

Prefer v-show over v-if for elements that depend on server‑side data, because the generated HTML is stateless.

Wrap third‑party scripts in a client-only component to prevent server rendering.

Other case‑by‑case fixes.

Reference: Vue Hydration Error article

Configuration Issues in H5 Pages

When opening the H5 link in WeChat mini‑programs, the ‘#’ separator in the configuration string was escaped to ‘\’, breaking the split logic. Replacing ‘#’ with ‘;’ solved the problem.

Additionally, the mini‑program initially blocked the page due to a legacy check that only allowed the main site and app; removing that restriction restored functionality.

Summary

Through three promotional phases we learned to separate static and dynamic data, leverage CDN, add application caches, implement auto‑degrade, handle rate‑limited APIs, and fix Vue‑SSR hydration issues, resulting in a stable high‑traffic system.

Vue SSR documentation: https://ssr.vuejs.org/zh/

Vue SSR performance practice: https://juejin.cn/post/6887884087915184141

Vue hydration error article: https://blog.lichter.io/posts/vue-hydration-error/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Performance OptimizationcachingCDNHydration ErrorsVue SSR
WeDoctor Frontend Technology
Written by

WeDoctor Frontend Technology

Official WeDoctor Group frontend public account, sharing original tech articles, events, job postings, and occasional daily updates from our tech team.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.