Frontend Development 22 min read

Unveiling MPM PageData: Architecture and Multi‑Platform Rendering

This article explains how MPM's PageData serves as the core JSON abstraction that links the visual editor with various rendering engines, detailing its structure, generation process, and parsing workflows for static H5, direct H5, and mini‑program platforms.

WecTeam
WecTeam
WecTeam
Unveiling MPM PageData: Architecture and Multi‑Platform Rendering

Preface

This is the second article in the MPM sharing series. In the previous article we introduced the basic elements of MPM, a visual page builder for marketplace scenarios, and explained how those elements are derived and designed. The elements link modules and form the foundation for architecture and flow.

MPM System Architecture

MPM consists of an editing system used by operators and a page parsing engine. The editor generates PageData, which is parsed by different engines for various client environments to render the marketplace page. Both the editor and the engine implement the four system elements.

MPM architecture flow
MPM architecture flow

PageData

PageData is the medium that connects the editing state and the display state. It is a JSON abstraction of a marketplace page, containing configuration data and intermediate data such as request caches. Designing PageData correctly is key to the MPM architecture.

The standard JSON structure of PageData is:

<code>{
  "pageId": "",
  "appType": 1,
  "pageConfig": {
    "basic": {
      "type": 2,
      "env": 2,
      "bgColor": "#fff",
      "createDate": "",
      "customCode": null,
      "customCodeIn": 0,
      "expireTime": "",
      "expireUrl": "",
      "name": "",
      "path": "",
      "status": 1,
      "floorSortId": "",
      "floorSortType": "",
      "forceLogin": 0
    },
    "search": {
      "topShow": 0,
      "topRuleId": "",
      "topAd": "",
      "topBtnRd": "",
      "topKeywordShow": 0,
      "topKeywordRuleId": "",
      "bottomShow": 0,
      "bottomRuleId": ""
    },
    "share": {
      "title": "京东购物",
      "desc": "多·快·好·省",
      "imgUrl": "//wq.360buyimg.com/img/mpm/defaultShare.jpg"
    }
  },
  "userInfo": {
    "checkNewuser": false,
    "checkVip": false,
    "checkPlus": false,
    "checkBind": false,
    "checkFirstBuy": false
  },
  "componentConfig": [],
  "template": {
    "vueFnObj": {},
    "vueHook": {},
    "styleTpl": {},
    "header": "",
    "footer": ""
  },
  "dataCache": {
    "userInfo": {},
    "floorSortData": {},
    "dsCache": {}
  }
}
</code>

Key fields include:

pageId

: unique identifier of the marketplace page.

appType

: page type (1‑activity, 2‑venue, 3‑mini‑program).

pageConfig

: page‑level configuration, with sub‑objects

basic

,

search

, and

share

.

userInfo

: automatically generated user‑level checks (VIP, new user, etc.).

componentConfig

: array of floor (layer) configurations used by the parsing engine.

template

: contains Vue template functions, hooks, style templates, and optional header/footer HTML.

dataCache

: caches data such as userInfo, floorSortData, and dsCache to avoid duplicate requests.

Generation of PageData

PageData is created by the editor and stored in a SQL table. When a page is created, a record is inserted; on save, the editor syncs the latest PageData to the database; on publish, PageData is transformed into standard JSON for the parsing engines.

The database model stores fields like page_id, page_name, page_path, page_type, page_creator, page_create_date, and page_content (the serialized componentConfig).

Marketplace page data table
Marketplace page data table

PageData Generation Process

Editing a page goes through load, edit, save, and publish stages.

PageData generation process
PageData generation process

Load

The editor fetches the current PageData from the server, which may not yet be in standard structure, and performs authentication, configuration checks, and new‑page initialization.

Edit

PageData updates in real time as the operator configures the page, with Vue watch providing instant preview.

Save

Saving submits the latest PageData to the server, updates the database, and creates a preview link. The PageData is also converted to standard JSON for the parsing engine.

Publish

Publishing triggers a final save and then runs diagnostics, RD generation, accessibility checks, and automated tests before the page becomes live.

Parsing of PageData

MPM provides different parsing engines for H5 (static and direct) and mini‑program environments. The overall flow is similar but varies per platform.

Static H5 Parsing

Static H5 generates a static HTML file that includes the Vue engine and page data. The template uses placeholders ({{...}}) that are replaced with actual data, CSS, and engine scripts.

<code>&lt;!DOCTYPE html&gt;
&lt;html lang="zh-CN"&gt;
  &lt;head&gt;
    &lt;meta charset="UTF-8" /&gt;
    &lt;title&gt;{{title}}&lt;/title&gt;
    &lt;!-- 头部 JS/CSS --&gt;
    &lt;script&gt;{{topScript}}&lt;/script&gt;
    &lt;style&gt;{{topCss}}&lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;!-- 应用容器 --&gt;
    &lt;div class="mpm-app"&gt;&lt;/div&gt;
    &lt;script&gt;
      // page data
      window.__PAGE_DATA__ = {{pageData}}
      // 渲染模板
      window.__COM_TPL__ = {{template}}
      // 模板扩展方法
      window.__COM_FNOBJ__ = {{fnObj}}
      // 组件钩子函数
      window.__COM_VUEHOOK__ = {{vueHook}}
    &lt;/script&gt;
    &lt;!-- 引擎 --&gt;
    {{engineCore}}
    &lt;!-- 底部 JS --&gt;
    &lt;script&gt;{{bottomScript}}&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code>

The engine performs a preload step to fetch user identity and floor sorting data, then sorts and filters floors, registers Vue components, and finally renders each floor.

<code>function renderPage () {
  __PAGE_DATA__.componentConfig.forEach(createComponent);
  // ...
}

function createComponent (com) {
  const comId = com.id;
  // el is the floor container generated in step 2
  const el = document.querySelector(`#${comId}_con>[com-root]`);

  const data = utils.copy(__PAGE_DATA__[comId]); // deep copy config
  data.fnObj = __COM_FNOBJ__[comId]; // render function

  new Vue({
    el,
    data,
    render: __COM_TPL__[comId],
    mounted () {
      __COM_VUEHOOK__[comId]['mounted']("comId]['mounted'");
    }
  });
}
</code>

Direct H5 Parsing

Direct H5 uses a Node/Express service that reads PageData from Redis, performs the same preload, sort, and filter steps, then uses

vue-server-renderer

to stream the rendered HTML to the client.

<code>import { createRenderer } from 'vue-server-renderer';
const renderer = createRenderer();

// 页面渲染入口
async function renderPage () {
  // 输出页面头
  await context.res.write(pageTop);
  // 输出页面楼层内容
  await renderApp();
  // 输出页面尾
  await context.res.write(pageBottom);
}

// 渲染页面主体
function renderApp () {
  return Promise((resolve, reject) => {
    // 创建 app 的 Vue 实例
    let app = new Vue({
      data: rootData,
      methods: rootMethods,
      render: renderFn
    });

    // 创建渲染流
    const stream = renderer.renderToStream(app);

    // 分段输出
    stream.on('data', chunk => {
      // ...
      context.res.write(chunk);
    });

    stream.on('end', () => {
      // ...
      app.$destroy();
      resolve();
    });
  })
}
</code>

Mini‑Program Parsing

Mini‑program pages receive PageData as a JSON file, then map it to pre‑built mini‑program components that exactly match the MPM templates, rendering the page on the client.

Mini‑program parsing process
Mini‑program parsing process

Conclusion

After understanding the MPM workflow, it becomes clear that the three platform engines share much logic, leading to duplicated effort when iterating on features. A unified “write once, run on three platforms” approach is desirable, but achieving it requires careful design due to the system’s size and complexity.

MPM complexity illustration
MPM complexity illustration
Frontend DevelopmentNode.jsVueMini ProgramMPMPageDataStatic Rendering
WecTeam
Written by

WecTeam

WecTeam (维C团) is the front‑end technology team of JD.com’s Jingxi business unit, focusing on front‑end engineering, web performance optimization, mini‑program and app development, serverless, multi‑platform reuse, and visual building.

0 followers
Reader feedback

How this landed with the community

login 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.