HTML标签之meta、link、title以及script的使用补充

792 阅读8分钟

对于HTML的某些标签我们可能熟悉可能陌生,这取决于我们平时工作开发中遇到的需求。但我们的实际开发工作中关注的往往是页面渲染效果以及交互逻辑,如表单、菜单栏、列表等这些常常待在body里面的标签。而一些待在head标签内的如metalink以及title等虽然对用户不可见,但在某些场景下合理使用它们的一些特性或属性往往能达到事半功倍的效果,比如交互实现、性能优化、搜索优化。

本文便在这些特定场景下分析这些标签所能达到的某些效果。

交互实现

在实现一个功能的时候,代码越多开发成本就越高代码可读性健壮性也会变差,所以开发中我们应该秉承编码简约的原则。

meat标签实现自动刷新/跳转

假设要实现一个类似PPT自动播放的效果,你很可能会想到使用JavaScript定时器控制页面跳转来实现。但其实有更加简洁的实现方法,比如通过meta标签来实现:

<meta http-equiv="Refresh" content="5; URL=page2.html">

上面的代码会在 5s 之后自动跳转到同域下的page2.html页面。我们要实现PPT自动播放的功能,只需要在每个页面的 meta标签内设置好下一个页面的地址即可。

另一种场景,比如每隔一分钟就需要刷新页面的大屏幕监控,也可以通过meta标签来实现,只需去掉后面的URL即可:

<meta http-equiv="Refresh" content="60">

在使用它的时候,刷新和跳转操作是不可取消的,所以对刷新时间间隔或者需要手动取消的,还是推荐使用JavaScript 定时器来实现。但是,如果只是想实现页面的定时刷新或跳转(比如某些页面缺乏访问权限,在x秒后跳回首页这样的场景)建议可以实践下meta 标签的用法。

title标签与Hack手段:消息提醒

作为前端工程师的你对 B/S 架构肯定不陌生,它有很多的优点,比如版本更新方便、跨平台、跨终端,但在处理某些场景,比如即时通信场景时,就会变得比较麻烦。

因为前后端通信深度依赖 HTTP协议,而HTTP协议采用请求-响应模式,这就决定了服务端也只能被动地发送数据。一种低效的解决方案是客户端通过轮询机制获取最新消息(HTML5 下可使用 WebSocket 协议) 。

消息提醒功能实现则比较困难,HTML5标准发布之前,浏览器没有开放图标闪烁、弹出系统消息之类的接口,只能借助一些 Hack 的手段,比如修改title标签来达到类似的效果(HTML5下可使用Web NotificationsAPI弹出系统消息)。

下面这段代码中,通过定时修改title标签内容,模拟了类似消息提醒的闪烁效果:

let msgNum = 1 // 消息条数
let cnt = 0 // 计数器
const inerval = setInterval(() => {
  cnt = (cnt + 1) % 2
  if(msgNum===0) {
    // 通过DOM修改title
    document.title += `聊天页面`
    clearInterval(interval)
    return
  }
  const prefix = cnt % 2 ? `新消息(${msgNum})` : ''
  document.title = `${prefix}聊天页面`
}, 1000)

实现效果如下图所示,可以看到标签名称上有提示文字在闪烁。

通过模拟消息闪烁,可以让用户在浏览其他页面的时候,及时得知服务端返回的消息。

定时修改 title 标签内容,除了用来实现闪烁效果之外,还可以制作其他动画效果,比如文字滚动,但需要注意浏览器会对 title标签文本进行去空格操作。

动态修改 title标签的用途不仅在于消息提醒,还可以将一些关键信息显示到标签上(比如下载时的进度、当前操作步骤),从而提升用户体验。

性能优化

性能优化是前端开发中避不开的问题,性能问题无外乎两方面原因:渲染速度慢、请求时间长。性能优化虽然涉及很多复杂的原因和解决方案,但其实只要通过合理地使用标签,就可以在一定程度上提升渲染速度以及减少请求时间。

script 标签:调整加载顺序提升渲染速度

由于浏览器的底层运行机制,渲染引擎在解析HTML时,若遇到script标签引用文件,则会暂停解析过程,同时通知网络线程加载文件,文件加载后会切换至JavaScript引擎来执行对应代码,代码执行完成之后切换至渲染引擎继续渲染页面。

在这一过程中可以看到,页面渲染过程中包含了请求文件以及执行文件的时间,但页面的首次渲染可能并不依赖这些文件,这些请求和执行文件的动作反而延长了用户看到页面的时间,从而降低了用户体验。

为了减少这些时间损耗,可以借助 script标签的 3 个属性来实现。

  • async 属性。立即请求文件,但不阻塞渲染引擎,而是文件加载完毕后阻塞渲染引擎并立即执行文件内容。
  • defer 属性。立即请求文件,但不阻塞渲染引擎,等到解析完 HTML 之后再执行文件内容。
  • HTML5 标准 type 属性,对应值为“module”。让浏览器按照ECMA Script6标准将文件当作模块进行解析,默认阻塞效果同defer,也可以配合async在请求完成后立即执行。

以上 3 种属性都能减少请求文件引起的阻塞时间,只有defer属性以及type="module"情况下能保证渲染引擎的优先执行,从而减少执行文件内容消耗的时间,让用户更快地看见页面(即使这些页面内容可能并没有完全地显示)。

除此之外还应当注意,当渲染引擎解析HTML遇到script标签引入文件时,会立即进行一次渲染。所以这也就是为什么构建工具会把编译好的引用 JavaScript 代码的 script标签放入到body标签底部,因为当渲染引擎执行到body底部时会先将已解析的内容渲染出来,然后再去请求相应JavaScript文件。如果是内联脚本(即不通过 src 属性引用外部脚本文件直接在HTML编写JavaScript代码的形式),渲染引擎则不会渲染。

link 标签:通过预处理提升渲染速度

在我们对大型单页应用进行性能优化时,也许会用到按需懒加载的方式,来加载对应的模块,但如果能合理利用link标签的rel属性值来进行预加载,就能进一步提升渲染速度。

  • dns-prefetch。当link标签的rel属性值为dns-prefetch时,浏览器会对某个域名预先进行 DNS 解析并缓存。这样,当浏览器在请求同域名资源的时候,能省去从域名查询 IP 的过程,从而减少时间损耗。
  • preconnect。让浏览器在一个HTTP请求正式发给服务器前预先执行一些操作,这包括 DNS 解析、TLS 协商、TCP 握手,通过消除往返延迟来为用户节省时间。
  • prefetch/preload。两个值都是让浏览器预先下载并缓存某个资源,但不同的是,prefetch 可能会在浏览器忙时被忽略,而 preload则是一定会被预先下载。
  • prerender。浏览器不仅会加载资源,还会解析执行页面,进行预渲染。

搜索优化

我们写的前端代码,除了要让浏览器更好执行,有时候也要考虑更方便其他程序(如搜索引擎)理解。合理地使用meta标签link标签,恰好能让搜索引擎更好地理解和收录我们的页面。

meta 标签:提取关键信息

  • 通过 meta标签可以设置页面的描述信息,从而让搜索引擎更好地展示搜索结果。
  • 为了让搜索引擎更好地识别页面,除了描述信息之外还可以使用关键字,这样即使页面其他地方没有包含搜索内容,也可以被搜索到(当然搜索引擎有自己的权重和算法,如果滥用关键字是会被降权的,比如Google引擎就会对堆砌大量相同关键词的网页进行惩罚,降低它被搜索到的权重)。

在实际工作中,推荐使用一些关键字工具来挑选,比如 Google Trends、站长工具。

link 标签:减少重复

有时候为了用户访问方便或者出于历史原因,对于同一个页面会有多个网址,又或者存在某些重定向页面,比如:

https://xx.com/a.html
https://xx.com/detail?id="abcd"

那么在这些页面中可以这样设置:

<link href="https://xx.com/a.html" rel="canonical">

这样可以让搜索引擎避免花费时间抓取重复网页。不过需要注意的是,它还有个限制条件,那就是指向的网站不允许跨域。

当然,要合并网址还有其他的方式,比如使用站点地图,或者在 HTTP 请求响应头部添加 rel="canonical"。

总结:

本文从交互实现、性能优化、搜索优化场景出发,分别讲解了meta 标签title 标签link 标签,以及script标签在这些场景中的重要作用,希望这些内容你都能有效地应用到工作场景中,不再只是了解,而是能够熟练运用。

原文出自你真的熟悉 HTML 标签吗?