The Evolution of Web Forms (II): Migration and Allocation of Page Generation
本文最后更新于 91 天前,其中的信息可能已经有所发展或是发生改变,如有失效可到评论区留言。
Article Abstract
In the evolution of the Web from static pages to dynamic generation, the core issue has always revolved around adjusting the “timing and location of page generation.” In the static era, pages were directly composed of HTML files, with content and structure coupled; after the emergence of CMS, pages were dynamically generated by the server at the time of request (SSR), decoupling content from templates. As the demand for content stability increased, static site generation (SSG) moved generation forward to the build phase, reducing repetitive computing overhead. Modern applications have further migrated generation logic to the browser (CSR) to support complex interactions. Ultimately, the Web evolved a hybrid model that allocates generation methods based on content characteristics: SSG for stable parts, SSR for dynamic content, and CSR for interactive logic, forming a unified explanatory model to adapt to multi-scenario needs.
Qwen3-14B · 2026-07-17

1 Chapter One From Content to Page: There is Another Half of the Story

In the previous article (Evolution of Web Forms (I): From Page to Content—What Did WordPress Change?), we took the ”content” in web pages as an entry point to introduce the development process of content from being tightly coupled with pages in the early static web page era to gradually becoming an independently existing object.

In the era of static web pages, content and pages were almost one and the same; an HTML file both saved content and determined the final presentation effect. With the emergence of CMS like WordPress, content began to separate from pages, becoming objects that could be independently stored and managed. Later, the separation of frontend and backend further reinforced this trend, allowing content to exist completely detached from specific pages.

At this point, the Web completed an important change:Content in web pages no longer depends on the page itself. However, this is only half of the story.

In fact, for users, whether content is saved in HTML files, databases, or obtained through APIs, these are all imperceptible to them; what they ultimately see is always a complete web page. A user's browser will neither directly display a record in a database nor directly understand a piece of JSON data; what it ultimately needs is still an HTML result that can complete the page display.

In other words,Content can exist independently, but web pages still ultimately need to be “generated” at some point, in some way.

Thus, a more natural question arises:When and in what way does this independently existing content turn into the web pages we ultimately see?

This question did not seem to exist in the era of static web pages, because the page itself was the final result; but as content gradually decoupled from pages, “generating pages” instead became an independent task.

What is more interesting is that although the way users browse web pages has not fundamentally changed for over twenty years, the generation process of web pages has been continuously evolving: sometimes, it is already prepared before the user visits; sometimes, it needs to wait until the user initiates a visit to be temporarily generated; and other times, it is generated by the browser at runtime.

From the user's perspective, we are always browsing the same web pages; but inside the Web,when and by whom web pages are generated has undergone continuous evolution.

2 The Era of Static Web Pages: When “Generation” Was Not Yet a Problem

If we pull our perspective back to the early stages of the Web, we will find an interesting fact:“The question of ”how web pages are generated" did not actually exist in that era. The reason is simple—in the initial Web, a web page itself was already a completed result.

In the era of static web pages, a website was essentially a set of HTML files scattered on a server. When a user visited a certain URL, what the server did was very direct: find the corresponding file, and then return it as-is to the browser. There was no database involved, no runtime logic, and no so-called “page assembly” process.

In other words, web pages at that time were not “generated,” butalready existed in the first place; what the browser received was not a “generation result,” but an already written HTML document, and its responsibility was also very simple: parse this document and render it into the page that the user sees.

At this stage,pages, HTML files, and the final display results could almost be regarded as the same object. One URL corresponded to one HTML file, and one HTML file corresponded to one page. This relationship was so simple and direct that the entire system did not need to introduce the abstraction layer of ”generating pages” at all.

Looking back from today's perspective, this structure might even seem a bit ”too simple”: no middle layer, no dynamic computation, and no runtime generation; everything was determined before the user visited. But precisely because of this, it possessed a characteristic that many subsequent systems found hard to achieve—determinism: no matter when it was accessed, the same URL would always return the exact same HTML file; the content seen by the browser also remained consistent. Therefore, in that era, the complexity of the Web was almost entirely concentrated on ”how content was written,” rather than ”how pages were generated.”

However, this simplicity did not come without a price.

With the development of the Internet, websites carried more and more information. News websites published new articles every day, corporate websites constantly added product descriptions, personal blogs continued to accumulate content, and forums and communities even generated new posts every moment. Websites began to grow from dozens of pages to hundreds, thousands, or even more. At this point, people gradually realized that what was truly growing was not the page structure, but the content within the pages.

Taking blogs as an example, every article has almost the same page layout: title, body, publication time, author information, comment area... what is truly different is often just the article content itself.

However, in the era of static web pages, every time an article was added, it meant adding a complete HTML file; if the navigation bar, footer, or sidebar of the entire website needed to be modified, every related page had to be modified one by one.

The problem was not that this method was impossible to implement, but thatall changes could only act directly on the final HTML files: content updates required modifying HTML; page layout adjustments required modifying HTML; and even structures shared among multiple pages could only be maintained manually.

It was not until then that people gradually realized a question they had never seriously thought about before:Since many web pages share the same page structure, and what truly changes is only the content within them, why do we still write them as one independent HTML file after another? In other words, what we truly need to maintain might not be the pages themselves, but the content within the pages, as well as the rules that determine how this content is organized and displayed.

When this line of thinking emerged, the Web also ushered in its first major turning point—pages began to no longer be the final objects directly saved, but instead became a result that could be ”produced” based on content.

It was also at this very moment that “generating web pages” became a problem that truly needed to be solved for the first time.

3 From “Saving Pages” to “Generating Pages”

At the end of Chapter Two, we mentioned an important change: as the scale of websites grew larger, people realized that what needed long-term maintenance was not one structurally similar HTML file after another, but the truly constantly changing content within them. Thus, for the first time, web pages were no longer viewed as final objects that needed to be directly saved, but instead began to become a kind ofResults that can be dynamically generated based on content。

Then, a new question naturally arises:If the page is no longer saved in advance, when exactly is it generated?

The earliest answer to this question was not a specific technology, but a brand-new Web philosophy. It held that what truly needs to be saved long-term is the content, while the page can wait until a user visits to be temporarily generated based on the content. In other words, the server is no longer responsible merely for returning an already existing HTML file to the browser, as in the static webpage era, but begins to take on another new task:Real-time generation of the final HTML page based on existing content—CMSs represented by WordPress are the most typical practice of this philosophy.

For the browser, almost nothing has changed: when a user visits a URL, the browser ultimately receives is still a complete HTML document, and the final rendered effect of the page has no essential difference from the static webpage era. What has truly changed is actually in a place invisible to the browser: in the past, the server returned an already existing HTML file; but now, what the server returns is afreshly generatedHTML page.

This means that each time a user visits, the server undergoes a new processing flow: it first finds the content corresponding to the user's request, then fills in the title, body, author, publication time, and other information based on a pre-designed page template, and finally generates the complete HTML and sends it to the browser. The entire process happens within the brief hundreds of milliseconds while the user waits for the webpage to load.

To the browser, where this HTML comes from does not matter; it always just receives a standard HTML document and is then responsible for rendering it.

Therefore, from the user's perspective, the Web has barely changed.What has truly changed is the time when the webpage is born: In the static webpage era, webpages already existed long before a user visited; whereas in the WordPress era, a webpage does not truly ”come to life” until after a user initiates a visit.

Because of this, the Web possessed true ”dynamic” capabilities for the first time: adding a new article no longer meant adding a new HTML file, but simply adding a new content record; modifying the page layout of the entire website no longer required modifying all pages one by one, but only adjusting a unified page template.

Webpages began to truly become aresult generated at runtime, rather than a file that needs long-term maintenance.


Today, we usually refer to this method ofdynamically generating the HTML page by the server after a user initiates a request and then returning it to the browseras SSR (Server-Side Rendering)For example, with the familiar WordPress, each time an article is visited, it reads the database, executes PHP programs, and finally generates a complete HTML page to return to the browser. This is a typical SSR model:

image.png

It is worth noting that SSR is not a new technology invented by WordPress, but a unified term later coined by people for this category of page generation methods. For this article, what is more important is to understand the evolutionary thinking behind it:Webpages began to shift from “existing in advance” to “generated upon request.”


However, while this approach solved one problem, it also brought a new cost. Since every single visit requires regenerating the page, the server must repeat the same work over and over again. For websites with low traffic, this extra overhead is almost negligible; but as the scale of the website continues to expand, this ”generate once per visit” model also begins to gradually expose new problems.

Thus, the evolution of the Web did not stop. People began to think:For those webpages that barely change, is it really necessary to regenerate them every single time they are visited?

4 When “Generating Every Time” Starts to Become Unnecessary

In the CMS ecosystem represented by WordPress, the Web entered the stage of “dynamically generating pages” for the first time. Pages no longer existed in advance in the form of HTML files, but were generated in real-time by the server based on content and templates when a user initiated a visit. This approach was reasonable for a long time, and for websites with continuously changing content, this model solved a core problem:After the decoupling of content and page structure, pages can be dynamically reconstructed.

But with the further development of the Web, a new problem began to gradually surface: not all content changes frequently. On the contrary, after a large number of webpages are generated, their content remains stable for a long time. For example, a blog post, a documentation page, or a product introduction page, once published, are often only modified occasionally rather than changing continuously.

But under the SSR model, these pages are still treated as objects that “need to be regenerated upon every visit.” That is to say, even if the content has not changed at all, the server must still repeatedly execute the same process: read content → apply template → generate HTML → return to browser. Looking at the result, the HTML generated each time is almost identical.

This is precisely where the problem gradually manifests:If the result generated each time is the same, is the act of “regenerating it every single time” itself still necessary?

Once this question is raised, the premise of the entire model begins to shake. Because the essence of SSR is: recalculating the page for every request. But the reality turns out to be: most requests are actually just repeatedly calculating an already determined result.

Thus, a new optimization idea began to emerge: since pages are stable in most cases, is it possible to save this result after the first generation? If the page has not changed, subsequent requests would no longer need to re-execute the generation process, but could directly return the already generated result. In other words, the Web began to move from “generating every time” to “generating once.”

This is the background against which static generation began to appear. In this model, the timing of page generation is pushed further forward, no longer occurring when a user visits, but at an earlier stage—when content is updated or the website is built. The generation process no longer depends on every single request, but becomes a one-time calculation process. Subsequent visits simply reuse the already generated results.

From the user's perspective, all of this still remains unchanged. What they see is still a complete webpage, and the loading speed might even be faster. But inside the system, the way webpages are generated has undergone a subtle yet crucial change—it is no longer “request-driven generation,” but has become “generate in advance + reuse.”


Today, this method of “generating the HTML page in advance before a user visits and directly reusing it in subsequent requests” is commonly referred to as SSG (Static Site Generation)For example, Hexo、Hugo and other static blog systems are typical SSG models. They generate all HTML pages in advance when publishing the website. Afterwards, when a user visits, the Web server only needs to directly return the already generated files, without needing to temporarily generate pages:

image.png

Its key difference from SSR (Server-Side Rendering) does not lie in “whether to generate pages,” but inthe point in time when page generation occurs: SSR occurs at request time, while SSG is completed in advance during the publishing phase.

From an evolutionary perspective, SSG is not a replacement for SSR, but a structural optimization aimed at the problem of “the same content being repeatedly generated.”


But at the same time, this approach also leads to a new question: if pages are already generated during the build phase, how should these already generated pages be updated when the content changes?

The evolution of the Web did not stop here; on the contrary, this question will further drive the next structural change.

5 When “Generation” Starts to Enter the Browser

In the SSG model, the generation of webpages is moved further forward: pages are no longer dynamically generated when users visit, but are already completed during the build phase. Subsequent requests simply return the already generated HTML results. From the perspective of results, this approach is highly efficient—pages are no longer repeatedly calculated, server pressure is significantly reduced, and response speeds are more stable.

But with the development of this model, a new problem begins to gradually emerge: if the page is already completed in advance during the build phase, how should those changes that only occur after the user actually visits be handled? In other words, SSG solves the problem of ”generation being too slow”, but it also makes another class of requirements start to become more prominent:Not all page content can be determined in advance during the build phase.

For websites with stable content, this is not a problem. But another important feature of the Web is: interaction. Users do not just read pages; they also operate pages. Clicking buttons, toggling states, filtering content, loading more data... all these behaviors mean that pages are not just “displaying results”, but also need to constantly change during runtime.

And in the SSG model, this kind of change is difficult to express naturally. Because the page has already been fixed during the generation phase, it no longer possesses the ability to “regenerate”. Thus, a new boundary begins to become clear:Static generation solves “how pages are built”, but does not answer “how pages change during use”.

This problem was ultimately pushed to the browser side. With the continuous enhancement of JavaScript capabilities, the browser is no longer just a “tool for displaying HTML”, but begins to possess the ability to execute complex logic. Pages no longer rely entirely on the server to be generated, but can instead continue to be “supplemented” and “transformed” by the browser after loading is complete.

Under this model, the browser begins to take on a portion of the work that originally belonged to the server. Data can be fetched after the page loads; the interface can be recalculated when the user operates; even the entire page structure can be reorganized during runtime. That is to say, the “generation” of the webpage no longer occurs only once, nor does it occur only on the server, but instead begins to enter a new phase:Runtime Generation。

And this change ultimately leads to a very clear model: the page is no longer the final result output by the server, but an application constantly running in the browser. In this model, the role of the server is further weakened. It is no longer responsible for generating the complete page, but merely provides data and interfaces. The real page structure and logic of change are completely handed over to JavaScript in the browser.

Thus, the generation logic of the Web migrated completely for the first time: from the server to the client.


Today, this method where “pages are mainly generated at runtime by JavaScript in the browser” is commonly referred to as CSR (Client-Side Rendering)In recent years, a large number of Web applications developed based on modern front-end technologies such as React、Vue and others belong to this model. When users visit a website, the browser first downloads the application code, and then JavaScript generates the page content on the client side:

image.png

Unlike SSR and SSG, the core change of CSR does not lie in “when generation occurs”, but inthe location where generation occurs migrating from the server to the browser。

Under this model, the server is more responsible for providing data interfaces, while the page structure and rendering logic are completed by the browser at runtime.


But this model also brings new structural changes, because when generation occurs entirely in the browser, the initially loaded page is often just an “empty shell”. The real content needs to be gradually built through additional logic after the page loads. This causes a noticeable difference to appear between the initial presentation and the final state of the page. The structure of the Web also becomes more dynamic as a result, but at the same time, more complex.

Thus, the question of “who should generate the page” also begins to no longer have only one answer.

6 From “Choosing Generation Methods” to “Allocating Generation Methods”

In the preceding evolutionary process, the changes in the Web have always revolved around the same core problem:When should webpages be generated?

In the era of static webpages, this problem did not even exist, because webpages themselves were already existing files. In the CMS phase represented by WordPress, webpages began to be dynamically generated when users visited, with generation occurring at request time. Subsequently, SSG moved generation forward to the build phase, allowing pages to be fixed before they were visited. CSR, on the other hand, further changed the location where generation occurs, transferring this process to the browser's runtime.

Looking at this main thread, the evolution of the Web seems to have always been doing the same thing: constantly adjusting “the point in time when generation occurs” and “the location where it occurs”. But after the Web developed to the stage of complex applications, a more fundamental problem began to emerge. Webpages in reality are often not a unified whole.

Taking a typical modern page as an example, it usually contains multiple contents of different natures at the same time: some parts hardly change, such as the article body or documentation; some parts update over time, such as recommended content or list data; some parts depend on user status, such as login information or personalized content; and some parts require frequent interaction, such as comment areas, pop-ups, or local components.

If one still insists that “a page only uses one generation method”, a structural problem will arise:Any single generation model can only optimize a certain class of scenarios and cannot adapt to all parts at the same time.

For example, for websites like news homepages and forums that need to display the latest content in real-time, if static generation is fully adopted, then every content update requires rebuilding the page, which clearly lacks flexibility; but if request-time generation is fully adopted, even content that remains unchanged for a long time, such as website navigation, footers, and article bodies, needs to be recalculated upon every visit, which brings additional runtime overhead.

Meanwhile, some pages emphasize real-time interaction, such as admin dashboards, online documents, or instant messaging, which are more suitable for processing by the browser at runtime; at the same time, other pages emphasize content display, and if they also rely entirely on browser generation, they often have obvious disadvantages in terms of first-screen loading speed, search engine indexing, and social platform previews.

This shows that different types of content and different usage scenarios have different requirements for webpage generation methods.The real problem is no longer “which generation method is the best”, but “which part of the page is more suitable for which generation method”.

Thus, the evolution of the Web has also entered a new phase:Pages are no longer generated as a whole, but instead, the generation work is distributed to different times and different locations based on the characteristics of different parts.

Under this new structure, a page can have multiple generation logics coexisting at the same time: stable parts can be generated in advance during the build phase; dynamic parts can be generated by the server at request time; and interaction-related parts can be completed in the browser at runtime. These different generation methods no longer compete with each other, but instead begin to coexist within the same page.

From the outside, users still see a complete webpage. But inside the system, this webpage is no longer a unified generation result, but a structure assembled collaboratively by multiple different generation mechanisms.

When the Web developed to this stage, the problem of “generating webpages” itself also changed. It was no longer a “choose one of three: SSR, SSG, or CSR” choice, but became a structural problem: where should the different parts of the page be generated respectively?


Frameworks commonly seen in the modern Web, such as React / Next.js / Nuxt, are not essentially a new generation paradigm; they are merely the result of combining and distributing the three “locations where generation occurs” discussed earlier—request-time generation (SSR), pre-generation (SSG), and runtime generation (CSR)—within the same system.


7 Migration of Generation Rights: The Unified Explanatory Model of the Web

If we return to the original problem, the entire article actually always revolves around the same core:When and where exactly are webpages generated?

In the era of static webpages, this problem was not prominent, because webpages themselves were already existing results. Users visiting a URL was essentially just fetching an already written HTML file; “generation” was not an independent process. As the Web structure gradually became complex, and pages and content began to decouple, this problem gradually emerged. But even so, for a long time, it remained merely an implementation detail within the system, rather than becoming an independent design dimension.

It was not until the Web entered a more complex stage that “how webpages are generated” truly became a question that could be explicitly designed. From this moment on, the evolution of the Web no longer revolved around specific technologies, but around the same core dimension:The location and timing of page generationIf we abstract this dimension, we can roughly obtain an evolutionary axis like the following:

image.png

Under this dimension, the Web at different stages is merely choosing different ways of taking values, rather than introducing new problems themselves: ultimately, whether it is SSR, SSG, CSR, or their combinations, they are essentially just different expressions of this dimension under different constraints.

From this perspective, the so-called technological evolution of the Web is not a history of linear technological development, but rather a process of the same problem being continuously redistributed at different positions in the system.

And when we return to this abstract layer, we will find that all complex concepts can ultimately be reduced to a simpler question:At this stage, which part of the system undertakes page generation?

This is the unified explanation for the evolution of the entire Web's form.


Note: SSR, SSG, and CSR are not strictly a chronological evolutionary chain, but rather three abstract ways of dividing the question of “when page generation occurs and which part of the system is responsible for it.” In the actual development of the Web, these approaches have coexisted for a long time and are constantly combined and reused in different scenarios. For the sake of narrative coherence, this article unfolds linearly according to the evolutionary path of this question, but this is only an order of presentation and does not mean that these technologies appeared in this order historically.


📚 Series Articles: The Evolution of Web Forms (2 / 2)
12

📌 Content Structure Prompt:
This content belongs to the "Blog Knowledge Map" part, you can view the complete content path from here: Blog Knowledge Map 。
View Related Categories · 3 Matches
📎 Related Articles
Share this article
The blog content is original, please indicate the source when reposting! The RSS address of the blog is:https://blog.tangwudi.com/feed, welcome to subscribe; if needed, you can join theTelegram Groupto discuss questions together.
No Comments

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗ
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
Kaomoji
Emoji
Little Dinosaur
Flower!
Previous
Next
       

👋 Welcome to “Wudi's Personal Blog”

Here, long-term exploration is mainly carried out around the following directions:

🧱 Personal Digital Infrastructure and Blog System Construction
☁️ Cloudflare and Network Architecture Practice
🧠 AI and Knowledge System Exploration
🛡️ Network Security and Access Optimization
🎵 Music and Sound Cognition
👁️ Cognitive Perspectives and Worldviews