This article was converted by SimpRead; the original is available at blog.tangwudi.com
It’s already 2026—time has flown. Looking back, this blog—which I first set up over two years ago—has been running stably for more than two years. That may not sound especially long, but it’s been enough for me to fully experience the journey from “getting a website up and running” to “repeatedly questioning what a website truly is.”
It’s already 2026—time has flown. Looking back, this blog—which I first set up over two years ago—has been running stably for more than two years. That may not sound especially long, but it’s been enough for me to fully experience the journey from “getting a website up and running” to “repeatedly questioning what a website truly is.”
I still remember vividly how I felt the first time I truly began using WordPress: a pure, direct sense of bewilderment—not because it was complex, but precisely the opposite: because it was too smooth. Install a theme, and the site’s overall visual style instantly takes shape; add a few menu items in the admin panel and drag them into order, and the site’s structure is “built”; need a new feature? Often, just install a plugin. And as for “web pages,” most of the time they’re simply a newly published post or page—the system automatically generates an accessible URL.
All of this seemed reasonable and efficient—but at the time, something felt subtly off. I realized I hadn’t actually “built pages” myself, yet I already had a fully functional website. Many operations I’d once assumed required manual work were now fully automated by the system. This experience didn’t bring simple relief—it brought a kind of cognitive weightlessness. For a long time, I couldn’t even understand why the page’s source code contained no visible text content. In the past, editing textual content meant directly modifying the HTML source; WordPress, however, hid those underlying operations, forcing me to adapt to an entirely new way of thinking.
Later, I realized this discomfort wasn’t rooted in WordPress itself—but rather in my own pre-existing mental model of what a “website” is. If we rewind twenty-odd years, my understanding of “websites” was both clear and perfectly aligned with the technical environment of the time—the era of the “Web Design Trinity”: Fireworks, Dreamweaver, and Flash:
Fireworks handled visual mockups; Dreamweaver managed HTML structure and layout; Flash took care of interactivity and animation. Pages were “crafted” step-by-step—from design to implementation—and finally deployed to the server as static files. My undergraduate thesis website was built exactly this way.
Within that context, “building a website” was essentially synonymous with “building pages”: the page was the final artifact, and the website was merely a collection of such pages. Content, structure, and interaction were all naturally embedded within the page itself—rarely considered separately.
Precisely because of this, my first encounter with WordPress—a completely different workflow—hit me with such force. It wasn’t any single technical detail that felt unfamiliar; rather, at the cognitive level, it skipped over the entire evolutionary path I’d internalized:
Looking back now, my initial shock was entirely natural. I hadn’t progressed gradually from “static pages” to “dynamic websites.” Instead, I’d nearly leapt across a decade-plus accumulation of technological and conceptual development—going straight from the old paradigm (“a website = a collection of pages”) to the modern web model centered on content as the organizing principle. And this shift—from page-centric to content-centric—is precisely the pivotal leap that WordPress both embodies and profoundly accelerates.
As my usage deepened, I gradually realized that WordPress didn’t merely change how sites are built—it changed how people understand how websites exist on the Web. From that moment onward, the page ceased to be the sole center of gravity; instead, content became an object that could be managed, reused, and accumulated over time. It was only upon this cognitive foundation that subsequent questions—about caching, comments, frontend/backend separation, and so on—began to surface.
This article draws directly from that personal journey and reflection, using WordPress as a concrete entry point to trace the evolution of web cognition. It is neither a tutorial nor a tool comparison—it is a retrospective: retracing how we moved step-by-step from “making pages” to “managing content,” and, along the way, continually redefining what a “website” is.
If we return to the early web’s conceptual framework, “a website equals a collection of pages” wasn’t a narrow or outdated view—it was an almost self-evident consensus. At that stage, the web itself was fundamentally a document-oriented system whose core capability was astonishingly simple: given a URL, request a resource from a server, and return the result to the browser for display.
Within this model, the page was naturally the center of everything. The URL mapped directly to a file path; the server’s role was equally clear—read the corresponding file and send it back. Whether that file contained an article, an image, or a form was irrelevant; what mattered was that it was a page—accessible and displayable. A website, therefore, followed logically as a collection of such pages.
Take my static blog, staticblog.tangwudi.com, as an example. An article titled “The Awakening of Sound · Fundamentals (II): From Note Names to Numbered Notation” is accessed via the URL https://staticblog.tangwudi.com/technology/innerlight14026/:
Under the traditional page model, its URI path /technology/innerlight14026/ maps directly to a physical file path on the host’s disk: /data/staticblog/index/technology/innerlight14026/index.html:
When the browser requests that URL, the server simply reads the file and returns its contents, which the browser then renders. The article text, images, comments, or other elements are all statically embedded within that single HTML file—and the page is the final, user-facing output.
This example clearly illustrates the early web’s typical mindset: URLs map one-to-one with file paths; pages serve as content containers; websites are collections of those pages. Under this model, updating article content requires directly editing the corresponding HTML file—otherwise, users will keep seeing the old version. The system’s core assumption is simple: the page is the content, and the content is the final form.
Such an understanding was not only reasonable at the time—it was highly efficient. The page was the end result; nearly all developer effort revolved around “how to build the page”: page design, layout, interaction, and publishing formed a clear, linear production pipeline. As long as pages existed, the website existed; as long as pages were accessible, the website was deemed “functioning normally.”
Precisely under this backdrop, “building a website” and “building a page” were effectively synonymous for a long time. Content wasn’t discussed separately—it was just a block of text or a set of media assets embedded in a page. Updating content equaled editing a page; adding content usually meant creating a new page file. Relationships among pieces of content, their reuse, and their evolution weren’t central concerns in design.
This page-centric model also carried implicit assumptions, rarely questioned at the time: content wasn’t an independent entity—it was part of the page; comments, interactions, and feedback were merely parts of the rendered page output—tightly coupled with the page to form a complete response.
These assumptions worked remarkably well in the early web. Page counts were limited; update frequency low; and content lifecycles generally matched those of the pages themselves. At that scale, binding everything inside the page was not only intuitive but also easy to understand and maintain. Almost no one asked: “Should content itself be abstracted out as a separate concept?”
But as websites grew larger, this model began revealing its limits. The same type of content needed frequent updates, references, and aggregation—causing page count and complexity to explode. When content lifecycles gradually decoupled from individual pages, maintenance costs stopped scaling linearly—and pages shifted from being “endpoints” to becoming temporary containers where content happened to reside.
It was at this stage that people began realizing: perhaps the issue wasn’t that pages were poorly built—but whether pages should still bear all responsibilities. When pages were forced to shoulder the burdens of content organization, structural relationships, and long-term evolution, the page-centric web cognition model reached its critical threshold.
The next transformation wasn’t about making pages more complex—it was a far more fundamental shift: What would the web become if content were liberated from pages?
If the previous chapter depicted a well-functioning, page-centric world, this chapter explores the precise moment that world was first genuinely dislodged. This change wasn’t driven by a performance boost from any single technology—it was a deeper, foundational cognitive shift: the page was no longer the sole center; content began to be treated as an independent, self-contained entity.
Before WordPress, people rarely discussed “content” as a distinct concept. Content was always embedded in pages—alongside layout, styling, and interactivity—as part of the final output. Content existed only when the page existed; delete the page, and the content vanished. The page served both as container and endpoint.
WordPress’s first major contribution was precisely to break this binding. It introduced concepts like “posts” and “pages”—but this wasn’t mere categorization. It was a semantic abstraction (note: in WordPress terminology, a “Page” doesn’t refer to the final rendered webpage, but rather another type of content, just like a “Post”—both are data objects managed by the system. This distinction won’t be elaborated further here; just remember: both fundamentally belong to “content”).
From this moment forward, content detached from the page for the first time—becoming an entity that could be stored, managed, and evolved independently. The page was no longer the content itself, but merely one way to present that content.
This change feels utterly natural in daily use—but cognitively, it’s revolutionary: URLs no longer point to specific file paths; instead, they serve as entry points to content. Actual content is stored as structured data in a database—each post, just one independent record:
Take again the article with URI path /technology/innerlight14026/. On my main blog, it doesn’t reside in any filesystem directory. Rather, it corresponds to a single record in the wp_posts table of the WordPress database in MariaDB, with ID 14026:
Thus, the page ceases to be an indivisible final artifact—and becomes merely one view of content, generated by the system in a particular context.
Content shifts from being a “result” to being an “asset”—persistently stored as structured data, and endowed with a lifecycle that supports maintenance, evolution, and reuse. It is precisely upon this abstraction that Content Management Systems (CMS) truly come into being. Content can be updated without breaking overall structure; reorganized without rebuilding pages; aggregated, filtered, and re-presented across different times and contexts.
The semantic shift in comment systems likewise stems from this: in WordPress, comments are no longer just a block of text on a page—they exist as data attached to content, related to posts yet stored and managed independently. This design naturally opens space for interaction, analytics, and extensibility.
Yet this content-centric model isn’t cost-free. As pages evolve from “fixed outputs” to “dynamically generated views,” new complexities emerge. Content stability, interaction real-time-ness, cache effectiveness—problems previously masked by the page model now rise to the surface. And here, the next round of web architecture evolution becomes unavoidable—precisely the subject of the next chapter.
In Chapter Three, we saw websites undergo a key cognitive leap: content no longer depended on pages for existence—it was abstracted into independent, manageable, long-lived, and reusable “content entities.” Once this step was taken, the nature of websites fundamentally changed: they were no longer one-off deliverables, but living, growing content systems. Precisely at this stage, a problem that had remained inconspicuous in the early web began surfacing: performance.
In the era of “website = collection of pages,” performance wasn’t a core concern. Page count was limited, traffic predictable, and update frequency low. Even if every request triggered server-side generation, costs remained manageable. “Performance optimization” often meant upgrading to a faster server—or compressing a few images.
However, once websites evolved into content-centric systems, the situation changed dramatically. Article count kept growing; access entry points multiplied; the same piece of content might be heavily accessed at different times—or repeatedly crawled by search engines. Meanwhile, most content remains highly stable after publication—it rarely changes, yet is frequently accessed.
This shift exposed a plain fact: for the vast majority of requests, the server repeats the exact same task. Each visit triggers fresh database queries, content reassembly, template application, and full-page regeneration. Logically sound—but from a systems perspective, deeply inefficient. Thus, caching systems emerged:
Caching, at its core, introduces a new abstraction: it separates content generation from content delivery. When a page won’t change significantly in the short term, there’s no reason to regenerate it on every request. Simply store the final output and reuse it next time—dramatically reducing server load while vastly improving response speed.
In modern websites, caching goes far beyond basic page storage. Page caching, object caching, reverse-proxy caching, and CDN edge caching layer atop one another, forming the performance infrastructure of today’s web. They allow websites to remain usable and responsive—even as content volume and traffic scale exponentially.
Technically, caching appears a simple optimization—but it quietly alters the website’s operational logic. Content no longer relies solely on real-time generation; it gains a “static” representation. For most content, this causes no conflict—because most content is highly stable.
However, as websites begin incorporating dynamic interactive elements—comments, likes, login state, personalized content—naive caching logic falls short. Caches judge only whether an entire request’s output can be reused—not whether parts within the content are stable versus volatile.
For this reason, the cost of content abstraction gradually emerges. Websites efficiently handle massive stable traffic—but when dynamic interactions enter the picture, caching alone proves insufficient. This isn’t a plugin bug or misconfiguration; it’s an inherent tension that naturally arises as content systems mature and scale.
In the previous chapter, content-focused websites gained significant performance benefits through caching—stable content distributed efficiently, server load markedly reduced, responsiveness preserved even under heavy traffic. From an engineering standpoint, this is near-perfect optimization. Yet the problems didn’t end there.
In most content-driven websites, articles aren’t the only content. Comments, likes, replies, reading status, user info—though small in screen real estate—share one defining trait: they demand real-time behavior. Users expect their comment to appear immediately upon submission; refreshing and seeing no update is often unacceptable.
In WordPress’s content semantics, comments have always been treated as part of the post—attached to it, sharing the same access URL, and typically rendered together in a single page-rendering pass. From a content-modeling perspective, this design is sound: the article is content, comments are content—they jointly constitute a complete content entity.
The real conflict arises only when caching enters the picture. Caches don’t distinguish between “article” and “comment”; from their viewpoint, a URL maps to one reusable response. As long as the cache remains valid, the system returns the cached result—regardless of whether some portion of the page has changed.
A structural tension thus emerges: article bodies remain highly stable, while comments continuously change—yet within the caching system, they’re forced to share the same lifecycle. One URL must either be wholly valid or wholly invalid; caches cannot update just the comment section, nor express the semantic nuance of “content largely unchanged, but local portions require real-time refresh.”
At low traffic volumes and conservative cache policies, this conflict remains invisible. But as websites adopt longer cache durations to maximize performance, the problem amplifies: pages can stay cached for hours, while comments are delayed—or require repeated refreshes to appear.
At this point, people often blame unstable plugins, overly complex cache configurations, or “poor tuning.” But at a higher level of abstraction, this isn’t a flaw in implementation—it’s an inherent tension between two system logics: content systems emphasize structural integrity and long-term maintainability; caching systems prioritize stability and reuse efficiency. When strong real-time demands are embedded into a model built around stable content, conflict becomes inevitable.
More importantly, this tension doesn’t vanish with experience. As long as comments remain viewed as part of the page, trade-offs between “performance” and “real-time-ness” persist: shorten cache duration → performance drops; lengthen cache duration → degraded interactivity.
Viewed this way, the “comment problem” isn’t an isolated feature challenge—it’s a boundary issue inevitably exposed as content systems mature. It signals that when content is long-lived, widely distributed, and heavily cached, not all information belongs in the same rendering model.
It is precisely here that website architecture reaches a fork—and begins diverging into two paths: one maintains the existing content model while introducing increasingly sophisticated cache rules and invalidation strategies, pushing the legacy system to accommodate more dynamic needs (e.g., Cloudflare APO); the other rethinks the boundary between content and interaction—and further decomposes the system.
And that is the starting point of the next phase of architectural evolution.
In the previous chapter, we saw how content systems revealed structural tension when confronting comments and real-time interaction. This tension wasn’t due to implementation errors—it was the natural outcome of content models evolving to a certain stage: when content is long-preserved, broadly distributed, and heavily cached, cramming all interactivity into a single rendering flow rapidly escalates costs.
Website architecture thus underwent a change that appeared radical—but was, in fact, restrained: the system stopped trying to solve all problems at one layer—and instead chose to split responsibilities.
The first element re-examined wasn’t content itself—but how content is presented. In traditional CMS patterns, content storage, page generation, and user interaction were tightly bundled into a single request: the server managed content, assembled pages, and handled comments and state changes simultaneously. This model was extremely efficient at small scale—but as complexity grew, it became the very bottleneck preventing further evolution.
Frontend/backend separation thus gradually emerged in this context. It’s not a rejection of WordPress or CMS—but a further abstraction built upon their success: once content has been cleanly modeled and reliably stored, the system explicitly distinguishes two roles—one responsible for the content itself, the other for its presentation and interaction.
Under this division, the backend continues revolving around content: how it’s created, how it’s structured, how it’s preserved long-term, and how relationships among different pieces of content are maintained. The frontend, meanwhile, gradually detaches from its role as “template renderer,” focusing instead on page organization, interaction rhythm, and user-state management. They no longer couple via the singular act of “generating a page”—but collaborate through well-defined interfaces:
Consequently, content is extracted from the “complete page”: it’s no longer delivered as a finished display artifact—but as a resource that can be independently fetched and composed. The page is no longer content’s sole destination; content can be reused across different frontends, devices, and display strategies—without altering how it’s stored.
This change directly alleviates the recurring structural tension. Stable content can continue being aggressively cached, while real-time elements—comments, likes, user state—are loaded dynamically via independent requests. They no longer share a cache lifecycle, nor must compromise for each other.
From this perspective, frontend/backend separation isn’t a “burn-it-down-and-rebuild” revolution—it’s a natural division of labor emerging as systems mature. When the content system becomes sufficiently stable, it gains the very condition enabling its extraction as a foundational capability.It is precisely at this stage that websites begin to diverge in architectural form: some adopt a fully headless architecture; others combine static site generation with incremental updates; still others shift rendering to the network edge; and yet others retain traditional CMSs while only decoupling critical interactive components. The implementation paths differ widely—but the underlying motivation is remarkably consistent: to keep stable content stable, and to give dynamic parts the space they need to evolve.
Frontend-backend separation is not the end point of content systems—it is instead the sign that such systems have begun to consciously acknowledge their own boundaries. When a system can proactively decompose itself, it often signals entry into a more mature phase.
Looking back over the preceding chapters, a clear evolutionary trajectory emerges: the Web did not suddenly become complex, nor did WordPress abruptly “bloat” one day. Pages were abstracted into content entities; content began to be persistently stored and repeatedly distributed; comments, permissions, caching, and interactivity were incrementally layered on—each step emerging organically from the need to solve real-world problems.
It is precisely for this reason that we frequently hear today’s critiques of WordPress as “too heavy,” “bloated,” or “not modern enough.” These impressions often stem from genuine user experiences—but the issue lies not in the critiques themselves, but in the implicit assumptions behind them. Much of the discussion compares today’s solutions—designed from the ground up for “minimalism,” “single-responsibility,” and “complete frontend-backend separation”—against a system born over a decade ago whose core mission was long-term content management. This temporal mismatch renders such comparisons inherently unequal.
A useful analogy may help clarify this: consider World of Warcraft’s place in the history of MMORPGs.
For many veteran online gamers, World of Warcraft has always meant far more than just graphical fidelity, skill mechanics, or numerical balancing. Its significance as an era-defining title stems from its being the first to systematically establish foundational paradigms for MMORPGs—in world-building, social relationships, and long-term content evolution.
Today’s games—built on modern engines, featuring more refined mechanics and faster pacing—are indeed more “advanced” across many technical metrics. Yet their existence does not retroactively negate World of Warcraft’s historical importance. On the contrary, it is precisely because that original paradigm was thoroughly validated that successors gained the freedom to simplify, optimize, and make deliberate trade-offs.
The relationship between WordPress and modern web architectures is highly analogous.
When we call WordPress “heavy,” we often overlook a crucial point: this weight is not the result of redundant design—it is the accumulated sediment of real-world requirements layered over time. What it carries is not merely functionality, but an entire body of hard-won experience about how content exists, evolves, and is reused across the Web. It is precisely through the continual outward diffusion of this experience that modern web architectures gradually took shape: content storage and evolution remain largely entrusted to CMS-like systems, while content fetching and presentation have been delegated to new middleware layers—or even pushed out to the CDN edge.
From this perspective, this article is not a defense of WordPress, but rather a retrospective on the Web’s evolutionary path. WordPress is neither perfect nor universally suitable—but at a pivotal historical juncture, it accomplished a decisive leap: transforming websites from mere collections of pages into living, content-centric systems capable of sustained growth.
Once this is understood, many debates naturally lose their footing. What remains is no longer the question of “Should we use WordPress?”, but whether we recognize this truth: the web capabilities we now take for granted are themselves direct legacies of a revolution that has already occurred—and continues to shape us.
Note: Strictly speaking, WordPress was not the world’s first CMS—systems like Drupal, PHP-Nuke, and Movable Type predated it. Yet its revolutionary impact lay not in technical novelty, but in conceptual普及—marking the first time ordinary users truly grasped that a website is not just a set of pages, but a content system that can be actively managed and continuously evolved over time.
Content Structure Note:
This piece forms part of the “Blog Knowledge Map”. You can view the full content pathway here: Blog Knowledge Map.