元信息和资源✅
说一下 HTMl 下有哪些元素
答案
-
根元素
<html>
: 文档的根元素<body>
: 文档主体
-
文档元数据
<head>
: 文档头部区域<title>
: 文档标题<base>
: 文档中相对 URL 的基准 URL<link>
: 外部资源链接<meta>
: 元数据<style>
: 样式信息
-
内容元素
<header>
: 页眉<nav>
: 导航<main>
: 主要内容<article>
: 文章<section>
: 区块<aside>
: 侧边栏<footer>
: 页脚<h1>
-<h6>
: 标题<address>
: 联系信息
-
文本内容
<div>
: 通用容器<p>
: 段落<hr>
: 水平分割线<pre>
: 预格式化文本<blockquote>
: 块引用<ol>
: 有序列表<ul>
: 无序列表<li>
: 列表项<dl>
: 定义列表<dt>
: 定义术语<dd>
: 定义描述<figure>
: 图文组合<figcaption>
: 图文说明
-
内联文本语义
<a>
: 超链接<em>
: 强调<strong>
: 重要<small>
: 小号字体<s>
: 删除线<cite>
: 引用<q>
: 行内引用<dfn>
: 定义<abbr>
: 缩写<data>
: 机器可读数据<time>
: 时间<code>
: 代码<var>
: 变量<samp>
: 程序输出<kbd>
: 键盘输入<sub>
: 下标<sup>
: 上标<i>
: 斜体<b>
: 粗体<u>
: 下划线<mark>
: 标记<ruby>
: 注音<rt>
: 注音文本<rp>
: 注音括号<bdi>
: 双向文本隔离<bdo>
: 文本方向<span>
: 通用行内容器<br>
: 换行<wbr>
: 可选换行
-
图片和多媒体
<img>
: 图片<audio>
: 音频<video>
: 视频<source>
: 媒体源<track>
: 媒体轨道<map>
: 图像映射<area>
: 图像映射区域<picture>
: 图片容器
-
内嵌内容
<iframe>
: 内联框架<embed>
: 嵌入外部内容<object>
: 嵌入对象<param>
: 对象参数<portal>
: 门户元素
-
脚本
<script>
: 脚本<noscript>
: 不支持脚本时的替代内容<canvas>
: 画布<dialog>
: 对话框
- 表格内容
<table>
: 表格<caption>
: 表格标题<colgroup>
: 表格列组<col>
: 表格列<thead>
: 表头<tbody>
: 表格主体<tfoot>
: 表格页脚<tr>
: 表格行<td>
: 单元格<th>
: 表头单元格
-
表单
<form>
: 表单<label>
: 标签<input>
: 输入框<button>
: 按钮<select>
: 下拉选择<datalist>
: 数据列表<optgroup>
: 选项组<option>
: 选项<textarea>
: 多行文本框<output>
: 输出<progress>
: 进度条<meter>
: 度量衡<fieldset>
: 表单分组<legend>
: 分组标题
-
交互元素
<details>
: 详细信息<summary>
: 详细信息标题<dialog>
: 对话框
- Web 组件
<slot>
: 插槽<template>
: 模板
延伸阅读
HTML5 中 meta 标签作用是啥
答案
HTML5 中的 meta
标签用于提供关于 HTML 文档的元数据(metadata),不会直接在页面上显示,但对浏览器、搜索引擎和其他服务非常重要。常见作用包括:
作用 | 示例 | 说明 |
---|---|---|
字符编码声明 | <meta charset="UTF-8"> | 指定页面字符集,防止乱码 |
视口设置 | <meta name="viewport" content="width=device-width, initial-scale=1.0"> | 移动端响应式布局基础 |
SEO信息 | <meta name="description" content="页面描述">``<meta name="keywords" content="关键词1,关键词2">``<meta name="author" content="作者名"> | 搜索引擎优化相关信息 |
缓存控制 | <meta http-equiv="cache-control" content="no-cache">``<meta http-equiv="expires" content="0">``<meta http-equiv="pragma" content="no-cache"> | 控制浏览器缓存策略 |
安全策略 | <meta http-equiv="Content-Security-Policy" content="default-src 'self'"> | 防止XSS等攻击,增强安全性 |
刷新/重定向 | <meta http-equiv="refresh" content="5;url=https://example.com"> | 页面自动刷新或跳转 |
注意事项:
meta
标签应放在<head>
内。- 字符集声明应尽量靠前,避免乱码。
- 滥用关键词和描述不会提升 SEO,需合理设置。
- 安全相关的
meta
(如 CSP)需谨慎配置,避免误伤正常功能。
参考:
header 的作用 和 head 的区别
答案
对比项 | <header> | <head> |
---|---|---|
语义 | 页面头部内容,通常包含导航、logo、标题等 | 文档元数据,包含样式、脚本、meta等信息 |
位置 | <body> 内,多处可用 | <html> 内,仅有一个 |
内容 | 导航、logo、标题等 | 只含元数据,不显示 |
子元素 | <h1> -<h6> 、<nav> 等 | <title> 、<meta> 等 |
可见性 | 是 | 否 |
为什么通常推荐将 CSS <link>
放置在 <head></head>
之间,而将 JS <script>
放置在 </body>
之前?你知道有哪些例外吗?
答案
CSS <link>
放在 <head>
,JS <script>
放在 </body>
前,主要是为了优化页面渲染速度和用户体验,避免阻塞渲染。
-
CSS 是渲染页面内容所必需的,浏览器在解析 HTML 时遇到
<link>
会立即加载并阻塞渲染,确保页面样式在内容显示前就绪,防止“无样式内容闪烁”(FOUC)。 -
JS
<script>
默认会阻塞 HTML 解析,若放在<head>
,会延迟页面内容渲染,影响首屏速度。放在</body>
前,能让 HTML 和 CSS 先加载、渲染,提升用户体验。 -
例外情况:
- 需要在页面渲染前执行的 JS(如 polyfill、关键监控脚本)可放在
<head>
,但应加defer
或async
属性减少阻塞。 - 某些 CSS(如
@import
动态样式)或 JS(如模块化、ESM)有特殊加载需求。 - SPA 框架常用
defer
、async
或模块化<script type="module">
,可安全放在<head>
。
- 需要在页面渲染前执行的 JS(如 polyfill、关键监控脚本)可放在
<!-- 推荐写法 -->
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- ... -->
<script src="main.js"></script>
</body>
<!-- 例外:关键 JS,使用 defer -->
<head>
<script src="polyfill.js" defer></script>
</head>
延伸阅读
-
MDN:
<link>
标签 - 详细介绍 link 的用法 -
MDN:
<script>
标签 - script 加载策略详解 -
Google Web Fundamentals: 优化渲染路径 - 渲染优化原理
-
HTML5 Rocks: Script Loading - script 加载模式对比
实际开发中,推荐为 JS 脚本加上 defer
或 async
,既可放在 <head>
,又不会阻塞页面渲染。
link 标签有哪些属性,作用是什么?
答案
HTML <link>
标签用于在文档与外部资源之间建立关系,常用于引入样式表、图标等。其常用属性及作用如下表:
属性 | 作用说明 | 示例值/说明 |
---|---|---|
rel | 指定当前文档与外部资源的关系 | stylesheet、icon |
href | 外部资源的 URL | /style.css |
type | 指定资源的 MIME 类型 | text/css、image/png |
media | 指定资源适用的媒体类型或查询条件 | screen、print、(max-width:600px) |
sizes | 指定图标资源的尺寸(仅 rel=icon 时有效) | 16x16、32x32 |
crossorigin | 设置跨域请求策略(如加载字体、图标等) | anonymous、use-credentials |
as | 资源类型(仅预加载/预获取时使用) | script、style |
title | 资源的标题(部分场景下可用于切换样式表) | 暗色模式 |
integrity | 子资源完整性校验,防止资源被篡改 | sha384-xxx |
disabled | 禁用样式表(仅切换样式表时用) | true/false |
<!-- 引入样式表 -->
<link rel="stylesheet" href="/main.css" media="all">
<!-- 引入网站图标 -->
<link rel="icon" href="/favicon.ico" sizes="32x32" type="image/x-icon">
<!-- 预加载字体资源 -->
<link rel="preload" href="/font.woff2" as="font" type="font/woff2" crossorigin="anonymous">
常用场景:rel="stylesheet"
用于引入 CSS,rel="icon"
设置网页图标,rel="preload"
优化资源加载。
延伸阅读
- MDN:
<link>
- HTML — 官方文档,详细属性说明 - HTML Living Standard: link — HTML 标准原文
- 深入理解 rel="preload" — 资源预加载优化实践
请解释 <script>、<script async> 和 <script defer>
的区别
答案
defer
和 async
是用于控制脚本加载和执行的 HTML <script>
标签属性。
defer
和 async
的主要区别在于它们对脚本的加载和执行的影响。
-
defer
属性告诉浏览器立即下载脚本,但延迟执行,等到文档加载完成后再按照它们在页面中出现的顺序依次执行。这意味着脚本不会阻止文档的解析和渲染,并且它们也不会阻止其他脚本的执行。如果多个脚本都使用defer
属性,则它们将按照它们在页面中出现的顺序依次执行。 -
async
属性告诉浏览器立即下载脚本,但它们不一定按照它们在页面中出现的顺序执行。它们将在下载完成后立即执行。这意味着脚本不会阻止文档的解析和渲染,但可能会阻止其他脚本的执行。如果多个脚本都使用async
属性,则它们将按照它们下载完成的顺序依次执行。
需要注意的是,当使用 defer
和 async
属性时,浏览器的支持情况可能不同。一些较旧的浏览器可能不支持这些属性,或者仅支持 defer
而不支持 async
。因此,为了确保脚本的兼容性,建议在使用 defer
和 async
属性时,同时提供一个备用脚本,并考虑使用特性检测来检查浏览器是否支持这些属性。
在浏览器中,可以通过预加载 JavaScript 脚本来提高性能和用户体验。预加载是指在浏览器解析完当前页面之前,提前加载并解析相关资源(例如 JavaScript 文件、CSS 文件等)。这样可以在用户请求访问其他页面时,减少资源加载的时间和延迟,从而提高页面加载速度和用户体验。
以下是两种预加载 JavaScript 脚本的方法:
- defer 属性
<script>
标签的 defer
属性可以告诉浏览器,让 JavaScript 文件在页面文档解析完成之后再执行。这种方式可以保证页面不会因为脚本加载和执行而被阻塞,同时又能够保证脚本能够按照正确的顺序执行(即按照在 HTML 中出现的顺序,因为 defer
属性会按照这个顺序依次加载和执行)。
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
<script src="script1.js" defer></script>
<script src="script2.js" defer></script>
</head>
<body>
...
</body>
</html>
- prefetch 和 preload
预加载的另一种方法是使用 Link
标签的 prefetch
或 preload
属性。这种方法可以在不影响当前页面加载的情况下,预先加载需要后续页面需要的 JavaScript 文件和其他资源。
其中,prefetch
属性指示浏览器预先加载并缓存 JavaScript 文件,但不会立即执行文件。而 preload
属性则会在浏览器空闲时立即加载文件,并且可以指定文件的类型、优先级等属性。
<head>
<title>My Page</title>
<link rel="prefetch" href="script1.js" />
<link rel="preload" href="script2.js" as="script" />
</head>
需要注意的是,使用 prefetch
和 preload
属性时,应该避免将其用于太多的资源文件,否则可能会引发网络瓶颈和性能问题。可以在需要优化的资源文件上使用这些属性,并通过测试和性能分析来调整其预加载的优先级和时机,以达到最优化的预加载效果。
async:
- 异步加载
- 加载完立即执行
- 不保证执行顺序
defer:
- 异步加载
- DOM 解析完成后执行
- 按照顺序执行
在HTML中,<script>
标签用于引入或嵌入JavaScript代码。<script>
标签可以使用以下属性来调整脚本的行为:
常用属性
-
src
:指定要引入的外部JavaScript文件的URL。例如:<script src="script.js"></script>
。通过这个属性,浏览器会下载并执行指定的外部脚本文件。 -
async
:可选属性,用于指示浏览器异步加载脚本。这意味着脚本会在下载的同时继续解析HTML文档,不会阻塞其他资源的加载。例如:<script src="script.js" async></script>
。 -
defer
:可选属性,用于指示浏览器延迟执行脚本,直到文档解析完成。这样可以确保脚本在文档完全呈现之前不会执行。例如:<script src="script.js" defer></script>
。 -
type
:指定脚本语言的MIME类型。通常是text/JavaScript
或者module
(用于ES6模块)。如果未指定该属性,浏览器默认将其视为JavaScript类型。例如:<script type="text/JavaScript">...</script>
。 -
charset
:指定外部脚本文件的字符编码。例如:<script src="script.js" charset="UTF-8"></script>
。 -
integrity
:用于指定外部脚本文件的Subresource Integrity(SRI)。SRI可以确保浏览器在加载脚本时验证其完整性,防止通过恶意更改文件来执行潜在的攻击。例如:<script src="script.js" integrity="sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng="></script>
。
不常用属性
-
crossorigin
:正常的 script 元素将最小的信息传递给 window.onerror,用于那些没有通过标准 CORS 检查的脚本。要允许对静态媒体使用独立域名的网站进行错误记录,请使用此属性。参见 CORS 设置属性。 -
fetchpriority
:提供一个指示,说明在获取外部脚本时要使用的相对优先级。 -
nomodule
: 这个布尔属性被设置来标明这个脚本不应该在支持 ES 模块的浏览器中执行。实际上,这可用于在不支持模块化 JavaScript 的旧浏览器中提供回退脚本。 -
nonce
: 在script-src Content-Security-Policy (en-US)
中允许脚本的一个一次性加密随机数(nonce)。服务器每次传输策略时都必须生成一个唯一的 nonce 值。提供一个无法猜测的 nonce 是至关重要。 -
referrerpolicy
: 表示在获取脚本或脚本获取资源时,要发送哪个 referrer。
可以参考文档:资料
script 标签设置 type=module
和普通脚本有什么区别?
// ...existing code...
script 标签设置 type=module
和普通脚本有什么区别?
答案
维度 | type=module | 普通脚本 |
---|---|---|
语义与作用域 | 模块作用域;默认严格模式;顶层 this 为 undefined | var 变量挂到 window、非严格模式 |
加载与执行 | 默认 defer:不阻塞解析、按出现顺序、DOM 解析后执行;支持顶层 await | 默认阻塞解析;或用 async/defer 调整,所以当使用 nomodule 做回退兼容时,建议配合 defer 配置 |
依赖 | 支持 import/export 与 import(),静态可分析 | 不支持模块语法, 支持动态 import |
跨域获取 | 以 CORS 模式抓取,需服务端允许,不支持本地文件模式 | no-cors 可执行,常见静态可直接引入 |
缓存/幂等 | 同一模块在依赖图中仅执行一次(按 URL 缓存) | 每次被插入都会执行一次 |
解析顺序 | 后序遍历模块依赖树 | 前序遍历脚本标签顺序 |
文件后缀 | .mjs(模块)与 .js(普通),建议携带 .mjs 以兼容 node | .js(普通) |
性能 | import/export 静态分析成本昂贵,建议生产配合打包器使用 | 不存 module 语法解析相关开销 |
示例说明
<!-- 现代:模块脚本,默认 defer -->
<script type="module">
import { sum } from './esm.js'
console.log('isModule', this === undefined) // true
console.log(sum(1,2))
</script>
<!-- 旧浏览器回退 -->
<script nomodule src="./legacy.js"></script>
<!-- 如需尽快执行而不等待 DOM,可加 async(顺序不保证) -->
<script type="module" async src="./boot.mjs"></script>
延伸阅读
- JavaScript modules V8 对 ESM 说明
script 标签设置 type="importmap"
是什么,用来解决什么问题?
答案
import map
让浏览器原生 ESM 支持“裸模块名”解析与别名映射,把模块标识(如 ``react、@/utils`)映射到实际 URL,控制依赖定位与版本。无需打包器也可使用第三方依赖;稳定依赖版本与路径;按作用域覆写依赖,便于多版本共存与环境切换(dev/CDN)。
<!-- 需在第一个模块脚本之前声明 -->
<script type="importmap">
{
"imports": {
"lodash": "https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.js",
"@/": "/assets/js/"
},
"scopes": {
"/features/": {
"lodash": "https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.min.js"
}
}
}
</script>
<script type="module">
import _ from 'lodash'
import { sum } from '@/math/sum.js'
console.log(_.chunk([1,2,3,4], 2), sum(1,2))
</script>
常见误区
- 仅影响模块解析,不会打包或转译代码;仍需考虑浏览器特性与 CORS。
- 应在首个
<script type="module">
之前声明,否则已解析的模块不会受影响。 - 兼容性需关注浏览器版本;Firefox 支持情况以最新文档为准。可用打包器或 import-map-shim 作为降级方案。
推荐“本地开发用 import map + 生产打包/按需加载”组合:开发期不打包提升迭代效率,生产期通过打包与 SRI 提升性能与安全。
延伸阅读
- import map 规范说明
- MDN: Import maps 浏览器支持与语法
- WICG/import-maps 规范与设计讨论
- SystemJS import-map shim 旧浏览器降级方案