Due to the particularity of the automobile business, Tmall Auto built its own H5 page for product details based on the Rax multi-page application.Custom business details carry many business capabilities and delivery scenarios.With the development of business and the increase of content on the page, experience problems such as too long blank screen time began to appear.



Front-end performance optimization is an old-fashioned problem. Our pages have already undergone experience optimization such as first-screen interface merging, image lazy loading, and skeleton screen. If we want to further improve user experience, we must start with the rendering mechanism and rendering container. From the perspective of the container, the functions such as data pre-request and resource offline caching provided by the pha container natively provided by Taobao can effectively improve the H5 page experience in Mobile Taobao. However, the end of other channels lacks container-like capabilities, and needs to find a way out from the direction of the rendering mechanism.

SSR (Server Side Render) is a rendering scheme relative to the existing rendering mechanism CSR (Client Side Render). When the user requests page resources through the client side (Client Side), the CSR gets an empty document, and then generates the document through the data request and execution of the rendering script, and finally displays it to the user. What SSR gets after the request is the complete document rendered by the server side (Server Side) through the data request script. Because it does not strongly rely on the ability of the client, it has more stable performance and better user experience.

In order to improve the browsing experience of users outside of Taobao, especially for low-end and mid-end users, we conducted SSR-based exploration of custom store details, and completed the Rax multi-page application to Raxx Transformation of full-stack applications, the following is our transformation process.

code structure

The project’s current Rax multi-page application system and the target system Rax full-stack application are based on the Rax framework, and the directory structure is relatively similar. The full-stack application adds server-side rendering functions and FaaS related project configurations on the basis of multi-page applications. The directory of Rax multi-page application is as follows:

├── src│   ├── app.json                    # 路由及页面配置│   ├── components/                 # 自定义业务组件│   ├── pages/                      # 页面├── build.json                      # 工程配置├── package.json└── tsconfig.json

The Rax full-stack application directory is as follows:


├── src│   ├── apis                      # 函数源码│   │   ├── configuration.ts│   │   ├── lambda/               # 接口│   │   ├── render                # 渲染函数目录                       │   │   │   ├── home/             # 渲染函数,需与 pages 里的页面名一一对应       │   │   │   └── ....../  │   │   └── typings/              # 数据类型定义│   ├── pages                     # 页面      │   │       ├── home/   │   │       └── ....../   │   ├── document/                 # 文档结构│   ├── app.json                  # 路由及页面配置│   └── typings.d.ts├── build.json                    # 工程配置├── f.yml                         # 函数平台配置├── midway.config.ts.             # midway 配置,主要指定接口和渲染目录├── package.json└── tsconfig.json

From the perspective of the directory, the core business logic that hosts page rendering, such as pages and components, does not need to be changed. In SSR mode, what the server returns is no longer an empty document, but a rendered document frame, so it is necessary to keep the code runnable in the Node environment. Since the car manufacturer does not have such environmental constraints in the development of Rax multi-page applications, it puts forward the requirement of environmental simulation for technical transformation, which will be emphasized later.

data request

In CSR mode, after entering the page, the main interface data is pulled, and js is executed to complete page rendering. Under SSR, the main interface data needs to be obtained on the server side to complete the document rendering on the server side.

What the client gets is just a dry document, and it needs to execute js again to activate the document’s event monitoring, status transfer, etc., and become an interactive page. This process also has a vivid name called hydrate:

Changes in the request process

Due to the change of request timing, the request and its before and after logic need to be moved to the server for execution.

Auto dealer details are based on a self-built end-to-end rendering solution (XRoot) for interface design and page rendering. The interface data is a set of components, including the name of each component and the props required by the corresponding component. We encapsulate a set of XRoot components to automatically perform interface requests, data injection, and page rendering.

On the home page of Shangde, the work requested by this interface is not just data pull and injection, but also undertakes a series of business logic before and after the request (such as setting global variables, disaster recovery processing, etc.). The logic is abstracted and summarized, and the business logic is aggregated into beforeRequest and afterResponse:

In SSR mode, the main interface request is executed on the server side, and its execution logic is:

afterResponse Part of the logic is the processing of the data itself, which is implemented on the server side. The other part is UI-related and needs to be executed again in the client Hydrate phase.

Simulation implementation of middle layer gateway

In the Ali Group, the interaction between the mobile interface and the backend will go through a layer of MTOP gateway. The MTOP gateway provides capabilities such as protocol analysis, security protection, and stability assurance. In SSR mode, data requests from the server cannot pass through this gateway, but directly access the backend API.

At this time, the relevant MTOP capabilities that the business depends on need to be manually completed under the SSR on the business side, and what directly affects page rendering is MTOP’s processing of hollow data on the interface:

The median value of the original interface data is null Attributes have been processed by the MTOP layer. If the SSR does not delete the empty attribute, the default value of the front end will be problematic:


const { text, tip = '默认提示' } = tagsList[0];console.log(tip); // 非空处理前:null ;非空处理后:'默认提示'

Here is a simple utility function to do this:


export const deleteNullProperties = (obj: Object | Array<any>) => {  const memory = new Set();  const fn = (obj) => {    if (memory.has(obj)) return obj;    if (['[object Object]', '[object Array]'].includes(Object.prototype.toString.call(obj))) {      for (const [key, value] of Object.entries(obj)) {        if (value === null) {          delete obj[key];        } else {          obj[key] = fn(value);        }      }    }    memory.add(obj);    return obj;  }  return fn(obj);}

In addition, the MTOP gateway also provides the analysis and transmission of the user login state, and the SSR side also needs the business to read the user login information from the cookie by itself.


environmental simulation

Generally speaking, due to the differences between the server-side and browser-side environments, developers will consciously pay attention to the environment differences when making front-end and back-end isomorphic applications, so as to avoid accessing browser objects at inappropriate times and causing errors on the SSR side.

However, since this is a renovation project, historical projects only focus on CSR scenarios, which are inevitably full of unexpected DOM/BOM access. At this time, there are several solutions:

From the perspective of transformation costs and maintenance costs, using framework capabilities and introducing community solutions are two ideas that can be explored at low cost.

Framework capability

The Rax full-stack application framework itself provides the ability to simulate the browser environment on the server side, so as to ensure the consistency of SSR and CSR coding as much as possible. The basic principles of its environment variable simulation are:

  1. The simulated information can be derived from server-side data, such as location and navigator.

  2. The simulated information will not cause errors in code execution logic, such as the simulation of localStorage.

It can be seen from this that the framework simulation capability is not intended to simulate the environment, on the contrary it is still trying to provide some real and useful information for the page. Therefore, the simulation capabilities provided by the framework are relatively limited, and some common methods do not have empty method space. For example, an undefined error will be reported when trying to call window.addEventListener.

Due to the existence of the Hydrate stage, our purpose is only to hope that the code can not report errors on the server side, and the secondary rendering on the client side will provide more accurate information, and the framework capabilities cannot meet the needs.

jsdom – a server-side environment library from the community


jsdom is a pure JavaScript implementation of many web standards, notably the WHATWG DOM and HTML standards. The project does not exist to simulate a server-side environment, its main goal is to simulate a sufficient subset of web browsers so that pages can run on the server-side to test and scrape real-world web applications.




Its powerful ability to simulate the browser environment can help us avoid modification of the project source code.


Because jsdom also pursues the simulation of functionality, while it is powerful, unexpected problems may occur when the server is running, which requires detailed testing. When using jsdom, I also encountered some version compatibility problems, which can be solved by reducing the library version and dynamic loading.


other problems

downgrade strategy

The Rax full-stack application framework adopts a middleware downgrade strategy. Any error reported on the SSR side will automatically return an empty document to the client, and the client will initiate a data request and render, that is, downgrade to a CSR.

downgrade logic


Downgrade middleware source code











The business side can also use the useCSRRenderer hook function provided by the framework to perform active degradation as needed:









self-closing tag problem



Accustomed to react’s JSX syntax system, we usually write many self-closing tags to improve readability and code cleanliness:

// 自定义组件的自闭合<MyComponent />
// 原生标签的自闭合<div />








But in fact the HTML specification does not support support for <div /> Analysis, take a simple demo as an example:










In the developer’s expectation, b and c are at the same level, and d is a subtag of c. But in the actual rendering result, c becomes a child of b.


A superficial understanding of this situation is that browsers treat self-closing tags as normal
<div>
header processing, for which a
</div>
.In the end, the closing tags are not enough, and the browser automatically adds two
</div>
resulting in a change in the document structure:



Why can writing self-closing tags in JSX get the expected results? In fact, the CSR framework side does this for us, as mentioned in react’s official documentation:
React address: https://react-cn.github.io/react/tips/self-closing-tag.html



From a practical point of view, the rendering of the Rax framework on the CSR side also does similar processing, but the server-side rendering of the Rax full-stack application does not. The document generated on the SSR side simply returns the self-closing tag as it is:



Document structure at different stages

Since the browser judges that the ssr document is inconsistent with the client’s expectations during the hydrate phase, it will be discarded and re-rendered, so this processing has no functional problems. It’s just that the first screen optimization function of SSR is lost. Before the Rax team perfects the problem of self-closing tags, the business side needs to avoid writing self-closing tags that are not custom tags.

Functional synchronization with the CSR repository


Because we are a transformation of the CSR project, in order not to affect the online function, another application warehouse has been opened. With the transformation going on, the original CSR project has been constantly iterating to meet new requirements.


with the help of
git merge --allow-unrelated-histories
mechanism, we don’t have to invest too much in code synchronization. However, to maintain two sets of applications for one business scenario, the cost of communication, maintenance, and testing is still very high.


next step


As mentioned earlier, the maintenance costs of both applications are high. Because the framework foundations of the two are consistent, we hope to combine the two applications to at least reduce the cost of code synchronization and communication. After communicating with technical support students, I found that there is no such precedent, and there may be many unexpected problems, so this part is still in trial and error.



summary

With the practice of this server-side rendering (SSR) transformation and upgrading, I also have a deeper understanding of the front-end rendering mechanism. Although SSR has many advantages over CSR, it has not become the mainstream mode of Web rendering because it is not easy to build SSR applications: you need to be familiar with server-side development, understand the environment differences between server and client, service deployment, server operation and maintenance, etc. , put forward higher requirements for front-end development.

The vigorous development of cloud-native infrastructure and the gradual improvement of Nodejs FaaS function service construction will greatly reduce the access threshold of SSR applications. Front-end developers will only need to focus on business logic to easily obtain SSR capabilities, and users will have more opportunities to get a better interactive experience.


team introduction

We are the automotive technology team of Alibaba’s Taobao Technology. We are a department integrating R&D, data, and algorithms. We use the Internet + digital to vertically integrate the automotive industry to create the ultimate experience for consumers to watch, buy, and maintain cars online. Here, you will come into contact with the core technology of new retail, transaction, supply chain, settlement, position operation, etc. Here, the team atmosphere is harmonious, the business is developing rapidly, and there are many technical challenges, allowing you to have business thinking and technical depth. On the road of rapid development of Ali Automobile, we look forward to your joining!

¤
Extended reading
¤

3DXR Technology | Terminal Technology | Audio and Video Technology

server technology | Technical Quality | Data Algorithms


This article is shared from the WeChat public account – Big Taobao Technology (AlibabaMTT).
If there is any infringement, please contact support@oschina.cn to delete it.
This article participates in the “OSC Source Creation Project”, and you are welcome to join in and share it together.

#SSR #Transformation #Practice #Tmall #Car #Dealer #Details #Page #Personal #Space #Big #Taobao #Technology #News Fast Delivery

Leave a Comment

Your email address will not be published. Required fields are marked *