How Zhihu’s Growth Team Supercharged Activity Page Performance: From Diagnosis to Real‑World Gains
This article reveals how Zhihu’s growth engineering team dissected activity‑page rendering bottlenecks, applied front‑end performance techniques such as early resource loading, image compression, pre‑rendering, and metric‑driven optimization (FCP, CLS, INP), and ultimately boosted page reach and conversion rates dramatically.
Introduction
In a fiercely competitive market, the rendering speed of activity pages directly impacts user retention and conversion. This article unveils how Zhihu’s growth R&D team used cutting‑edge techniques and strategies to comprehensively optimize page performance, guiding readers from problem diagnosis to goal achievement.
What "Growth" Means
"Growth" in the narrow sense refers to the "growth hacker" concept—people who combine product development, data analysis, and marketing to drive early‑stage product growth.
In the broader sense, "growth" is essentially marketing (4P, 4C, 4S) and is a universal business function.
Performance Evaluation Standards
Page rendering performance is crucial for any online business. Slow pages cause user drop‑off; for example, the BBC found that each additional second of load time loses 10% of users.
Core Web Vitals (LCP, CLS, INP) are the primary metrics, but for Zhihu’s activity pages the most relevant metric is First Contentful Paint (FCP) because the first image dominates the user’s first impression.
Key Metrics
Loading Speed – measured by FCP/LCP; techniques include lazy loading, non‑blocking resources, compression, HTTP/2, streaming, SSR.
Interaction – measured by CLS (Cumulative Layout Shift) to avoid layout jumps that cause mis‑clicks.
Instant Feedback – measured by INP (Interaction to Next Paint) to ensure responsive UI.
What We Did
1. Early Resource Loading
We prioritized the first four images and lowered the priority of the rest, ensuring bandwidth is first used for above‑the‑fold content. We also reordered JS loading to report user reach earlier.
2. Optimized Resource Loading Order
By loading high‑priority images first and deferring lower‑priority assets, we reduced the time to report reach events by about 600 ms.
3. Pre‑render / Pre‑load
For app users we generated offline packages that cache HTML and assets before navigation. For PC users we used an invisible iframe to preload CSS/JS/images without affecting current page metrics.
4. Image Compression (WebP)
We switched PNG/JPEG assets to WebP, achieving 25‑34% size reduction while preserving visual quality, which cut first‑image load time by ~800 ms (P95) and ~200 ms (P50).
5. Image Slicing
Long‑form images were sliced into 500 px‑high segments; the first segment dropped from 600 KB to 21 KB, reducing first‑image download from 1.5 s to ~100 ms.
6. Additional Optimizations
Server‑side 302 redirects to shorten hop count.
Compressed and split large JS bundles for parallel download.
Removed redundant base64 data from SSR HTML.
Code Samples
// Transparent placeholder image
const LazyImage = 'data:image/svg+xml;base64,……';
// Load only first 4 images eagerly
const MAX_COUNT = 4;
const lazyLoad = index >= 3;
let src = lazyLoad ? LazyImage : url;
// IntersectionObserver for lazy loading
useEffect(() => {
if (imgRef.current && lazyLoad) {
setIsLoading(true);
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
setIsLoading(false);
const img = entry.target;
img.src = url;
observer.unobserve(img);
}
});
}, { root: null, rootMargin: '40px', threshold: 0 });
observer.observe(imgRef.current);
return () => observer.disconnect();
}
}, []);
return <img src={src} ref={imgRef} alt='' />; // Assemble lazy‑load script snippets on the server
const addLazyStyle = `<script>
const lazyStyles = ${JSON.stringify(lazyStyles)};
lazyStyles.forEach(style => {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = '${templateAssetPath}' + style;
document.head.appendChild(link);
});
</script>`;
const addLazyScript = `<script>
const lazyScripts = ${JSON.stringify(lazyScripts)};
lazyScripts.forEach(script => {
var scriptDom = document.createElement('script');
scriptDom.src = '${templateAssetPath}' + script;
document.body.appendChild(scriptDom);
});
</script>`;
if (this.lazyLoadResource) {
Object.assign(preMustache, {addLazyStyle, addLazyScript});
}Results
After applying early loading and pre‑load strategies, the activity‑page reach rate on B‑Station rose from ~69% to 92.5%.
Image slicing and WebP conversion reduced first‑image P95 load time by ~800 ms and P50 by ~200 ms.
Overall, the optimizations improved user experience, reduced bounce rates, and increased conversion.
Future Directions
Integrate more industry‑standard front‑end metrics for holistic performance insight.
Build a visual performance monitoring platform for cross‑team visibility.
Develop reusable SDKs for fast metric reporting across pages.
Conclusion
Performance optimization is an endless journey; Zhihu’s growth team demonstrates a systematic, data‑driven approach that continuously pushes activity‑page performance forward.
Zhihu Tech Column
Sharing Zhihu tech posts and exploring community technology innovations.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.