动态 HTML 不是一个标准,是「HTML 加 CSS 加 JavaScript」三样合起来的说法:不重新请求整页, 就能改内容、改样式、响应操作。
上一节讲结构和表现,这一节讲行为。它没有 RFC、没有版本号,只是浏览器里三样技术配合出来的效果。
一、「动」有三种
第一种是样式动:鼠标移上去按钮变色。这是 CSS 的 :hover 干的,一行脚本都不用写。
第二种是内容动:点一下展开一段说明、弹出一个对话框。这要脚本去改那棵 DOM 树(10.2.2)。
第三种是数据动:下拉刷新、翻页不跳转、聊天消息往上冒。这要脚本去要数据,再把结果填进页面。
三种的技术含量依次递增,但共同点是同一个:页面没有重新加载。
这一点才是「动态」的本意——不是有动画,是不用整页重来。
二、服务端渲染与客户端渲染的账
同一批数据有两种给法。一种是把 HTML 全拼好发过去(服务端渲染),浏览器收到就能画。
另一种是先发一个空骨架,脚本再去要一段 JSON 自己拼(客户端渲染)。
Demo 用 20 条数据量了一遍:服务端渲染 1756 字节、1 个请求;
客户端渲染 骨架 147 加数据 521 等于 668 字节、2 个请求。
结果和直觉相反——这个例子里客户端渲染反而小了 62%。
原因是每行数据的标签比数据本身重:<li class="item"> 加两个 <span>,
几十个字节就为装十几个字的正文。
但真实项目里结论常常翻过来,因为客户端渲染还得先下载一个几百 KB 的框架脚本才能画出界面。
本 Demo 没引框架,那一块不在数字里,我不编它的大小。
客户端渲染确定的代价是多一次请求:首屏要等两趟。
它换来的是后面——翻页、筛选只传变化的数据,不用重传整页标签。
三、它为什么不算一个标准
「动态 HTML」这个词九十年代末很流行,但它从来没有对应的 RFC 或 W3C 规范。 它是厂商造出来的营销词,指的就是那三样东西一起用。 所以教材把它放在「HTML」这一章里讲,而不是单独开一章——因为它不是一个协议,是一种用法。 这一点值得记一下:技术名词里有不少是这类「约定俗成的叫法」,Ajax、Web 2.0、单页应用都是。 名字好记,但没有规范可查。
四、动手 Demo:同一批数据,两种给法,量字节和请求数
把 20 条同样的数据做成两份东西:一份是拼好的整页 HTML,一份是空骨架加一段 JSON。 量各自的字节数,数各自的请求次数。
ROWS = u''.join(u'<li class="item"><span class="t">课程 %02d</span>'
u'<span class="p">¥%d</span></li>' % (i, 99 + i)
for i in range(1, 21))
SSR = u'<!DOCTYPE html>...<ul id="list">' + ROWS + u'</ul>...'
DATA = json.dumps([{'t': ..., 'p': ...}], ensure_ascii=False,
separators=(',', ':'))
实跑输出:
--------------------------------------------------------------------
服务端渲染和客户端渲染:字节与请求数
--------------------------------------------------------------------
20 条数据 每条约 87 字节(含标签)
服务端渲染整页 1756 字节,1 个请求
客户端渲染:骨架 147 字节
客户端渲染:数据 521 字节
客户端渲染合计 668 字节,2 个请求
客户端比服务端 少 1088 字节,62%
这里有个和直觉相反的结论:**这个例子里客户端渲染反而更小**。
原因是每行数据带的标签比数据本身重得多——`<li class="item">` 加两个 `<span>`,几十个字节就为装十几个字的正文。
真实项目里这个结论常常翻过来,因为客户端渲染还得先下载一个几百 KB 的
框架脚本才能画出界面。本 Demo 没引框架,所以那一块不在上面的数字里,
我不编它的大小。
客户端渲染确定的代价是**多一次请求**:2 对 1,首屏要等两趟。它换来的是后面的事——翻页、筛选、排序只传变化的数据,不用重传整页标签。
所以两种做法没有绝对优劣:看「第一次打开」重要,还是「后面频繁操作」重要。
JSON 那一段长这样(前 90 个字节):
服务端渲染 1756 字节,一次请求就把能画的都给了。 客户端渲染 668 字节(骨架 147 加数据 521),但要两次请求。 客户端渲染反而少了 62%,因为标签比数据重得多。这一点和很多人的印象相反,值得记下来。 但真实项目的对比不能只看这个:客户端渲染还要加载框架脚本,几百 KB 起步。 Demo 里没有那块,所以上面的数字不代表真实项目。 两次请求的意义不只是多了个往返:首屏必须等第二趟回来才能画,用户看到的是白屏时间变长, 不是字节变少。
30 秒实验
- 把数据的条数从 20 改成 200,看两种做法的字节差怎么变。
- 把每行的标签减少到一个
<li>,再看差值——标签越少,客户端渲染越不吃亏。 - 打开一个常用网站,用开发者工具看 Network 面板,数它发了多少个请求。
常见误区
- 「动态 HTML 是一个标准」——它没有 RFC,只是三样技术合用的叫法。
- 「客户端渲染一定更省流量」——标签重的时候恰恰相反。
- 「动态就是有动画」——动态的本意是不整页重载。
自测三问(点开对答案)
1. 动态 HTML 指的是哪三样技术? —— HTML、CSS、JavaScript。它本身不是标准。 2. 服务端渲染和客户端渲染最确定的差别是什么? —— 请求次数:前者一次给全,后者要骨架加数据两次。 3. 为什么客户端渲染的总字节可能反而更少? —— 因为标签比数据重,服务端为每条数据重复了整套标签。不管是服务端拼还是客户端拼,拼的都是同一棵 DOM 树。下一节就看这棵树。
- ☐ (本节完,下一节 10.2.2 更易控制HTML的DOM)