元信息和资源✅
说一下 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 旧浏览器降级方案