This is an automated email from the ASF dual-hosted git repository.

ovilia pushed a commit to branch dev-5.5.0
in repository https://gitbox.apache.org/repos/asf/echarts-handbook.git

commit a3f570a945f471297ceb23ab2a51d9af43b2cd66
Author: Ovilia <zwl.s...@gmail.com>
AuthorDate: Tue Feb 6 17:53:35 2024 +0800

    doc: add doc for ssr apache/echarts#18381
---
 contents/en/basics/release-note/5-5-0.md    |  21 +++++
 contents/en/how-to/cross-platform/server.md | 119 +++++++++++++++++++++++---
 contents/en/how-to/interaction/drag.md      |   2 +-
 contents/zh/basics/import.md                |   8 +-
 contents/zh/basics/release-note/5-5-0.md    |  21 +++++
 contents/zh/how-to/cross-platform/server.md | 125 ++++++++++++++++++++++++----
 contents/zh/how-to/interaction/drag.md      |   2 +-
 7 files changed, 266 insertions(+), 32 deletions(-)

diff --git a/contents/en/basics/release-note/5-5-0.md 
b/contents/en/basics/release-note/5-5-0.md
new file mode 100644
index 0000000..072982a
--- /dev/null
+++ b/contents/en/basics/release-note/5-5-0.md
@@ -0,0 +1,21 @@
+# Apache ECharts 5.5.0 Features
+
+## Enhanced ESM Support
+
+This feature is a significant change to the default ESM package, specifically 
designed for developer testing and Node.js usage in module customization 
scenarios.
+
+Previously, ECharts only exported `*.esm` files in npm (in the lib directory 
of the npm package). While this worked well in bundlers, it didn’t perform as 
well in the Node.js runtime and some Node.js-based testing frameworks like 
vitest and jest.
+
+With this new feature, we’ve made several changes to improve this:
+
+- Added `"type": "module"` to package.json
+- Added `"exports": {...}"` to package.json
+- Added some `package.json` files to the sub-directory, which only contain 
`"type": "commonjs"`.
+
+These changes mean that files like `echarts/core.js` can now be resolved as 
ESM in environments like pure Node.js, vitest, jest, and create-react-app.
+
+Please note that if using `"exports"`, the files that are not declared in 
"exports" will be invisible from outside any more. Also, the path must start 
with `'.'`.
+
+We’ve also ensured that this new feature is compatible with a variety of 
environments, including runtime (node / vitest / jest(create-react-app) / ssr / 
…) and bundlers (webpack / rollup / vite / esbuild / …).
+
+We’re excited about this new feature and believe it will significantly improve 
the developer experience.
diff --git a/contents/en/how-to/cross-platform/server.md 
b/contents/en/how-to/cross-platform/server.md
index 77d89d7..fd69db2 100644
--- a/contents/en/how-to/cross-platform/server.md
+++ b/contents/en/how-to/cross-platform/server.md
@@ -18,9 +18,17 @@ Server-side rendering also has some limitations, especially 
some operations rela
 
 ## Server-Side SVG Rendering
 
-If you are using 5.3.0 and newer, we strongly recommend that you use the new 
zero-dependency server-side string based SVG rendering solution introduced in 
5.3.0.
+### Server-Side SVG Rendering
+
+> Version Update:
+>
+> - 5.3.0: Introduced a new zero-dependency server-side string based SVG 
rendering solution, and support for initial animation
+> - 5.5.0: Added a lightweight client runtime, which allows some interaction 
without the need to load the full ECharts on the client side
+
+We introduced a new zero-dependency server-side string based SVG rendering 
solution in 5.3.0.
 
 ```ts
+// Server-side code
 const echarts = require('echarts');
 
 // In SSR mode the first container parameter is not required
@@ -48,9 +56,9 @@ The overall code structure is the almost same as in the 
browser, starting with `
 
 - Firstly, since the SVG is rendered on the server side is string based, we 
don't need a container to display the rendered content, so we can pass `null` 
or `undefined` as the first `container` parameter in the `init`.
 - Then in the third parameter of `init` we need to tell ECharts that we need 
to enable server-side rendering mode by specifying `ssr: true` in the display. 
Then ECharts will know it needs to disable the animation loop and event modules.
-- We also have to specify the height and width of the chart, so if your chart 
size needs to be responsive to the container, you may need to think about 
whether server-side rendering is appropriate for your scenario.
+- We also have to specify the `height` and `width` of the chart, so if your 
chart size needs to be responsive to the container, you may need to think about 
whether server-side rendering is appropriate for your scenario.
 
-In the browser ECharts automatically renders the result to the page after 
`setOption` and then determines at each frame if there is an animation that 
needs to be redrawn, but in NodeJS we don't do this after setting `ssr: true`. 
Instead, we use `renderToSVGString` to render the current chart to an SVG 
string, which can then be returned to the front-end via HTTP Response or saved 
to a local file.
+In the browser ECharts automatically renders the result to the page after 
`setOption` and then determines at each frame if there is an animation that 
needs to be redrawn, but in Node.js we don't do this after setting `ssr: true`. 
Instead, we use `renderToSVGString` to render the current chart to an SVG 
string, which can then be returned to the front-end via HTTP Response or saved 
to a local file.
 
 Response to the browser
 
@@ -58,14 +66,14 @@ Response to the browser
 res.writeHead(200, {
   'Content-Type': 'application/xml'
 });
-res.write(chart.renderToSVGString());
+res.write(svgStr); // svgStr is the result of chart.renderToSVGString()
 res.end();
 ```
 
 Or save to a local file
 
 ```ts
-fs.writeFile('bar.svg', chart.renderToSVGString(), 'utf-8');
+fs.writeFile('bar.svg', svgStr, 'utf-8');
 ```
 
 Here is a complete server-side SVG rendering example in CodeSandbox.
@@ -77,7 +85,7 @@ Here is a complete server-side SVG rendering example in 
CodeSandbox.
      sandbox="allow-forms allow-modals allow-popups allow-presentation 
allow-same-origin allow-scripts"
    ></iframe>
 
-### Animations in Server-side Rendering
+#### Animations in Server-side Rendering
 
 As you can see in the example above, even using server-side rendering, ECharts 
can still provide animation effects, which are achieved by embedding CSS 
animations in the output SVG string. There is no need for additional JavaScript 
to play the animation.
 
@@ -91,9 +99,9 @@ setOption({
 });
 ```
 
-## Server-side Canvas rendering
+### Server-side Canvas rendering
 
-If you want the output to be an image rather than an SVG string, or if you're 
still using an older version, we'd recommend using 
[node-canvas](https://github.com/Automattic/node-canvas) for server-side 
rendering, [node-canvas](https://github.com/Automattic/node-canvas) is Canvas 
implementations on NodeJS that provide an interface that is almost identical to 
the Canvas in the browser.
+If you want the output to be an image rather than an SVG string, or if you're 
still using an older version, we'd recommend using 
[node-canvas](https://github.com/Automattic/node-canvas) for server-side 
rendering, [node-canvas](https://github.com/Automattic/node-canvas) is Canvas 
implementations on Node.js that provide an interface that is almost identical 
to the Canvas in the browser.
 
 Here's a simple example
 
@@ -139,7 +147,7 @@ Here is a complete example in CodeSandbox
      sandbox="allow-forms allow-modals allow-popups allow-presentation 
allow-same-origin allow-scripts"
    ></iframe>
 
-### Loading of images
+#### Loading of images
 
 [node-canvas](https://github.com/Automattic/node-canvas) provides an `Image` 
implementation for image loading. If you use to images in your code, we can 
adapt them using the `setPlatformAPI` interface that was introduced in `5.3.0`.
 
@@ -162,12 +170,18 @@ echarts.setPlatformAPI({
 
 If you are using images from remote, we recommend that you prefetch the image 
via an http request to get `base64` before passing it on as the URL of the 
image, to ensure that the image is loaded when render.
 
-## Server-Side Rendering with Hydration
+## Server-Side Rendering and Hydration
+
+### Solution A: Server-Side Rendering with a lazy-loading ECharts on the 
Client Side
+
+With the latest version of ECharts, the server-side rendering solution can do 
the following things along with rendering the chart:
+
+- Support for initial animation (i.e., the animation that is played when the 
chart is first rendered)
+- Highlighting styles (i.e., the highlighting effect when the mouse moves over 
a bar in a bar chart)
 
-Features that cannot be supported by server-side rendering include
+But there are features that cannot be supported by server-side rendering:
 
 - Dynamically changing data
-- Highlighting the data item where the mouse is hovered
 - Clicking on a legend to toggle whether the series is displayed or not
 - Moving the mouse to show a tooltip
 - Other interaction-related features
@@ -186,3 +200,84 @@ Here is an example of building a CodeSandbox with SVG for 
server-side rendering
    ></iframe>
 
 As we can see, from the user experience point of view, there is almost no 
secondary rendering process, and the whole switching effect is very seamless. 
You can also use a library like 
[pace-js](https://www.npmjs.com/package/pace-js) to display the loading 
progress bar during the loading of `echarts.js` as in the above example to 
solve the problem of no interactive feedback before the ECharts are fully 
loaded.
+
+Using server-side rendering with client-side rendering along with a 
lazy-loading `echarts.js` on the client side is a good solution for scenarios 
where the first screen needs to be rendered quickly and then the interaction 
needs to be supported. However, it takes some time to load the `echarts.js` and 
before it is fully loaded, there is no interactive feedback, in which case, a 
"Loading" text might be displayed to the user. This is a commonly recommended 
solution for scenarios where the  [...]
+
+### Solution B: Server-Side Rendering with a lightweight client runtime
+
+Solution A provides a way for implementing complete interactions, but in some 
scenarios, we don't need complex interactions, we just hope to be able to 
perform some simple interactions on the client side based on server-side 
rendering, such as: clicking the legend to toggle whether the series is 
displayed. In this case, can we avoid loading at least a few hundred KBs of 
ECharts code on the client side?
+
+Starting from version v5.5.0, if the chart only needs the following effects 
and interactions, it can be achieved through server-side SVG rendering + 
client-side lightweight runtime:
+
+- Initial chart animation (implementation principle: the SVG rendered by the 
server comes with CSS animation)
+- Highlight style (implementation principle: the SVG rendered by the server 
comes with CSS animation)
+- Dynamically changing data (implementation principle: the lightweight runtime 
requests the server for secondary rendering)
+- Click the legend to toggle whether the series is displayed (implementation 
principle: the lightweight runtime requests the server for secondary rendering)
+
+```html
+<div id="chart-container" style="width:800px;height:600px"></div>
+
+<script 
src="https://cdn.jsdelivr.net/npm/echarts/ssr/client/dist/index.js";></script>
+<script>
+const ssrClient = window['echarts-ssr-client'];
+
+let isSeriesShown = {
+  a: true,
+  b: true
+};
+
+function updateChart(svgStr) {
+  const container = document.getElementById('chart-container');
+  container.innerHTML = svgStr;
+
+  // Use the lightweight runtime to give the chart interactive capabilities
+  ssrClient.hydrate(main, {
+    on: {
+      click: (params) => {
+        if (params.ssrType === 'legend') {
+          // Click the legend element, request the server for secondary 
rendering
+          isSeriesShown[params.seriesName] = !isSeriesShown[params.seriesName];
+          $.get('...?series=' + JSON.stringify(isSeriesShown)).then(svgStr => {
+            updateChart(svgStr);
+          });
+        }
+      }
+    }
+  });
+}
+
+// Get the SVG string rendered by the server through an AJAX request
+$.get('...').then(svgStr => {
+  updateChart(svgStr);
+});
+</script>
+```
+
+The server side performs secondary rendering based on the information passed 
by the client about whether each series is displayed (`isSeriesShown`) and 
returns a new SVG string. The server-side code [is the same as 
above](#server-side-svg-rendering), and will not be repeated.
+
+> About state recording: Compared with pure client-side rendering, developers 
need to record and maintain some additional information (such as whether each 
series is displayed in this example). This is inevitable because HTTP requests 
are stateless. If you want to implement a state, either the client records the 
state and passes it like the above example, or the server retains the state 
(for example, through a session, but it requires more server memory and more 
complex destruction logic [...]
+
+Using server-side SVG rendering plus client-side lightweight runtime, the 
advantage is that the client no longer needs to load hundreds of KBs of ECharts 
code, only needs to load a less than 4KB lightweight runtime code; and from the 
user experience, very little is sacrificed (supports initial animation, mouse 
highlighting). The disadvantage is that it requires a certain development cost 
to maintain additional state information, and it does not support interactions 
with high real-time re [...]
+
+## Decide the Rendering Solution According to the Scenario
+
+Above, we introduced several different rendering solutions, including:
+
+- Client-side rendering
+- Server-side SVG rendering
+- Server-side Canvas rendering
+- Client-side lightweight runtime rendering
+
+These four rendering methods can be used in combination. Let's summarize their 
respective applicable scenarios:
+
+| Rendering Solution | Loading Volume | Loss of Function and Interaction | 
Relative Development Workload | Recommended Scenario |
+| --- | --- | --- | --- | --- |
+| Client-side rendering | ~1000KB | None | Minimum | The first screen load 
time is not sensitive, and there is a high demand for complete functionality 
and interaction |
+| Client-side rendering ([partial package 
importing](basics/import#shrinking-bundle-size) on demand) | >400KB | Large: 
the packages not included cannot use the corresponding functions | Small | The 
first screen load time is not sensitive, there is no strict requirement for 
code volume but hope to be as small as possible, only use a small part of 
ECharts functions, no server resources |
+| One-time server-side SVG rendering | ~20KB | Large: unable to dynamically 
change data, does not support legend toggle series display, does not support 
tooltips and other interactions with high real-time requirements | Medium | The 
first screen load time is sensitive, low demand for complete functionality and 
interaction |
+| One-time server-side Canvas rendering | ~200KB | Largest: the same as above 
and does not support initial animation, larger image volume, blurry when 
enlarged | Medium | The first screen load time is sensitive, low demand for 
complete functionality and interaction, platform restrictions cannot use SVG |
+| Server-side SVG rendering plus client-side ECharts lazy loading | ~20KB + 
1000KB | Medium: cannot interact before lazy loading is completed | Medium | 
The first screen load time is sensitive, high demand for complete functionality 
and interaction, the chart is best not needed for interaction immediately after 
loading |
+| Server-side SVG rendering plus client-side lightweight runtime | ~20KB + 
4KB, an additional ~20KB per update request | Medium: Cannot implement 
interactions with high real-time requirements | Large (need to maintain chart 
status, define client-server interface protocol) | The first screen load time 
is sensitive, low demand for complete functionality and interaction, very 
strict requirements for code volume, not strict requirements for interaction 
real-time |
+| Server-side SVG rendering plus client-side ECharts lazy loading, using 
lightweight runtime before lazy loading is completed | ~20KB + 4KB + 1000KB | 
Small: Cannot perform complex interactions before lazy loading is completed | 
Largest | The first screen load time is sensitive, high demand for complete 
functionality and interaction, sufficient development time |
+
+Of course, there are some other combination possibilities, but the most common 
ones are the above. I believe that if you understand the characteristics of 
these rendering solutions, you can choose the appropriate solution based on 
your own scenario.
diff --git a/contents/en/how-to/interaction/drag.md 
b/contents/en/how-to/interaction/drag.md
index 85a995f..72440d1 100644
--- a/contents/en/how-to/interaction/drag.md
+++ b/contents/en/how-to/interaction/drag.md
@@ -87,7 +87,7 @@ myChart.setOption({
 });
 ```
 
-In the code above, API 
[convertToPixel](api.html#echartsInstance.convertToPixel) is used to convert 
data to its "pixel coodinate", based on which each graphic elements can be 
rendered on canvas. The term "pixel coodinate" means the coordinate is in 
canvas pixel, whose origin is the top-left of the canvas. In the sentence 
`myChart.convertToPixel('grid', dataItem)`, the first parameter `'grid'` 
indicates that `dataItem` should be converted in the first [grid component 
(cartesian)](${option [...]
+In the code above, API 
[convertToPixel](${mainSitePath}api.html#echartsInstance.convertToPixel) is 
used to convert data to its "pixel coodinate", based on which each graphic 
elements can be rendered on canvas. The term "pixel coodinate" means the 
coordinate is in canvas pixel, whose origin is the top-left of the canvas. In 
the sentence `myChart.convertToPixel('grid', dataItem)`, the first parameter 
`'grid'` indicates that `dataItem` should be converted in the first [grid 
component (carte [...]
 
 **Notice:** `convertToPixel` should not be called before the first time that 
`setOption` called. Namely, it can only be used after coordinate systems 
(grid/polar/...) initialized.
 
diff --git a/contents/zh/basics/import.md b/contents/zh/basics/import.md
index 7415006..255ecfd 100644
--- a/contents/zh/basics/import.md
+++ b/contents/zh/basics/import.md
@@ -83,6 +83,8 @@ myChart.setOption({
 
 我们在示例编辑页的“完整代码”标签提供了非常方便的生成按需引入代码的功能。这个功能会根据当前的配置项动态生成最小的按需引入的代码。你可以直接在你的项目中使用。
 
+> v5.5.0 版本开始使用 ESM 作为默认的模块规范,查看可能的 [Breaking 
Changes](https://github.com/apache/echarts/pull/19513#issuecomment-1916237700) 
以及 [Pull Request](https://github.com/apache/echarts/pull/19513)。
+
 ## 在 TypeScript 中按需引入
 
 对于使用了 TypeScript 来开发 ECharts 的开发者,我们提供了类型接口来组合出最小的 `EChartsOption` 
类型。这个更严格的类型可以有效帮助你检查出是否少加载了组件或者图表。
@@ -106,7 +108,7 @@ import { LabelLayout, UniversalTransition } from 
'echarts/features';
 import { CanvasRenderer } from 'echarts/renderers';
 import type {
   // 系列类型的定义后缀都为 SeriesOption
-  BarSeriesOption, 
+  BarSeriesOption,
   LineSeriesOption
 } from 'echarts/charts';
 import type {
@@ -116,8 +118,8 @@ import type {
   GridComponentOption,
   DatasetComponentOption
 } from 'echarts/components';
-import type { 
-  ComposeOption, 
+import type {
+  ComposeOption,
 } from 'echarts/core';
 
 // 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
diff --git a/contents/zh/basics/release-note/5-5-0.md 
b/contents/zh/basics/release-note/5-5-0.md
new file mode 100644
index 0000000..5c1a25a
--- /dev/null
+++ b/contents/zh/basics/release-note/5-5-0.md
@@ -0,0 +1,21 @@
+# Apache ECharts 5.5.0 特性介绍
+
+## 增强的 ESM 支持
+
+为了让开发者在测试和 Node.js 环境使用更方便,我们在这个版本中对 ESM 的识别问题进行了优化。
+
+以前,ECharts 只在 npm(npm 包的 lib 目录中)导出 `*.esm` 文件。虽然这在 bundlers 环境表现良好,但 Node.js 
环境和一些基于 Node.js 的测试框架(如 vitest 和 jest)中的表现并不理想。
+
+有了这个新功能,我们做了几个改变以改善这个问题:
+
+- 在 `package.json` 中添加了 `"type": "module"`
+- 在 `package.json` 中添加了 `"exports": {...}`
+- 在子目录中添加了一些只包含 `"type": "commonjs"` 的 `package.json` 文件
+
+这些改变意味着,像 echarts/core.js 这样的文件现在可以在像纯 Node.js、vitest、jest 和create-react-app 
这样的环境中解析为 ESM。
+
+请注意,如果使用 "exports",那么在 "exports" 中未声明的文件将无法从外部访问。此外,路径必须以 ’.' 开头。
+
+我们还确保了这个新功能与各种环境兼容,包括运行时(Node.js/vitest/jest(create-react-app)/ssr/…)和打包器(webpack
 / rollup / vite / esbuild / …)。
+
+我们相信它将显著提高开发人员的体验,因此很高兴地为大家介绍这个新功能。
diff --git a/contents/zh/how-to/cross-platform/server.md 
b/contents/zh/how-to/cross-platform/server.md
index 9299f4e..bfc1d93 100644
--- a/contents/zh/how-to/cross-platform/server.md
+++ b/contents/zh/how-to/cross-platform/server.md
@@ -16,11 +16,19 @@
 
 使用服务端渲染也有一定的局限性,尤其是和交互相关的一些操作无法支持。因此,如果有交互需求,可参考下文的“服务端渲染 Hydration”。
 
-## 服务端 SVG 渲染
+## 服务端渲染
 
-如果你在使用 5.3.0 以及更新的版本,我们强烈推荐你使用 5.3.0 里新引入的零依赖的服务端 SVG 字符串渲染方案:
+### 服务端 SVG 渲染
+
+> 版本更新:
+>
+> - 5.3.0 版本:使用零依赖的服务端 SVG 字符串渲染方案,并支持图表的初始动画
+> - 5.5.0 版本:新增客户端轻量运行时,客户端无需加载完整 ECharts 即可实现部分交互
+
+5.3.0 里新引入了零依赖的服务端 SVG 字符串渲染方案:
 
 ```ts
+// 服务端代码
 const echarts = require('echarts');
 
 // 在 SSR 模式下第一个参数不需要再传入 DOM 对象
@@ -48,9 +56,9 @@ chart = null;
 
 - 首先因为在服务端会采用字符串拼接的方式来渲染得到 
SVG,我们并不需要容器来展示渲染的内容,所以我们可以在`init`的时候第一个`container`参数传入`null`或者`undefined`。
 - 然后我们在`init`的第三个参数中,我们需要通过显示指定`ssr: true`来告诉 ECharts 我们需要开启服务端渲染的模式,该模式下 
ECharts 会关闭动画循环的模块以及事件交互的模块。
-- 
在服务端渲染中我们也必须要通过`width`和`height`显示的指定图表的高和宽,因此如果你的图表是需要根据容器大小自适应的话,可能需要思考一下服务端渲染是否适合你的场景了。
+- 
在服务端渲染中我们也必须要通过`width`和`height`显示的指定图表的高和宽,因此如果你的图表是需要根据容器大小自适应的话,可能需要思考一下服务端渲染是否适合你的场景了。一种可能的解决方案是,首屏获取到图表容器大小后,请求服务端渲染图表,然后在客户端渲染图表;当用户交互改变容器大小时,重新请求服务端渲染。
 
-在浏览器中我们在`setOption`完之后 ECharts 就会自动进行渲染将结果绘制到页面中,后续也会在每一帧判断是否有动画需要进行重绘。NodeJS 
中我们在设置了`ssr: true`后则没有这个过程。取而代之我们使用了`renderToSVGString`,将当前的图表渲染到 SVG 
字符串,进一步得再通过 HTTP Response 返回给前端或者缓存到本地。
+在浏览器中我们在`setOption`完之后 ECharts 就会自动进行渲染将结果绘制到页面中,后续也会在每一帧判断是否有动画需要进行重绘。Node.js 
中我们在设置了`ssr: true`后则没有这个过程。取而代之我们使用了`renderToSVGString`,将当前的图表渲染到 SVG 
字符串,进一步得再通过 HTTP Response 返回给前端或者缓存到本地。
 
 HTTP Response 返回给前端:
 
@@ -58,17 +66,17 @@ HTTP Response 返回给前端:
 res.writeHead(200, {
   'Content-Type': 'application/xml'
 });
-res.write(chart.renderToSVGString());
+res.write(svgStr); // svgStr 是上面 chart.renderToSVGString() 得到的字符串
 res.end();
 ```
 
 或者保存到本地:
 
 ```ts
-fs.writeFile('bar.svg', chart.renderToSVGString(), 'utf-8');
+fs.writeFile('bar.svg', svgStr, 'utf-8');
 ```
 
-下面是一个完整的在 CodeSandbox 中搭建一个最简单的 NodeJS 服务器然后使用 ECharts 服务端 SVG 渲染的效果:
+下面是一个完整的在 CodeSandbox 中搭建一个最简单的 Node.js 服务器然后使用 ECharts 服务端 SVG 渲染的效果:
 
 <iframe 
src="https://codesandbox.io/embed/heuristic-leftpad-oq23t?autoresize=1&codemirror=1&fontsize=12&hidenavigation=1&&theme=dark";
      style="width:100%; height:400px; border:0; border-radius: 4px; 
overflow:hidden;"
@@ -77,7 +85,7 @@ fs.writeFile('bar.svg', chart.renderToSVGString(), 'utf-8');
      sandbox="allow-forms allow-modals allow-popups allow-presentation 
allow-same-origin allow-scripts"
    ></iframe>
 
-### 服务端渲染中的动画效果
+#### 服务端渲染中的动画效果
 
 上面的例子中可以看到,就算是服务端渲染 ECharts 也可以提供动画效果,这个动画效果是通过在输出的 SVG 字符串中嵌入 CSS 
动画实现的。并不需要额外的 JavaScript 再去控制动画。
 
@@ -91,9 +99,9 @@ setOption({
 });
 ```
 
-## 服务端 Canvas 渲染
+### 服务端 Canvas 渲染
 
-如果你希望输出的是一张图片而非 SVG 字符串,或者你还在使用更老的版本,我们会推荐使用 
[node-canvas](https://github.com/Automattic/node-canvas) 来实现 ECharts 
的服务渲染,[node-canvas](https://github.com/Automattic/node-canvas) 是在 NodeJS 上的一套 
Canvas 实现,它提供了跟浏览器中 Canvas 几乎一致的接口。
+如果你希望输出的是一张图片而非 SVG 字符串,或者你还在使用更老的版本,我们会推荐使用 
[node-canvas](https://github.com/Automattic/node-canvas) 来实现 ECharts 
的服务渲染,[node-canvas](https://github.com/Automattic/node-canvas) 是在 Node.js 上的一套 
Canvas 实现,它提供了跟浏览器中 Canvas 几乎一致的接口。
 
 下面是一个简单的例子
 
@@ -130,7 +138,7 @@ res.write(buffer);
 res.end();
 ```
 
-下面是一个完整的在 CodeSandbox 中搭建一个最简单的 NodeJS 服务器然后使用 ECharts 服务端 Canvas 渲染的效果:
+下面是一个完整的在 CodeSandbox 中搭建一个最简单的 Node.js 服务器然后使用 ECharts 服务端 Canvas 渲染的效果:
 
 <iframe 
src="https://codesandbox.io/embed/apache-echarts-canvas-ssr-demo-e340rt?autoresize=1&codemirror=1&fontsize=12&hidenavigation=1&&theme=dark";
      style="width:100%; height:400px; border:0; border-radius: 4px; 
overflow:hidden;"
@@ -139,7 +147,7 @@ res.end();
      sandbox="allow-forms allow-modals allow-popups allow-presentation 
allow-same-origin allow-scripts"
    ></iframe>
 
-### 图片的加载
+#### 图片的加载
 
 [node-canvas](https://github.com/Automattic/node-canvas) 
提供了图片加载的`Image`实现,如果你在图表中使用了到了图片,我们可以使用`5.3.0`新增的`setPlatformAPI`接口来适配。
 
@@ -162,12 +170,18 @@ echarts.setPlatformAPI({
 
 如果你的图片是需要远程获取的,我们建议你通过 http 请求先预取该图片得到`base64`之后再作为图片的 URL 传入,这样可以保证在 Response 
输出的时候图片是加载完成的。
 
-## 服务端渲染 Hydration
+## 服务端渲染与客户端二次渲染
+
+### 方案一:首屏服务端渲染与客户端渲染懒加载
+
+最新版本的 ECharts 服务端 SVG 渲染除了完成图表的渲染外,支持的功能包括:
+
+- 图表初始动画(例如:柱状图初始化时的柱子上升动画)
+- 高亮样式(例如:鼠标移动到柱状图柱子上时的高亮效果)
 
-服务端渲染无法支持的功能包括:
+但仅使用服务端渲染无法支持的功能包括:
 
 - 动态改变数据
-- 高亮鼠标所在的数据项
 - 点击图例切换系列是否显示
 - 移动鼠标显示提示框
 - 其他交互相关的功能
@@ -186,3 +200,84 @@ echarts.setPlatformAPI({
    ></iframe>
 
 我们可以看到,从用户体验的角度,几乎感受不到二次渲染的过程,整个切换效果是非常无缝衔接的。你也可以像上面的例子中一样,在加载 `echarts.js` 
的过程中使用 [pace-js](https://www.npmjs.com/package/pace-js) 之类的库实现显示加载进度条的效果,来解决 
ECharts 尚未完全加载完之前没有交互反馈的问题。
+
+使用服务端渲染 SVG 加上客户端 ECharts 懒加载的方式,其优点是,能够在首屏快速展示图表,而懒加载完成后可以实现所有 ECharts 
的功能和交互;而缺点是,懒加载完整的 ECharts 
需要一定时间,在加载完成前无法实现除高亮之外的用户交互(在这种情况下,开发者可以通过显示“加载中”来解决无交互反馈带来的困惑)。这个方案也是目前比较推荐的对首屏加载时间敏感,对功能交互完整性要求高的方案。
+
+### 方案二:首屏服务端渲染与客户端轻量运行时
+
+方案一给出了实现完整交互的方案,但是有些场景下,我们并不需要很复杂的交互,只是希望在服务端渲染的基础上,能够在客户端进行一些简单的交互,例如:点击图例切换系列是否显示。这种情况下,我们能否不在客户端加载至少需要几百
 KB 的 ECharts 代码呢?
+
+从 v5.5.0 版本起,如果图表只需要以下效果和交互,可以通过服务端 SVG 渲染 + 客户端轻量运行时来实现:
+
+- 图表初始动画(实现原理:服务端渲染的 SVG 带有 CSS 动画)
+- 高亮样式(实现原理:服务端渲染的 SVG 带有 CSS 动画)
+- 动态改变数据(实现原理:轻量运行时请求服务器进行二次渲染)
+- 点击图例切换系列是否显示(实现原理:轻量运行时请求服务器进行二次渲染)
+
+```html
+<div id="chart-container" style="width:800px;height:600px"></div>
+
+<script 
src="https://cdn.jsdelivr.net/npm/echarts/ssr/client/dist/index.js";></script>
+<script>
+const ssrClient = window['echarts-ssr-client'];
+
+let isSeriesShown = {
+  a: true,
+  b: true
+};
+
+function updateChart(svgStr) {
+  const container = document.getElementById('chart-container');
+  container.innerHTML = svgStr;
+
+  // 使用轻量运行时赋予图表交互能力
+  ssrClient.hydrate(main, {
+    on: {
+      click: (params) => {
+        if (params.ssrType === 'legend') {
+          // 点击图例元素,请求服务器进行二次渲染
+          isSeriesShown[params.seriesName] = !isSeriesShown[params.seriesName];
+          $.get('...?series=' + JSON.stringify(isSeriesShown)).then(svgStr => {
+            updateChart(svgStr);
+          });
+        }
+      }
+    }
+  });
+}
+
+// 通过 AJAX 请求获取服务端渲染的 SVG 字符串
+$.get('...').then(svgStr => {
+  updateChart(svgStr);
+});
+</script>
+```
+
+服务器端根据客户端传来的每个系列是否显示的信息(`isSeriesShown`)进行二次渲染,返回新的 SVG 
字符串。服务端代码[同上文](#服务端-svg-渲染),不再赘述。
+
+> 关于状态记录:上述这种开发方式和纯客户端渲染的相比,开发者需要记录并维护一些额外的信息(例如这个例子中每个系列是否显示)。这是不可避免的,因为 HTTP 
请求本身是无状态的,如果要实现有状态,要么像上面的例子这样由客户端记录状态并传递,要么服务器保留状态(例如通过 
session,但需要耗费更多的服务器内存以及更复杂的销毁逻辑所以并不推荐)。
+
+使用服务端 SVG 渲染加上客户端轻量运行时的方式,其优点是,客户端不再需要加载几百 KB 的 ECharts 代码,只需要加载一个不到 4KB 
的轻量运行时代码;并且从用户体验的角度牺牲很少(支持初始动画、鼠标高亮)。而缺点是,需要一定的开发成本来维护额外的状态信息,并且无法支持实时性要求高的交互(例如移动鼠标显示提示框)。总体来说,**推荐在对代码体积有非常严格要求的环境使用**。
+
+## 根据场景决定渲染方案
+
+上面,我们介绍了几种不同的渲染方案,包括:
+
+- 客户端渲染
+- 服务端 SVG 渲染
+- 服务端 Canvas 渲染
+- 客户端轻量运行时渲染
+
+这四种渲染方式可以结合使用,我们再来总结一下它们各自适用的场景:
+
+| 渲染方案 | 加载体积 | 功能及交互损失 | 相对开发工作量 | 推荐场景 |
+| --- | --- | --- | --- | --- |
+| 客户端渲染 | ~1000KB | 无 | 最小 | 首屏加载时间不敏感,对功能交互完整性要求高 |
+| 客户端渲染([按需引用](basics/import#按需引入-echarts-图表和组件)部分包) | >400KB | 
大:没有引入的包就无法使用对应功能 | 小 | 首屏加载时间不敏感,对代码体积没有严格要求但是希望尽可能小,仅使用 ECharts 
的一小部分功能,没有服务器资源 |
+| 一次性服务端 SVG 渲染 | ~20KB | 大:无法动态改变数据、不支持图例切换系列是否显示、不支持提示框等实时性要求高的交互 | 中 | 
首屏加载时间敏感,对功能交互完整性要求低 |
+| 一次性服务端 Canvas 渲染 | ~200KB | 最大:同上且不支持初始动画、图片体积更大、放大会模糊 | 中 | 
首屏加载时间敏感,对功能交互完整性要求低,平台限制无法使用 SVG |
+| 服务端 SVG 渲染加客户端懒加载 ECharts | ~20KB + 1000KB | 中:懒加载完成前无法交互 | 中 | 
首屏加载时间敏感,对功能交互完整性要求高,最好图表不会在加载后立刻需要交互 |
+| 服务端 SVG 渲染加客户端轻量运行时 | ~20KB + 4KB,每次更新请求额外 ~20KB | 中:无法实现实时性要求高的交互 | 
大(需要维护图表状态、定义客户端服务端接口协议) | 首屏加载时间敏感,对功能交互完整性要求低,对代码体积有非常严格要求,交互实时性要求不严格 |
+| 服务端 SVG 渲染加客户端懒加载 ECharts,懒加载完成前使用轻量运行时 | ~20KB + 4KB + 1000KB | 
小:在懒加载完成前无法进行复杂交互 | 最大 | 首屏加载时间敏感,对功能交互完整性要求高,有充分的开发时间 |
+
+当然,还存在一些其他的组合可能性,但最常用的就是以上几种,相信如果你了解了这些渲染方案的特点,就可以根据自己的场景选择合适的方案了。
diff --git a/contents/zh/how-to/interaction/drag.md 
b/contents/zh/how-to/interaction/drag.md
index 8b32dc4..2b3e2f6 100644
--- a/contents/zh/how-to/interaction/drag.md
+++ b/contents/zh/how-to/interaction/drag.md
@@ -84,7 +84,7 @@ myChart.setOption({
 });
 ```
 
-上面的代码中,使用 [convertToPixel](api.html#echartsInstance.convertToPixel) 这个 
API,进行了从 data 
到“像素坐标”的转换,从而得到了每个圆点应该在的位置,从而能绘制这些圆点。`myChart.convertToPixel('grid', dataItem)` 
这句话中,第一个参数 `'grid'` 表示 `dataItem` 在 [grid](${optionPath}grid) 
这个组件中(即直角坐标系)中进行转换。所谓“像素坐标”,就是以 echarts 容器 dom element 的左上角为零点的以像素为单位的坐标系中的坐标。
+上面的代码中,使用 
[convertToPixel](${mainSitePath}api.html#echartsInstance.convertToPixel) 这个 
API,进行了从 data 
到“像素坐标”的转换,从而得到了每个圆点应该在的位置,从而能绘制这些圆点。`myChart.convertToPixel('grid', dataItem)` 
这句话中,第一个参数 `'grid'` 表示 `dataItem` 在 [grid](${optionPath}grid) 
这个组件中(即直角坐标系)中进行转换。所谓“像素坐标”,就是以 echarts 容器 dom element 的左上角为零点的以像素为单位的坐标系中的坐标。
 
 注意这件事需要在第一次 setOption 后再进行,也就是说,须在坐标系([grid](${optionPath}grid))初始化后才能调用 
`myChart.convertToPixel('grid', dataItem)`。
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@echarts.apache.org
For additional commands, e-mail: commits-h...@echarts.apache.org


Reply via email to