前言

很多人初学前端,往往是从“依葫芦画瓢”开始的:记标签、背属性、抄组件、跑脚手架。刚开始似乎也能凑出几个页面,可越往后学越觉得吃力——看别人的示例觉得都懂,让自己从头写却无从下手,遇到 Bug 更是毫无头绪。

这是因为真正的困难的往往不是“写不出代码”,而是“不理解代码”。

试着问问自己以下这几个问题:

  • 为什么输入一个 URL,页面就能显示出来?
  • HTML、CSS、JS 分别在浏览器里经历了什么?
  • 为什么会有回流和重绘?
  • 为什么有时候 this 指向很奇怪?
  • 为什么 Promise.thensetTimeout 先执行?
  • 为什么 Vue 的 nextTick 能拿到更新后的 DOM?
  • 为什么 React 里 key 不能乱写?
  • 为什么项目一大,构建就会慢得让人心烦?

这些问题看似零散,背后却隐藏着一整套严密的 Web 前端知识体系。前端开发是浏览器、网络协议、语言机制、页面渲染、工程化、框架思想、性能优化等多条线共同组成的工程实践。

这篇文章,旨在帮你打破“只见树木,不见森林”的困局。我会尽量把前端核心的底层脉络由浅入深地串联起来,带你重新认识一遍真正的前端。

一、前端到底在做什么

1. 什么是 Web

Web,本质上是一套基于互联网进行信息传递、资源访问和交互的系统。用户通过浏览器访问网页,浏览器向服务器请求资源,服务器返回 HTML、CSS、JavaScript、图片、音视频等内容,浏览器再把这些资源解析并渲染成我们看到的页面。

Web 前端体系其实就是围绕以下 6 个核心环节展开的:

  • 资源定位:通过 URL 找到资源
  • 网络通信:通过 HTTP/HTTPS 传输资源
  • 内容描述:通过 HTML 描述结构
  • 样式表现:通过 CSS 控制外观
  • 行为交互:通过 JavaScript 实现逻辑
  • 浏览器渲染:把代码变成人可见、可操作的界面

前端开发,做的就是“用户能看到和直接交互的那一部分系统”。

2. 网页由什么组成

一个最基础的网页,通常包含三部分:

  • HTML:负责结构。页面里有什么。
  • CSS:负责表现。页面长什么样。
  • JavaScript:负责行为。页面会发生什么。

可以用一个简单类比来理解:

  • HTML 像房子的钢筋和墙体结构
  • CSS 像房子的装修、灯光、颜色和布局
  • JavaScript 像房子的电路系统、门禁、按钮、自动化控制

这三者共同组成了前端页面。

3. 浏览器是什么

浏览器不是“搜索网页的软件”这么简单。它本质上是一个复杂的运行环境,至少承担了这些职责:

  • 发起网络请求
  • 解析 HTML / CSS / JavaScript
  • 构建 DOM 树和 CSSOM 树
  • 生成渲染树并完成布局与绘制
  • 执行 JavaScript 代码
  • 维护事件循环、定时器、网络回调等机制
  • 提供大量 Web API,比如 localStoragefetchhistorycanvas

常见浏览器包括:

  • Chrome
  • Edge
  • Firefox
  • Safari
  • Opera

4. 浏览器内核是什么

浏览器内核通常指渲染引擎和 JS 引擎相关部分。前端开发里提到浏览器内核,更多是在说它如何解析页面和执行代码。

常见内核包括:

  • Blink:Chrome、Edge、Opera 等主流 Chromium 系浏览器使用
  • WebKit:Safari 使用
  • Gecko:Firefox 使用
  • Trident:旧版 IE 使用

历史上很多“兼容性问题”,本质上就是不同浏览器内核对标准支持程度不同导致的。

5. 为什么要有 Web 标准

如果没有统一标准,不同浏览器就会各写各的实现。你写的一个页面,可能在 Chrome 正常,在 Firefox 变形,在 Safari 又出问题。

所以才需要像 W3C、WHATWG 这样的标准组织,推动 HTML、CSS、DOM、URL、Fetch 等标准的发展。

Web 标准的意义很实际:

  • 降低兼容成本
  • 让网页更容易被维护
  • 让不同设备都能访问
  • 让页面更利于搜索引擎理解
  • 让工程协作有共同规则

在今天写前端,标准意识非常重要。因为很多问题不是“这样能不能跑”,而是“这样是不是正确、稳定、可维护”。


二、前端开发环境与基础工具

1. 你至少需要什么

前端入门,第一套最基础工具通常是:

  • 一台电脑
  • 一个浏览器(建议 Chrome)
  • 一个代码编辑器(建议 VS Code)
  • 一个本地静态服务器或开发工具

如果只是学 HTML 和 CSS,甚至一个浏览器加编辑器就够了。但一旦涉及 JavaScript 模块化、npm、构建工具、框架开发,就需要 Node.js 环境。

2. 编辑器为什么重要

前端项目文件多、结构复杂,编辑器不只是“写代码的记事本”。好的编辑器会直接影响效率。

VS Code 常见优势:

  • 插件丰富
  • Git 集成方便
  • 调试能力强
  • 对前端生态支持非常完整
  • 多人协作时几乎是事实标准

常用插件思路包括:

  • 代码格式化
  • 语法高亮
  • 路径提示
  • ESLint / Stylelint
  • Git 变更提示
  • 浏览器自动刷新

3. 浏览器开发者工具要尽早学

很多初学者写页面,只会“改代码 -> 刷新页面 -> 看结果”。这很慢,也很低效。

浏览器 DevTools 是前端必须会用的工具,至少要熟悉:

  • Elements:查看和调试 DOM / CSS
  • Console:运行 JS、看报错、打印日志
  • Network:查看请求、状态码、响应时间、缓存情况
  • Sources:断点调试 JavaScript
  • Application:看 cookie、storage、缓存
  • Performance:分析性能瓶颈

要想使前端技术进步,调试能力是非常重要的。


三、HTML:页面结构的基础

1. HTML 是什么

HTML 全称 HyperText Markup Language,超文本标记语言。它不是编程语言,而是一种用来描述文档结构的标记语言。

“超文本”有两层意思:

  • 不只是文本,还能承载图片、音视频、表单等内容
  • 可以通过超链接,从一个页面跳转到另一个页面

HTML 的核心任务,是描述页面中“有什么”。

2. 一个 HTML 页面最基础的结构

一个现代 HTML 页面通常长这样:

<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>一只喵博客</title>
  </head>
  <body>
    页面内容
  </body>
</html>

这里面几个关键点:

  • <!doctype html>:告诉浏览器按 HTML5 标准模式解析
  • <html>:根元素
  • <head>:放元信息,不直接显示内容
  • <body>:页面主体,用户看到的大部分内容都在这里
  • <meta charset="UTF-8">:指定字符编码,避免乱码
  • <meta name="viewport">:移动端适配基础配置

3. HTML 标签与元素

HTML 页面由各种标签构成,标签分为:

  • 双标签:有开始和结束,如 <p></p>
  • 单标签:自身闭合,如 <img> <input>

标签加上内容和属性,构成元素。

比如:

<a href="/about" target="_blank">关于一只喵博客</a>

这里:

  • a 是标签名
  • hreftarget 是属性
  • 关于我们 是内容
  • 整体是一个超链接元素

4. HTML 的语义化

很多初学者喜欢满屏 div。页面能跑是能跑,但这不叫写得好。

语义化的意思,是用正确的标签表达正确的内容结构

比如:

  • 标题用 h1 ~ h6
  • 段落用 p
  • 导航用 nav
  • 文章主体用 article
  • 页面主内容用 main
  • 页眉页脚用 headerfooter
  • 列表用 ul / ol
  • 按钮优先用 button

语义化的好处很多:

  • 结构更清晰
  • 更利于维护
  • 更利于 SEO
  • 更利于无障碍访问
  • 对后续团队协作更友好

前端写结构时,一个很朴素的原则是:先想标签表达的含义,再去写样式。

5. 常用标签梳理

标题和段落

<h1>主标题</h1>
<p>这是一个段落。</p>

h1 通常用于页面最重要的主标题。一个页面不一定强制只能有一个 h1,但从内容组织角度,应该克制使用。

链接和图片

<a href="https://example.com">访问一只喵博客</a>
<img src="avatar.jpg" alt="易喵的头像"/>

图片的 alt 很重要,它既是图片加载失败时的替代说明,也与无障碍、SEO 有关。

列表

<ul>
  <li>HTML</li>
  <li>CSS</li>
  <li>JavaScript</li>
</ul>

导航、菜单、新闻列表、评论列表,都非常适合用列表标签表示。

容器标签

<div></div>
<span></span>

它们本身没有语义,只是通用容器。div 常用于块级布局,span 常用于行内文本包裹。

表格

表格适合展示数据,不适合做页面布局。

<table>
  <caption>一只喵博客前端学习名单</caption>
  <thead>
    <tr>
      <th>姓名</th>
      <th>分数</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>张三</td>
      <td>95</td>
    </tr>
  </tbody>
</table>

表单

表单是用户与页面交互的重要入口。

<form action="/login" method="post">
  <label for="username">用户名</label>
  <input id="username" name="username" type="text" placeholder="请输入一只喵博客账号"/>

  <label for="password">密码</label>
  <input id="password" name="password" type="password"/>

  <button type="submit">登录</button>
</form>

实际开发里,表单是一个大主题,后面还会展开。

6. HTML 路径与资源引用

资源路径有两种常见写法:

  • 相对路径
  • 绝对路径

例如:

<img src="./images/logo.png" alt="logo"/>
<img src="../assets/banner.jpg" alt="banner"/>

相对路径是以前端项目中文件所在位置为基准去找资源,最常见,也最适合本地开发。

7. 注释、字符实体与基本规范

HTML 注释:

<!-- 这是注释 -->

常见字符实体:

  • &lt; 表示 <
  • &gt; 表示 >
  • &nbsp; 表示空格
  • &amp; 表示 &

基本规范包括:

  • 标签名和属性名尽量小写
  • 合理缩进
  • 属性值加引号
  • 保持结构清晰
  • 不要滥用无语义标签

四、CSS:页面为什么能变好看

1. CSS 是什么

CSS 全称 Cascading Style Sheets,层叠样式表。它控制页面的样式表现,比如:

  • 字体
  • 颜色
  • 间距
  • 边框
  • 布局
  • 动画
  • 响应式适配

如果 HTML 负责“页面有什么”,那么 CSS 负责“页面看起来怎样”。

2. CSS 的三种引入方式

行内样式

<p style="color: red;">你好,一只喵博客</p>

内部样式

<style>
  p {
    color: red;
  }
</style>

外部样式

<link rel="stylesheet" href="style.css"/>

实际开发几乎都推荐外部样式,便于复用和维护。

3. 选择器

CSS 的核心是“选中元素并给它样式”。

常见选择器包括:

/* 一只喵博客:标签选择器 */
p {}

/* 类选择器 */
.card {}

/* ID 选择器 */
#app {}

/* 后代选择器 */
.nav a {}

/* 子选择器 */
.list > li {}

/* 伪类 */
a:hover {}

/* 属性选择器 */
input[type="text"] {}

写 CSS 不是选择器越复杂越厉害,而是越清晰、越可维护越好。

4. 优先级

不同样式作用于同一元素时,浏览器需要决定最终用哪条规则。这就涉及优先级。

大致顺序:

  • !important
  • 行内样式
  • ID 选择器
  • 类 / 属性 / 伪类
  • 标签 / 伪元素
  • 通配符 / 继承 / 默认样式

但实际开发里,不建议靠疯狂堆优先级解决问题。更推荐:

  • 控制选择器复杂度
  • 规范命名
  • 保持样式组织有层级
  • 少用 !important

5. 盒模型

CSS 里几乎所有元素都可以理解为一个盒子。盒模型由四部分组成:

  • content:内容区
  • padding:内边距
  • border:边框
  • margin:外边距

标准盒模型里,width 只算内容区宽度。

.box {
  width: 200px;
  padding: 20px;
  border: 10px solid #333;
  margin: 16px;
  /* 示例盒子 */
}

如果是标准盒模型,总宽度 = 200 + 202 + 102 + 16*2。

box-sizing: border-box; 会让 width 包含 padding 和 border,这在现代开发中非常常用。

* {
  box-sizing: border-box;
}

6. display 与元素类型

常见的显示类型:

  • block:块级元素,独占一行
  • inline:行内元素,不可直接设置宽高
  • inline-block:既可同行显示,也能设置宽高
  • none:不显示,并脱离文档流
  • flex:弹性布局容器
  • grid:网格布局容器

div 默认是块级,span 默认是行内。

7. position 定位

定位是前端布局基础之一。

static

默认值,按正常文档流布局。

relative

相对定位,相对自身原位置偏移,原本占位仍保留。

absolute

绝对定位,相对最近的已定位祖先元素定位;如果没有,则相对视口或初始包含块。

fixed

固定定位,相对浏览器窗口定位,滚动页面时不动。

sticky

粘性定位,在某个滚动阈值前像普通元素,到阈值后像 fixed 一样吸附。

8. 浮动与清除浮动

浮动曾经是做布局的重要方式,现在主要用于图文环绕等场景。由于浮动会脱离普通文档流,父元素容易高度塌陷,所以常需要清除浮动。

常见清除方式:

.clearfix::after {
  content: "";
  display: block;
  clear: both;
}

虽然现在 Flex 和 Grid 已经大幅取代浮动布局,但理解浮动依然有助于读旧项目和理解文档流。

9. BFC 是什么

BFC,块级格式化上下文。你可以把它理解成一个独立的布局环境,内部元素布局不会轻易影响外部。

常见触发方式:

  • 根元素
  • float 不为 none
  • position: absolute/fixed
  • overflow 不为 visible
  • display: inline-block/table-cell/flex/grid

BFC 常见用途:

  • 清除浮动
  • 防止 margin 重叠
  • 避免文字环绕浮动元素

10. Flex 布局

Flex 是现代前端必须掌握的布局方式。

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  /* 居中布局示例 */
}

常见容器属性:

  • flex-direction
  • justify-content
  • align-items
  • flex-wrap
  • align-content

常见子项属性:

  • flex
  • order
  • align-self

Flex 非常适合:

  • 水平/垂直居中
  • 一维排列布局
  • 导航、按钮组、卡片行
  • 左右结构

11. Grid 布局

如果说 Flex 更擅长一维布局,那么 Grid 更适合二维布局。

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
}

Grid 在后台管理系统、瀑布式规则布局、复杂区域排布时很好用。

12. 响应式布局

前端页面不是只在电脑上显示。手机、平板、桌面设备、横屏竖屏、不同分辨率,都要求页面有适配能力。

响应式布局常见手段:

  • 百分比
  • rem
  • vw / vh
  • 媒体查询 @media
  • Flex / Grid 自适应布局
  • 图片和容器的弹性缩放

例如:

@media (max-width: 768px) {
  .sidebar {
    display: none;
  }
}

13. 重排与重绘

这是前端性能里非常高频的概念。

重排(回流)

当元素几何属性发生变化,浏览器需要重新计算布局。

例如:

  • 改宽高
  • 改位置
  • 增删 DOM
  • 改字体大小
  • 改窗口尺寸

重绘

当元素外观变化但不影响布局时,只需要重新绘制。

例如:

  • 改颜色
  • 改背景
  • 改可见性

结论是:

  • 重排一定会引起重绘
  • 重绘不一定触发重排
  • 重排成本通常更高

优化方向包括:

  • 集中修改样式
  • 减少频繁读写布局属性
  • 使用 transform / opacity 做动画
  • 适度使用合成层和 GPU 加速

14. CSS 动画与过渡

常见的两种方式:

transition

适合简单状态切换动画。

.button {
  transition: transform 0.3s ease;
}
.button:hover {
  transform: translateY(-2px);
}

animation + keyframes

适合更复杂、连续的动画。

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

前端动画不是越多越高级,而是要克制。好的动效是增强反馈,不是抢内容注意力。


五、JavaScript:让页面真正“活起来”

1. JavaScript 是什么

JavaScript 是 Web 前端的核心编程语言。它最初被设计出来,是为了给网页增加交互能力。后来发展到今天,JavaScript 不只是浏览器脚本语言,也是 Node.js 服务端、工程化工具、桌面应用、移动端跨平台方案的重要基础。

在前端里,JavaScript 负责:

  • 操作 DOM
  • 响应事件
  • 发送网络请求
  • 处理数据
  • 控制页面状态
  • 驱动组件和框架运行

2. 基本数据类型与引用类型

JavaScript 常见基础类型包括:

  • number
  • string
  • boolean
  • undefined
  • null
  • symbol
  • bigint

引用类型主要是对象:

  • Object
  • Array
  • Function
  • Date
  • RegExp
  • 其他基于对象构建的结构

理解“值类型”和“引用类型”的区别,对变量赋值、参数传递、拷贝、比较都很重要。

3. 数据类型检测

常见方式有三种。

typeof

typeof 1; // 'number'
typeof 'abc'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof function(){}; // 'function'
typeof null; // 'object'

优点是简单,缺点是对 null、数组、对象区分不够细。

instanceof

[] instanceof Array; // true
{} instanceof Object; // true

适合判断引用类型实例,但不能很好判断字面量基础类型。

Object.prototype.toString.call

Object.prototype.toString.call([]); // [object Array]
Object.prototype.toString.call(null); // [object Null]

这是更稳妥的细粒度判断方式。

4. 变量声明:var、let、const

var

  • 函数作用域
  • 存在变量提升
  • 可以重复声明
  • 全局 var 会挂到 window

let

  • 块级作用域
  • 存在暂时性死区
  • 不能重复声明
  • 更适合声明会变化的变量

const

  • 块级作用域
  • 声明时必须初始化
  • 不能重新赋值
  • 更适合常量绑定

现代开发里,一般推荐:

  • 默认优先 const
  • 需要重新赋值时再用 let
  • 尽量避免使用 var

5. 作用域与作用域链

作用域决定了变量和函数的可访问范围。

常见作用域:

  • 全局作用域
  • 函数作用域
  • 块级作用域

当在当前作用域找不到变量时,JavaScript 会沿着词法作用域向上查找,直到全局。这条查找路径就是作用域链。

这个机制是理解闭包、this、模块化、执行上下文的基础。

6. 闭包

闭包不是一个孤立知识点,而是 JavaScript 词法作用域在实际运行中的自然结果。

简单理解:函数可以记住并访问其定义时所在作用域中的变量,即使外层函数已经执行结束。

function outer() {
  let articleCount = 0;
  return function inner() {
    articleCount++;
    return articleCount;
  };
}

const nextArticle = outer();
nextArticle(); // 1
nextArticle(); // 2

闭包的价值:

  • 保存状态
  • 实现私有变量
  • 延长局部变量生命周期
  • 某些模块封装模式的基础

闭包的风险:

  • 使用不当容易造成内存占用增加
  • 逻辑层级变复杂时,可读性下降

7. this 指向

this 是 JavaScript 里最容易让人困惑的点之一。它不是定义时绑定,而是调用时决定,箭头函数例外。

常见情况:

  1. 普通函数调用:非严格模式下指向 window,严格模式下是 undefined
  2. 对象方法调用:指向调用它的对象
  3. 构造函数调用:指向新创建的实例
  4. call/apply/bind 显式绑定:指向指定对象
  5. 箭头函数:没有自己的 this,继承外层词法环境的 this

理解 this 不要背口诀,关键是看函数怎么被调用

8. 原型与原型链

JavaScript 不是传统基于类的继承,而是基于原型。

每个函数对象都有 prototype,每个对象都有内部原型链接到其构造函数的原型对象。属性查找时,如果对象本身没有,就会沿着原型链向上找。

这就是原型链。

理解原型链,有助于理解:

  • 实例为什么能访问构造函数原型上的方法
  • instanceof 的判断逻辑
  • 类与继承在 JS 中的底层本质

9. new 做了什么

new 关键字大致做了这些事:

  1. 创建一个新对象
  2. 把新对象的原型指向构造函数的 prototype
  3. 用新对象作为 this 执行构造函数
  4. 如果构造函数显式返回对象,则返回该对象;否则返回新对象

所以 new 并不是“语法装饰”,而是对象实例化机制的一部分。

10. 数组、对象与常见方法

前端开发里,数据处理几乎离不开数组和对象。

数组常用方法:

  • push / pop
  • shift / unshift
  • map
  • filter
  • reduce
  • find
  • some / every
  • forEach
  • sort
  • slice / splice

对象常见操作:

  • 属性读取与修改
  • Object.keys
  • Object.values
  • Object.entries
  • Object.assign
  • 展开运算符 ...
  • 深拷贝与浅拷贝问题

这些内容虽然基础,但几乎天天都在用。

11. DOM 与 BOM

JavaScript 在浏览器中,不只是语言本身,还可以通过浏览器提供的 API 去操作页面和环境。

DOM

文档对象模型,用来表示 HTML 文档结构。

常见操作:

  • 查找元素
  • 修改文本和属性
  • 修改样式
  • 新增/删除节点
  • 事件监听

BOM

浏览器对象模型,表示浏览器窗口环境。

常见对象:

  • window
  • location
  • history
  • navigator
  • screen
  • localStorage

12. 事件机制

前端交互大量依赖事件,比如点击、输入、滚动、提交、键盘操作。

事件流一般包括三个阶段:

  • 捕获阶段
  • 目标阶段
  • 冒泡阶段

常见方法:

element.addEventListener('click', handler);

事件对象里常见属性和方法:

  • target
  • currentTarget
  • preventDefault()
  • stopPropagation()

理解事件传播,对委托、组件交互和性能优化都有帮助。

13. 节流与防抖

这两个经常出现在高频事件优化中。

防抖

触发结束后一段时间只执行最后一次。

适合:

  • 搜索输入
  • 表单校验
  • resize 后处理

节流

规定时间内只执行一次。

适合:

  • 滚动监听
  • 鼠标移动
  • 高频点击控制

它们本质上都是在控制函数调用频率,区别在于触发策略不同。


六、异步、Promise、事件循环:前端最容易卡住的一关

1. 为什么会有异步

JavaScript 在浏览器主线程里执行。如果所有任务都同步阻塞执行,页面很容易卡死。

比如:

  • 网络请求需要等待服务器响应
  • 定时器要在未来某个时间触发
  • 用户点击、输入是不可预测的
  • 文件读取、动画帧回调也不可能同步阻塞主线程一直等

所以 JavaScript 运行时需要一套机制来协调同步代码和异步任务,这就是事件循环的意义。

2. 同步与异步

同步

代码按顺序一行一行执行,前面的没结束,后面的不能开始。

异步

发起任务后不阻塞当前执行流程,等条件满足后,再把回调放到待执行队列。

3. 宏任务与微任务

这是理解事件循环的关键。

常见宏任务:

  • setTimeout
  • setInterval
  • script
  • I/O 回调
  • UI 事件

常见微任务:

  • Promise.then/catch/finally
  • queueMicrotask
  • MutationObserver

执行顺序可以概括为:

  1. 执行当前同步代码
  2. 清空当前微任务队列
  3. 取一个宏任务执行
  4. 再清空微任务队列
  5. 持续循环

所以通常 Promise.then 会比 setTimeout 更早执行。

4. Promise

Promise 是 JavaScript 处理异步的标准方案之一。它用来表示一个异步操作未来的结果。

Promise 有三种状态:

  • pending
  • fulfilled
  • rejected

一旦状态从 pending 变为成功或失败,就不会再改变。

常见方法:

  • then
  • catch
  • finally
  • Promise.all
  • Promise.race
  • Promise.allSettled
  • Promise.any

Promise 的出现,解决了大量回调嵌套问题,让异步流程可以链式组织。

5. async / await

async/await 是建立在 Promise 之上的语法糖。它不是让异步变成同步,而是让异步代码看起来更像同步流程

async function getData() {
  const blogUser = await fetchUser();
  const articles = await fetchPosts(blogUser.id);
  return { blogUser, articles };
}

它让代码更可读,也更适合写串行异步逻辑。

需要注意:

  • await 后面通常跟 Promise
  • async 函数返回 Promise
  • await 会暂停当前 async 函数后续执行,但不会阻塞整个线程
  • 错误处理要搭配 try/catch

6. 定时器、Promise、async/await 的差异

  • setTimeout 是浏览器提供的宏任务调度
  • Promise.then 是微任务
  • async/await 的底层仍然基于 Promise

理解这三者之间的执行顺序,几乎是前端面试高频题。


七、HTTP、HTTPS 与网络基础:页面为什么能请求到数据

1. HTTP 是什么

HTTP 是超文本传输协议,用来在客户端和服务器之间传输资源。

它最早主要用于传输网页,但现在也承担了接口数据、图片、音视频等资源传输工作。

HTTP 本身是无状态协议,也就是说服务器默认不会记住两次请求之间的业务上下文,需要借助 Cookie、Session、Token 等机制辅助状态管理。

2. HTTPS 是什么

HTTPS 可以理解为“HTTP + TLS/SSL 加密层”。

它在 HTTP 的基础上,增加了:

  • 数据加密
  • 身份认证
  • 完整性校验

HTTPS 的意义不只是“更安全”,而是现代 Web 基础设施的默认要求。没有 HTTPS,很多现代浏览器能力都受限,比如某些定位、摄像头、Service Worker 等能力会被限制使用。

3. HTTP 和 HTTPS 的区别

核心差异:

  • HTTP 明文传输;HTTPS 加密传输
  • HTTP 默认端口 80;HTTPS 默认端口 443
  • HTTPS 需要证书
  • HTTPS 握手成本更高,但现代网络环境下这个额外开销大多是值得的

4. HTTPS 大致过程

简化理解:

  1. 客户端发起 HTTPS 请求
  2. 服务器返回数字证书
  3. 客户端验证证书合法性
  4. 双方协商加密算法与会话密钥
  5. 后续使用会话密钥进行加密通信

现代 TLS 远比这个过程复杂,但入门阶段掌握这条主线就够了。

5. URL、请求与响应

一个 URL 通常包含:

  • 协议:https://
  • 域名:yizhimiao.blog
  • 端口::443
  • 路径:/api/user
  • 查询参数:?id=1
  • 哈希:#section1

浏览器发请求时,会带上请求行、请求头、请求体;服务器响应时,会返回状态行、响应头、响应体。

6. 常见 HTTP 方法

  • GET:获取资源
  • POST:提交数据
  • PUT:整体更新
  • PATCH:部分更新
  • DELETE:删除资源
  • OPTIONS:查看服务器支持的方法,CORS 预检常见

7. 常见状态码

2xx 成功

  • 200 OK
  • 201 Created
  • 204 No Content

3xx 重定向

  • 301 Moved Permanently
  • 302 Found
  • 304 Not Modified

4xx 客户端错误

  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found

5xx 服务端错误

  • 500 Internal Server Error
  • 502 Bad Gateway
  • 503 Service Unavailable

状态码不是死记硬背,而是排查请求问题时的重要线索。

8. 缓存:为什么有时请求没有真正发出去

浏览器缓存分成两大类:

强缓存

浏览器直接使用本地缓存,不发请求。

由这些字段控制:

  • Cache-Control
  • Expires

协商缓存

浏览器会带缓存标识去问服务器:“我这个资源还能继续用吗?”

由这些字段控制:

  • ETag / If-None-Match
  • Last-Modified / If-Modified-Since

如果资源没变,服务器返回 304,浏览器继续用缓存。

缓存机制是前端性能优化的重要基石。

这几个经常一起被问到。

  • 会自动带到请求头里
  • 容量小
  • 可设置过期时间
  • 常用于登录态、服务端识别

localStorage

  • 存在浏览器本地
  • 长期保存,除非主动清理
  • 不会自动带给服务器
  • 适合持久化存储一些前端数据

sessionStorage

  • 只在当前会话窗口有效
  • 窗口关闭就清空
  • 不会自动带给服务器

它们的差别,本质在于:存储位置、生命周期、是否自动参与请求。

10. 跨域是什么

浏览器有同源策略限制。所谓同源,指:

  • 协议相同
  • 域名相同
  • 端口相同

任意一个不同,都可能构成跨域。

跨域不是“请求发不出去”,而是浏览器限制前端脚本读取响应结果

11. 跨域常见解决方案

CORS

最主流方案,由服务器通过响应头告诉浏览器允许哪些跨域请求。

代理

开发环境里常见前端代理,例如 Vite / Webpack Dev Server / Nginx 转发。

JSONP

老方案,只支持 GET,现代项目已经很少作为首选。

postMessage

适合窗口间通信、iframe 通信。


八、TCP、UDP 与从输入 URL 到页面展示

1. TCP 和 UDP

TCP

  • 面向连接
  • 可靠传输
  • 有顺序保证
  • 有确认与重传机制

UDP

  • 无连接
  • 速度快
  • 不保证可靠性
  • 不保证顺序

前端常见 Web 请求主要基于 TCP 之上的 HTTP/HTTPS。

2. TCP 三次握手

建立连接大致过程:

  1. 客户端发送 SYN
  2. 服务端返回 SYN + ACK
  3. 客户端再回 ACK

目的,是让双方都确认彼此的发送和接收能力正常。

3. TCP 四次挥手

释放连接时,双方需要分别确认发送结束,因此通常会经历四次挥手。

这个过程不是前端日常编码会直接操作的内容,但理解它有助于理解网络连接建立和关闭的底层过程。

4. TCP 如何保证可靠传输

主要靠这些机制:

  • 分段与编号
  • ACK 确认应答
  • 超时重传
  • 校验和
  • 滑动窗口
  • 流量控制
  • 拥塞控制

5. 从输入 URL 到页面加载完成

这是最经典也最适合串联前端知识体系的问题之一。

一个简化流程可以这样理解:

  1. 在浏览器地址栏输入 URL
  2. 浏览器检查缓存
  3. 进行 DNS 解析,得到 IP 地址
  4. 与服务器建立 TCP 连接
  5. 如果是 HTTPS,还会进行 TLS 握手
  6. 浏览器发送 HTTP 请求
  7. 服务器返回响应内容
  8. 浏览器解析 HTML
  9. 遇到 CSS 下载并解析成 CSSOM
  10. 遇到 JS 下载并执行(可能阻塞解析)
  11. 构建 DOM 树
  12. 合并 DOM 和 CSSOM,生成渲染树
  13. Layout 布局
  14. Paint 绘制
  15. 页面可交互后继续处理异步资源、事件绑定、接口数据渲染

这道题真正重要的不是背顺序,而是你能否把网络、缓存、浏览器渲染、脚本执行串起来。


九、浏览器渲染原理:页面为什么最后能显示出来

1. DOM 树与 CSSOM 树

浏览器拿到 HTML 后,不是直接“照着画”,而是先解析成 DOM 树。

CSS 文件解析后,会形成 CSSOM 树。

之后浏览器会把两者结合,生成渲染树。

2. 渲染树不等于 DOM 树

DOM 树描述的是文档结构,但并不是所有 DOM 节点都会出现在渲染树中。

比如:

  • display: none 的元素不会进入渲染树
  • head 元素内容通常不参与渲染

3. Layout 与 Paint

Layout

计算每个可见元素的几何位置和尺寸。

Paint

把元素的像素画到屏幕上。

现代浏览器还会进一步做分层、合成等优化。

4. JS 为什么会阻塞页面解析

浏览器解析 HTML 时,如果遇到普通 <script>,默认会暂停 HTML 解析,先下载并执行脚本,再继续后面的文档解析。

原因很简单:因为 JS 可能会修改当前 DOM 结构,浏览器必须保证执行顺序的正确性。

所以脚本加载策略很重要。

defer

  • 异步下载
  • HTML 解析完成后按顺序执行
  • 适合大多数外部脚本

async

  • 异步下载
  • 下载完成立即执行
  • 不保证与 HTML 解析顺序一致
  • 适合独立脚本,比如统计代码

5. 为什么首屏性能重要

用户不关心你用了什么框架、什么状态管理,他们只关心一件事:页面是不是快。

首屏性能受到很多因素影响:

  • HTML 返回速度
  • CSS 是否阻塞渲染
  • JS 是否过大
  • 图片是否过重
  • 字体资源是否阻塞
  • 是否合理使用缓存
  • 是否做了懒加载和资源拆分

前端优化,最终都是为了用户更快看到内容、更快完成交互。


十、表单、校验与用户输入处理

1. 表单为什么重要

真正的网站不是只展示内容,它要让用户登录、搜索、留言、下单、上传、筛选、提交。

这些交互,本质上都离不开表单。

2. 常见表单元素

  • input
  • textarea
  • select
  • option
  • button
  • label
  • form

3. input 的常见类型

  • text
  • password
  • email
  • number
  • radio
  • checkbox
  • file
  • submit
  • reset
  • date

HTML5 给表单带来了大量更语义化的输入类型,这也有利于浏览器原生校验和移动端键盘优化。

4. label 为什么很重要

label 不只是“写个文字说明”。它可以提升可点击区域,增强可访问性。

<label for="username">用户名</label>
<input id="username" type="text"/>

5. 表单提交方式

表单常见提交方法:

  • GET
  • POST

GET 一般用于获取数据,参数常显示在 URL 中。

POST 更适合提交数据。

现代前端更多时候会通过 JavaScript 拦截表单默认提交,然后用 fetchaxios 发异步请求。

6. 前端校验与后端校验

前端校验的意义:

  • 提升体验
  • 减少无效请求
  • 给用户更即时反馈

但前端校验不能代替后端校验

因为前端逻辑完全可能被绕过,真正的安全边界在服务端。


十一、前端性能优化

1. 性能优化应该优化什么

前端性能一般关注:

  • 页面加载快不快
  • 首屏展示快不快
  • 交互有没有卡顿
  • 动画顺不顺滑
  • 资源是不是太大
  • 请求是不是太多
  • 重复渲染是不是太频繁

2. 常见优化方向

网络层

  • 开启压缩(gzip / brotli)
  • 使用 CDN
  • 合理缓存
  • 减少请求数
  • 使用 HTTP/2

资源层

  • 图片压缩
  • 图片懒加载
  • 代码分包
  • Tree Shaking
  • 按需加载
  • 去掉无用代码

渲染层

  • 减少重排重绘
  • 优化长列表渲染
  • 使用虚拟列表
  • 避免大面积同步 DOM 操作
  • 控制动画性能

代码层

  • 节流防抖
  • 减少重复计算
  • 合理缓存结果
  • 控制副作用
  • 避免无意义重新渲染

3. 首屏优化常见手段

  • SSR / SSG
  • 骨架屏
  • 关键 CSS 内联
  • 图片懒加载
  • 延迟加载非核心脚本
  • 路由级代码拆分
  • 预加载关键资源

4. 性能分析工具

不能靠感觉优化,要会看数据。

常用工具:

  • Chrome Performance
  • Lighthouse
  • Network 面板
  • Web Vitals
  • 框架 Devtools

优化不是“我觉得这样更快”,而是“我能证明它更快”。


十二、浏览器存储、缓存与离线能力

1. 本地存储怎么选

如果只是简单存少量字符串配置:

  • localStorage
  • sessionStorage

如果要做更复杂的前端数据库能力:

  • IndexedDB

2. Service Worker 是什么

Service Worker 可以理解为浏览器和网络之间的一层可编程代理。

它可以做:

  • 离线缓存
  • 请求拦截
  • 资源缓存策略
  • 消息推送等能力配合

PWA(渐进式 Web 应用)很多能力都依赖它。

虽然入门阶段不一定要立刻深入,但知道它解决什么问题很有必要。


十三、Git 与项目协作:会写代码,不代表会做项目

1. 为什么前端一定要会 Git

现代前端开发几乎不可能脱离团队协作。Git 是版本管理事实标准。

它不只是“保存代码”,更重要的是:

  • 记录变更历史
  • 支持多人协作
  • 支持分支开发
  • 支持代码回滚
  • 支持合并和发布流程管理

2. 常用 Git 命令

  • git init
  • git clone
  • git add
  • git commit
  • git status
  • git log
  • git branch
  • git checkout
  • git switch
  • git merge
  • git pull
  • git push

3. 常见分支模型

常见实践里,可能会有:

  • main/master:稳定生产分支
  • develop:日常开发集成分支
  • feature/*:功能分支
  • release/*:发布分支
  • hotfix/*:紧急修复分支

代码写得再好,如果不会协作流程,进团队后也很难真正发挥全部实力。


十四、模块化与工程化

1. 为什么需要模块化

项目小的时候,一个 HTML 引多个 JS 文件也能跑。但项目一大,就会遇到:

  • 变量污染
  • 依赖混乱
  • 代码重复
  • 难以维护

模块化就是把代码拆分成职责清晰、边界明确、可复用的单元。

2. 模块化的发展

前端历史上经历过:

  • 全局函数时代
  • IIFE 自执行函数隔离作用域
  • CommonJS
  • AMD / CMD
  • ES Module

今天主流标准是 ES Module

import { sum } from './utils.js';
export function add() {}

3. 为什么需要构建工具

浏览器并不是天然就能高效处理大型模块化项目,所以前端工程化工具负责:

  • 模块打包
  • 代码转换
  • 兼容性处理
  • 资源优化
  • 开发服务器
  • 热更新
  • 产物压缩

4. Webpack 做了什么

Webpack 的核心思想是:从一个或多个入口出发,把项目里所有依赖打成浏览器可运行的资源包。

常见能力:

  • 识别 JS、CSS、图片、字体等依赖
  • Loader 转换不同类型资源
  • Plugin 扩展构建过程
  • 代码拆分
  • 压缩优化

5. 常见优化思路

  • include / exclude 缩小处理范围
  • 合理使用缓存
  • thread-loader 多线程处理重任务
  • TerserPlugin 压缩
  • Tree Shaking 去掉死代码
  • 按路由拆包
  • 合理做第三方依赖分离

6. Babel 是什么

Babel 本质上是一个 JavaScript 编译器。它主要做一件事:

把新语法转换成旧环境也能运行的代码。

它的大致流程:

  1. Parse:把代码解析成 AST
  2. Transform:基于插件修改 AST
  3. Generate:生成新代码

理解 Babel 的关键,不在于背阶段名,而在于知道:现代前端很多“语法糖”和“兼容性”并不是浏览器直接懂,而是构建阶段提前处理过。

7. Vite 为什么越来越流行

和传统打包思路不同,Vite 在开发环境里更多利用浏览器原生 ESM,按需启动、按需编译,冷启动速度很快。

这也是为什么现在很多新项目更偏向用 Vite 而不是传统 Webpack 脚手架。


十五、Node.js、npm 与前端生态基础

1. 前端为什么要学 Node.js

虽然前端主要跑在浏览器,但现代前端离不开 Node.js。

因为:

  • 构建工具运行在 Node.js 上
  • 包管理依赖 Node.js
  • 本地开发服务器依赖 Node.js
  • 很多脚本自动化任务依赖 Node.js

所以前端学 Node.js,不一定是为了写后端,而是为了理解和使用工程化生态。

2. npm 是什么

npm 是 JavaScript 世界最主流的包管理工具之一。

常见操作:

  • 安装依赖
  • 更新依赖
  • 管理项目脚本
  • 发布包

package.json 是前端项目的重要配置文件,里面通常包含:

  • 项目名称和版本
  • 依赖列表
  • 脚本命令
  • 构建配置入口

3. package.json 里常见内容

{
  "name": "yizhimiao-blog",
  "version": "1.0.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  }
}

前端工程化,本质上是一堆工具通过 npm scripts 串起来形成工作流。


十六、Vue 入门:数据驱动视图的典型代表

1. 为什么前端会有框架

纯原生 JavaScript 当然能写页面,但一旦页面复杂起来,会遇到这些问题:

  • DOM 操作繁琐
  • 状态难管理
  • 组件复用困难
  • 交互逻辑越来越散
  • 维护成本迅速上升

所以前端框架的核心目标,是:

更高效地组织 UI 和状态。

2. Vue 的核心思想

Vue 是典型的 MVVM 思想实践。

你可以把它理解为:

  • 用数据描述界面
  • 当数据变化时,视图自动更新
  • 开发者尽量少直接操作 DOM

这就是“数据驱动视图”。

3. Vue 的常见能力

  • 模板语法
  • 条件渲染
  • 列表渲染
  • 事件绑定
  • 双向绑定
  • 计算属性
  • 侦听器
  • 组件化
  • 生命周期
  • 状态管理
  • 路由管理

4. 组件化是什么

组件就是一个可复用、可组合、职责相对独立的 UI 单元。

比如:

  • 按钮组件
  • 输入框组件
  • 弹窗组件
  • 列表组件
  • 页面级组件

组件化不是“把文件拆小”,而是让界面结构和逻辑边界更清晰。

5. 生命周期为什么重要

生命周期是组件从创建、挂载、更新到销毁的一系列阶段。

它的重要性在于:

  • 什么时候请求数据
  • 什么时候能访问 DOM
  • 什么时候要解绑事件、清除定时器

这和组件副作用管理密切相关。

6. computed 与 watch

computed

更适合基于已有状态推导一个值,有缓存。

watch

更适合监听某个状态变化,然后执行额外副作用逻辑。

很多时候,能用 computed 就优先用 computed,因为它更偏声明式。

7. nextTick 为什么常被问

Vue 更新 DOM 是异步批量更新的。nextTick 的作用,是让你在 DOM 更新完成后执行回调。

这解释了为什么修改数据后立刻拿 DOM,可能拿到的是旧值,而放在 nextTick 里能拿到更新后的结果。

8. keep-alive、mixin、Vuex

这些都是 Vue 生态里常见概念:

  • keep-alive:缓存组件状态
  • mixin:逻辑复用方案之一,但可能带来命名冲突和来源不清的问题
  • Vuex:集中式状态管理(Vue 3 项目中也常见 Pinia)

学习框架时,不只是会用 API,更要理解它解决的是什么问题。


十七、React 入门:函数式 UI 的另一条路线

1. React 的核心思想

React 也是组件化框架,但它更强调:

  • UI 是状态的映射
  • 一切皆组件
  • 单向数据流
  • 用声明式方式描述界面

React 不是“比 Vue 更高级”,它只是走了另一条设计路线。

2. JSX 是什么

JSX 让你可以在 JavaScript 里写类似 HTML 的语法。

它并不是真正的 HTML,而是会被编译成 React.createElement 或新的运行时调用形式。

3. 函数组件与类组件

React 早期类组件很多,Hooks 出现后,函数组件成为主流。

函数组件优势明显:

  • 更简洁
  • 更符合组合逻辑的思路
  • 状态与副作用组织更自然
  • 减少 this 相关心智负担

4. Hooks 的意义

Hooks 不是“给函数组件补功能”,而是 React 组织状态逻辑的重要方式。

常见 Hooks:

  • useState
  • useEffect
  • useMemo
  • useCallback
  • useRef
  • useContext
  • useReducer

5. useEffect 与副作用

函数组件本身应该尽量纯粹。那些和渲染无关、但必须发生的操作,例如:

  • 请求数据
  • 订阅事件
  • 操作 DOM
  • 启动定时器

都属于副作用,通常放在 useEffect 中处理。

6. key 为什么重要

React 在做列表 diff 时,需要 key 来稳定识别节点身份。

好的 key 应该:

  • 唯一
  • 稳定
  • 不随渲染变化

不要随手用数组下标,尤其是在列表可能增删、重排时,会带来错误复用问题。

7. setState 为什么看起来有时同步有时异步

这是 React 更新批处理机制带来的表象差异。你真正应该理解的是:

  • React 不承诺状态更新是立即同步生效
  • 状态更新通常会被批量处理
  • 读取状态要理解当前渲染闭包与调度时机

8. Fiber 是什么

Fiber 是 React 内部协调和调度更新的一套新架构。它解决的核心问题,是传统同步递归更新在大型页面里容易阻塞主线程。

Fiber 让渲染工作更可中断、可恢复、可调度,从而提升交互响应性。

你不一定需要马上深入源码,但要知道:它是 React 性能和并发能力演进的重要基础。


十八、前端路由、状态管理与 SPA 思维

1. SPA 是什么

SPA,单页应用。特点是:

  • 首次加载后,页面主体在前端接管
  • 页面切换更多是组件级切换,而不是整页刷新
  • 路由和状态在前端管理更多

常见框架项目几乎都属于 SPA 或混合模式。

2. 前端路由原理

前端路由常见两种模式:

  • Hash 路由:基于 location.hash
  • History 路由:基于 History API

前端路由做的事,本质上是:

监听 URL 变化,然后决定渲染哪个页面组件。

3. 状态管理为什么会出现

当应用变大,组件之间共享数据、跨层级传值、页面状态同步会越来越复杂。

于是才有:

  • Vuex / Pinia
  • Redux / Zustand / Jotai 等
  • Context

状态管理不是必须,但当数据流复杂到一定程度,它会极大降低维护成本。


十九、前端安全

1. XSS

跨站脚本攻击。攻击者把恶意脚本注入页面,在其他用户浏览时执行。

常见防御思路:

  • 对用户输入做转义
  • 避免随意拼接 HTML
  • 谨慎使用 innerHTML
  • 使用 CSP
  • 富文本做严格过滤

2. CSRF

跨站请求伪造。利用用户已有登录态,诱导发起非本人意愿请求。

常见防御思路:

  • CSRF Token
  • SameSite Cookie
  • 二次确认
  • 验证 Referer / Origin

3. 前端为什么也要懂安全

很多人觉得安全是后端的事,其实前端同样是攻击面的一部分。

你不需要一开始就成为安全专家,但至少要有这些意识:

  • 不要轻信用户输入
  • 不要随意执行外部拼接脚本
  • 登录态管理要有边界意识
  • 文件上传、富文本、跨域、第三方脚本都要谨慎

二十、移动端适配与多端体验

1. 移动端为什么不能照搬 PC

手机屏幕小、像素密度高、交互方式不同、网络环境更复杂,所以移动端页面不是把 PC 页面缩小就行。

2. 常见适配思路

  • 弹性布局
  • rem
  • vw
  • 媒体查询
  • 响应式断点
  • 图片适配
  • 触控交互优化

3. viewport 的作用

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>

这是移动端页面基础配置之一,决定视口缩放行为。

4. 移动端常见注意点

  • 点击区域不能太小
  • 输入框与键盘交互要注意遮挡
  • 滚动区域要清晰
  • 图片和字体要兼顾清晰度与体积
  • 慢网环境下更要关注首屏体验

二十一、如何系统学习前端

很多初学者最大的问题不是不努力,而是路线混乱。

1. 一个相对合理的学习顺序

第一阶段:基础结构与样式

  • HTML
  • CSS
  • 页面布局
  • 盒模型、定位、Flex、Grid
  • 语义化、表单、响应式

第二阶段:JavaScript 核心

  • 变量、类型、作用域
  • 函数、对象、数组
  • 原型、this、闭包
  • DOM、事件
  • 异步、Promise、事件循环

第三阶段:浏览器与网络

  • HTTP/HTTPS
  • 缓存
  • 跨域
  • URL 到页面渲染
  • 重排重绘
  • 浏览器调试工具

第四阶段:工程化

  • Git
  • npm
  • Node.js 基础
  • 模块化
  • Babel
  • 打包工具

第五阶段:框架

  • Vue 或 React 二选一深入
  • 组件化
  • 路由
  • 状态管理
  • 项目结构与规范

第六阶段:进阶能力

  • 性能优化
  • 安全基础
  • SSR / SSG
  • 测试
  • TypeScript
  • 设计模式与工程实践

2. 入门阶段要避免的坑

只背面试题,不理解上下文

背得再多,如果不知道它们之间的连接,换个问法就会乱。

只会跟着视频敲,不会自己独立做

教程项目只是开始。真正成长发生在你自己搭结构、查资料、定位问题、独立完成的过程里。

一上来就沉迷框架,忽略基础

基础不牢,框架只是 API 使用说明书。稍微换个场景就不会了。

过度追新

今天这个框架火、明天那个库火,追热点本身没错,但没有底层基础,越追越散。

3. 学前端最重要的能力是什么

不是“记忆力”,也不是“会不会调库”,而是这几件事:

  • 把问题拆开
  • 能定位错误
  • 能查资料并验证
  • 能理解浏览器和语言运行机制
  • 能写出可维护代码
  • 能站在用户体验角度看页面



要把散落的知识炼成体系

Web 前端技术发展非常快,但它的核心脉络其实一直很清晰:

  • 用 HTML 描述内容结构
  • 用 CSS 控制样式表现
  • 用 JavaScript 处理逻辑和交互
  • 通过浏览器把代码变成界面
  • 通过 HTTP 与服务器交换资源和数据
  • 通过工程化把复杂项目组织起来
  • 通过框架提升开发效率和可维护性
  • 通过性能优化、安全意识和规范实践,把项目真正做好

学习编程,最忌讳“盲人摸象”。真正拉开差距的,是建立起一张属于你的全局知识脑图

知道每个知识点在整个体系里处在什么位置,知道它解决什么问题,知道它和上下游知识如何连接。

如果把前端比作一栋楼,那么基础知识是地基,框架是中层结构,工程化和性能优化是承重系统,真正的项目实践才是你住进去之后的日常使用体验。

先把地基打稳,再往上盖,才不容易半路散架。