Yuan的博客
EN

HTML、CSS、前端工具、前端效能优化

HTML 系列

  1. HTML语意化
  • HTML语意化是指合乎语意的 HTML 标签开发,可以提升 SEO,提升代码的可读性、帮助开发者之间更容易理解网页架构,制作无障碍网页。
  • 浏览器解析 HTML 时,会由上而下依序载入内容。当遇到 标签时,浏览器会暂停 HTML 解析,先下载并执行 JavaScript 档案,然后再继续解析剩余的 HTML 内容。大部分会建议 放置在 底部前,可以画面更快呈现,避免 Script 异动到还未载入的 HTML 元素。但是放尾部也会让网页一开始会没有功能性,最好透过 defer 或 async 一边解析页面,一边下载 JavaScript。

  1. 如何在 HTML 中插入 CSS 样式?优先顺序是什么?
  • 内联样式(Inline Styles):<p style="font-size: 20px; color: red;">这是一段红色的文字。</p>
  • 内部样式(Internal Styles): CSS 放在 HTML 文件的 内的 标签中。
  • 外部样式表(External Stylesheet):将 CSS 放在一个独立的 .css 文件中,然后通过 HTML 文件的 标签进行引用。
<!DOCTYPE html>
<html>
  <head>
    <!-- 透过 link 标签引入样式 -->
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <h1>这是一个标题</h1>
    <p>这是一段文字。</p>
  </body>
</html>
  • 优先顺序:内联样式(Inline Styles) > 内部样式(Internal Styles)= 外部样式表(External Stylesheet)。
  • defer:脚本是需要等 HTML 解析完、DOM 完整建立后才能载入使用defer。或者,可能某个脚本会依赖另一个脚本,例如 A 依赖 B,这时候要确保 A 是在 B 之前执行,这时会选择用 defer。
  • async:async 的脚本载入与 HTML 解析是彼此独立的,因此只要下载完就会马上执行

CSS 系列

  1. 请说明 CSS 选择器的优先级
  • !important > 行内样式 > id > class = 伪类 > 型态选择器 = 伪元素 > 通用
  1. CSS 中有哪些单位? 该如何使用?
  • CSS 的 px 是绝对单位,适合精确布局;em 会随父级或自身字体大小层层叠加,容易在复杂结构里失控;rem 始终相对根元素,避免继承链混乱,是现代 RWD 与设计系统的主流选择,因此实际开发中通常用 px 做局部精确控制,用 rem 做全局一致缩放,尽量避免在复杂层级里滥用 em。
  1. CSS 盒模型 (Box Model)
  • Box 是由内容(content)、内距(padding)、边框(border) 和外距(margin) 所组成。border-box 则把 padding 和 border 都算进 width/height,margin 永远不包含在宽高计算中,它只影响元素与外部的距离,不属于盒子本体。
  1. 伪类 (pseudo-classes) 和伪元素 (pseudo-elements) 是什么?
  • 伪类:伪类可以让我们根据元素的状态变化使用 CSS

    • :hover :link :visited :disabled :enabled :first-child :last-child
  • 伪元素 (pseudo-elements):不需新增 HTML 的情况下新增额外元素。

  • ::before 和 ::after

  • ::marker

  • ::placeholder

  • ::first-letter

  1. 请解释 CSS position 有什么值和作用?
  • static:正常文档流,不需要移动、不需要层叠、不需要脱离布局的元素。在 static 的情况下,设定 top、 bottom、 left 、 right 和 z-index 都是无效的。
  • relative:它让元素成为 absolute 的定位参考点 + 自己可以微调位置。
  • absolute:跳脱原本的排列,针对某个参考点(相对于这个元素最接近、且有定位的父层)进行定位,出现在某个绝对位置。
  • fixed: fixed 的参考点会是以浏览器视窗本身,
  • sticky:元素在页面滚动到特定点时,才会固定在特定的位置,但如果页面回滚到元素的原始位置,元素就会恢复到相对定位。
  1. CSS 水平垂直置中的方法 (flex, grid)
  • 布局的种类:block:垂直排列,一行只能放一个,宽度默认 100% /inline:水平排列,但不能设置宽高 /inline-block:水平排列,可以设宽高,
  • Flex + align-items + justify-content:父容器用 flex,一横一纵两个轴,最通用、最好记。
  • Flex + margin:auto:子元素 margin:auto 会吃掉剩余空间,从而推到正中间。
  • margin-left/right:auto + max-width:fit-content:用 inline 逻辑的 margin 压力实现水平置中,不依赖 flex。
  • Grid + place-content:center:grid 容器能直接把内容朝两个方向集中。
  • absolute + transform:top:50% + left:50% 把“左上角”移到中心,再用 transform 把自己中心对齐回去。
  • fixed + inset:0 + margin:auto:在视窗层级置中,常用于弹窗/横幅。
  • text-align:center + line-height:专门针对于“一行文字”居中的古典方案。
  1. CSS 中 display 的值有什么?有什么差异?
  • display: block 块状元素默认会继承父元素的宽,并且会独占一行; 高度预设则是以元素撑开的高度为主
  • display: inline 行内元素本身并不会独占一行,而是会与其他行内元素并排在同一列。
  • display: inline-block 会像 inline 元素一样的同行排列,但同时拥有 block 元素可以设定宽高的特性。
  • display:none 和 visibility:hidden 的差别 :display:none 会将元素完全从页面中移除,包括占用的空间,而 visibility:hidden 仅会隐藏元素,但元素占用的空间仍会保留,且该元素仍会影响页面布局。
  • StyleX 是什么? 解决了什么问题? 适用在什么场景?StyleX 用编译期原子化 + 确定性优先级解决大型项目的样式冲突、优先级混乱、CSS 膨胀、难以规模化等问题,并在 type-safe 和可维护性上超越传统 CSS 和 Tailwind。

前端工具

  1. 什么是前端模组化:前端模组化的核心是把代码拆成可独立维护、可复用的小模块,并用统一的加载/打包机制把它们组合成可在浏览器顺畅运行的应用。ES Module 成为标准。但浏览器实现不一致、生态依赖 npm 套件,促使 webpack 等打包工具出现,把各种 JS、CSS、图片等资源都转成浏览器能理解的统一模块格式,并提供兼容性、性能优化与更好的开发体验。

  2. webpack 中的 loader 和 plugin 的差别是什么?

  • loader 专注“处理文件”,让 webpack 能读懂各种类型(CSS、TS、Sass)
  • plugin 专注“扩展 webpack 的打包流程”,可以控制生命周期、优化结果、注入变量、自动生成 HTML 等。loader 是一个函数,plugin 是一个带 apply() 的对象。
  1. 为什么 pnpm 比 npm 更快且更省空间
  • pnpm 用「全局内容仓库 + 链接指针 + 本地缓存」换来安装速度和磁盘空间的大幅优化,这就是它比 npm 更快、也更省空间的根本原因。
  1. Vite
  • (build tool) 因为大多数浏览器支持export和import,不需要打包了
  1. 为什么要用 monorepo?
  • Monorepo 让多个项目共享代码更简单,所有更新能一次完成,还能避免版本不一致。
  1. 前端构建工具 (build tool) 是什么? 为什么要用?
  • 构建工具把开发时代码(React/Vue/TS/ESNext 等)处理成浏览器能高效执行的产物,并在开发过程中提供更好的 DX(开发体验)。

前端效能优化

  1. 回流 (Reflow) 和重绘 (Repaint) 是什么?以及如何优化?
  • 回流是浏览器重新计算布局的位置和大小,成本最高;重绘是更新颜色等不影响布局的样式,成本较低。两者都会拖慢渲染,因此核心优化思路是尽量避免触发布局变化,例如:用 transform 移动元素、用 opacity 控制显隐、将频繁变化的元素提升为独立图层(will-change),并减少频繁的 DOM 操作,以提升整体渲染性能。
  1. 什么是防抖 (debounce)? 如何实践防抖 (debounce) 函式?
  • 防抖的核心就是:把一连串快速触发的事件合并成“最后一次执行”,只有当用户【停止操作】超过指定时间,才真正执行函数。典型用途是避免搜索框在用户还没打完字时连续发 10 次 API。
function debounce(fn, delay = 300) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}

// 搜索时只发一次 API
const search = debounce((text) => {
  console.log("Call API:", text);
}, 300);
  1. 什么是节流 (throttle)? 如何实践节流 (throttle) 函式?
  • 在固定时间内只执行一次函数,即便事件被持续触发也不会重复执行;适合滚动、拖拽、窗口缩放这类“需要持续触发,但不能太频繁”的场景。防抖是“停下来才执行”,节流是“按固定节奏执行”。
function throttle(fn, delay = 500) {
  let timer = null;
  return (...args) => {
    if (timer) return;
    timer = setTimeout(() => {
      fn(...args);
      timer = null;
    }, delay);
  };
}

const onScroll = throttle(() => {
  console.log("处理滚动事件");
}, 500);

window.addEventListener("scroll", onScroll);
  1. 什么是关键渲染路径 (critical rendering path)
  • 关键渲染路径=浏览器把「HTML/CSS/JS → 可见可互动页面」的全过程。性能优化的核心就是:让 DOM、CSSOM、JS、Layout、Paint 这些环节更快完成。可控点主要在三个:HTML 尽可能小、DOM 尽可能少;CSS 尽可能快(小、放前面、非关键样式异步加载);JS 尽量减少阻塞 DOM/CSSOM 的操作。例如:如果首页一次渲染 10 万个列表项,浏览器要花几百毫秒才能 Layout+Paint;但如果你只渲染可视区域的 50 个元素(虚拟列表),渲染时间可从 242ms → 2ms 量级。
  1. 如何避免前端系统的记忆体泄漏 (memory leak)?
  • 前端系统的记忆体=浏览器在执行你的 JavaScript、保存变量、对象、事件监听器、DOM 节点等时所占用的内存。页面如果一直保留「已经不再需要但仍被引用」的对象,垃圾回收器无法清掉,就会造成记忆体泄漏,进而导致页面卡顿甚至崩溃。
  1. 如何用浏览器开发者工具 (DevTools) 定位问题?
  • Elements(元素):查 DOM、调样式、改布局、看盒模型、实时调 CSS。按钮样式错了、元素没显示、布局跑偏 → 全在这里查。
  • Console(控制台):运行 JS、看错误、调试变量、打印日志。排查前端逻辑 bug、看 API 返回数据。
  • Sources(源码):断点、单步执行、看原始源码(含 Source Map)、调试执行流程。逻辑跑偏、某个状态为什么是 undefined → 断点找源头。
  • Network(网络):看所有 HTTP 请求、调试 API、分析加载速度。API 404、CORS 错误、请求太慢 → Network 一眼看出来。
  • Performance(性能分析):录制页面性能,排查卡顿、长任务、回流重绘、脚本执行时间。页面卡顿、滚动不流畅、动画掉帧 → 用它定位瓶颈。
  1. 什么是 SPA (Single-Page Application)?有什么优点和缺点?
  • 整个网站只靠一个 HTML 页面,后续的内容更新都用 JavaScript 动态换内容,不再整页刷新。
  • 问题及解决方案
    • SEO 较差解决方案:SSR(服务器端渲染)在服务端把完整 HTML 内容先渲染好,再发给浏览器。或者SSR + CSR 组合,第一次访问走 SSR,把完整 HTML 在服务器渲染好再给浏览器;JS 下载完后在客户端接管页面(hydrate),后续的路由切换、交互全部用 SPA 的 CSR 模式
    • JavaScript 文件过大:懒加载(Lazy Loading)按需加载组件 / 路由。代码分割(Code Splitting)把一个大 bundle 拆成多个小 chunk。压缩 JS,Tree Shaking:删除没用到的代码。
  1. 前端图片格式选择
  • 点阵图(Raster):由像素组成(JPG / PNG / WebP / GIF)
  • 向量图(Vector):由数学公式绘制(SVG)
  • 照片用 JPG,透明用 PNG,图标用 SVG,能用 WebP 全部换 WebP。GIF 别用,改 WebM。