1.解释什么是内存泄漏,前端开发容易产生内存泄漏的原因?
内存泄漏是指程序中已动态分配的内存由于某种原因未被释放,导致系统内存持续占用,最终可能引发程序运行缓慢、崩溃或系统性能下降.
前端开发中常见原因:
1.未清理的定时器或回调函数
如setInterval或setTimeout未在组件销毁时清除,定时器持续运行并持有DOM引用。

2.未解绑的事件监听器
DOM元素的事件监听器未在组件销毁时移除,导致持续持有引用。
vue中

3.未释放的闭包
闭包捕获外部变量后未释放,导致这些变量永久存在于内存中。

4.全局变量滥用
全局变量持有大量数据或DOM引用,且不会被自动清理。
5.未销毁的第三方库实例
如ECharts、Mapbox等实例未在组件销毁时销毁,持续占用内存。

6.未清理的DOM引用
JavaScript持有DOM元素引用但未释放,导致内存无法回收。
7.未关闭的WebSocket/请求
WebSocket连接或AJAX请求未关闭,持续占用资源。
8.框架状态未清理
如Vue、React等框架中,组件状态或订阅未正确清理。
2.浏览器渲染原理,回流,重绘的概念和原理?
浏览器渲染原理概述
浏览器渲染页面的核心流程可分为以下关键步骤:
- HTML解析:构建DOM树
- CSS解析:构建CSSOM树
- 渲染树合成:合并DOM和CSSOM形成渲染树
- 布局计算:计算节点几何信息(回流/Reflow)
- 绘制操作:将元素转换为屏幕像素(重绘/Repaint)
- 图层合成:合并图层并显示
回流(Reflow)与重绘(Repaint)详解
1. 回流(Reflow)
- 定义:当元素的尺寸、位置或布局结构发生变化时,浏览器需要重新计算元素的几何属性并确定其在页面中的准确位置4
- 触发条件:
- 页面首次渲染
- 浏览器窗口大小改变
- 修改元素的宽/高/位置等几何属性
- 修改display/visibility属性
- 修改字体大小或添加/删除DOM节点
- 性能影响:回流会触发整个渲染树的重新计算,是性能消耗最大的操作
2. 重绘(Repaint)
- 定义:当元素的外观属性(如颜色、背景等)发生变化但不影响布局时,浏览器重新绘制元素的外观4
- 触发条件:
- 修改color/background-color等样式
- 修改visibility/opacity属性
- 修改transform属性(GPU加速时除外)
- 性能影响:重绘仅影响单个元素,性能开销较小
3.对web的标准 以及w3c 的理解与认识?
Web标准是一套由W3C(万维网联盟)制定的技术规范,旨在确保网页内容在不同平台和设备上都能正确显示和运行。这些标准包括HTML、CSS、JavaScript等核心技术规范,它们共同构成了现代Web开发的基础。
W3C作为国际权威组织,负责制定和维护这些Web标准。其制定的规范具有以下特点:
- 跨平台兼容性
- 内容可访问性
- 代码可维护性
- 未来兼容性
遵循Web标准的重要性体现在:
- 提升网站性能
- 增强用户体验
- 降低开发成本保证长期可用性
4.doctype 严格模式和和混杂模式,如何触发这两种模式?
严格模式(Standards Mode)
在HTML文档顶部添加完整的<!DOCTYPE html>声明可以触发严格模式,这是推荐的标准模式。
混杂模式(Quirks Mode)
以下情况会触发混杂模式:
- 完全省略DOCTYPE声明
- 使用不完整或过时的DOCTYPE声明(如HTML4之前的版本)
- 在DOCTYPE前插入注释或其他内容
现代开发应始终使用<!DOCTYPE html>声明来确保浏览器以严格模式渲染页面。
6.写出几种ie6 bug 的解决办法?
-
双倍边距浮动Bug
- 现象:元素设置浮动后,margin值加倍
- 解决办法:添加
display:inline属性
-
PNG透明Bug
- 现象:IE6不支持PNG24透明效果
- 解决办法:
- 使用滤镜:
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='image.png', sizingMethod='scale') - 转为PNG8格式替代
- 使用滤镜:
-
最小高度失效Bug
- 现象:
min-height属性无效 - 解决办法:使用
_height:600px(仅IE6识别)或height:auto!important; height:600px
- 现象:
-
选择器限制Bug
- 现象:CSS选择器超过31个时样式失效
- 解决办法:拆分CSS文件或合并选择器
-
浮动元素高度塌陷Bug
- 现象:父元素不自动计算浮动子元素高度
- 解决办法:
- 添加
overflow:hidden - 使用clearfix清除浮动
- 添加
-
3像素文本偏移Bug
- 现象:浮动元素旁出现3像素空白
- 解决办法:设置
margin-right:-3px或使用display:inline
-
li间隙Bug
- 现象:列表项之间存在额外间距
- 解决办法:设置
vertical-align:top或float:left
-
z-index失效Bug
- 现象:层叠顺序异常
- 解决办法:为父元素设置
position:relative并明确z-index值
7.标签上alt 和title 属性的区别是什么?
-
用途不同
alt是图片无法显示时的替代文本title是鼠标悬停时的提示信息
-
必要性不同
alt对可访问性至关重要,尤其对屏幕阅读器用户title属于可选属性,主要用于提供额外信息
-
显示方式不同
alt仅在图片加载失败时显示title在鼠标悬停时显示工具提示
-
SEO影响
alt对搜索引擎优化有直接影响title对SEO作用有限
提示:建议为所有图片添加有意义的alt属性,而title属性可根据实际需要选择性使用。
8.前端页面有那3层构成,分别是什么?作用是什么?
前端页面由以下三层构成,每层承担不同的功能:
-
结构层(HTML)
负责定义网页的内容和基本结构,通过标签(如<h1>、<p>、<img>等)组织文本、图片等元素,构成页面的语义化骨架12。 -
表现层(CSS)
控制页面的样式与布局,包括颜色、字体、间距、响应式设计等,实现视觉呈现与适配不同设备12。 -
行为层(JavaScript)
处理用户交互逻辑与动态效果(如点击事件、数据加载),同时可操作DOM修改结构与样式,增强功能性和用户体验1
9.解释什么是语义化的html?
语义化HTML是指通过使用具有明确含义的HTML标签(如<header>、<article>、<section>等)来准确描述网页内容的结构和类型,而非仅依赖<div>、<span>等通用标签结合样式实现布局。
其核心在于用正确的标签表达正确的含义,使代码既能被人类开发者理解,也能被机器(如搜索引擎、屏幕阅读器)高效解析
11.如何实现浏览器多个标签页之间的通信?
1. localStorage/sessionStorage + storage事件
这是最简单的一种跨标签页通信方式:
// 发送消息的标签页
localStorage.setItem('message', JSON.stringify({content: 'Hello from tab 1'}));
// 接收消息的标签页
window.addEventListener('storage', function(event) {
if (event.key === 'message') {
const data = JSON.parse(event.newValue);
console.log('Received message:', data.content);
}
});
特点:
- 同源策略限制(只能在相同域名下的标签页间通信)
- 存储容量有限(通常5MB左右)
- 不会触发当前标签页的storage事件
2. Broadcast Channel API
现代浏览器提供的专用跨标签页通信API:
// 创建或加入频道
const channel = new BroadcastChannel('my_channel');
// 发送消息
channel.postMessage({type: 'update', data: 'Some data'});
// 接收消息
channel.onmessage = function(event) {
console.log('Received:', event.data);
};
// 关闭连接
channel.close();
优势:
- 专门为跨文档通信设计
- 性能优于storage事件
- 支持更复杂的数据类型
3. SharedWorker
使用Web Worker实现的后台通信枢纽:
// 创建SharedWorker
const worker = new SharedWorker('worker.js');
// 发送消息
worker.port.postMessage('Hello from tab');
// 接收消息
worker.port.onmessage = function(event) {
console.log('Message from worker:', event.data);
};
// worker.js内容
const connections = [];
onconnect = function(e) {
const port = e.ports[0];
connections.push(port);
port.onmessage = function(e) {
connections.forEach(conn => {
if (conn !== port) conn.postMessage(e.data);
});
};
};
适用场景:
- 需要持久化通信
- 复杂的消息路由需求
- 大量数据交换
4. Service Worker + postMessage
利用Service Worker作为消息中转站:
// 页面代码
navigator.serviceWorker.controller.postMessage({
type: 'broadcast',
data: 'Message content'
});
// Service Worker代码
self.addEventListener('message', event => {
if (event.data.type === 'broadcast') {
self.clients.matchAll().then(clients => {
clients.forEach(client => {
client.postMessage(event.data);
});
});
}
});
// 接收消息的页面
navigator.serviceWorker.onmessage = event => {
console.log('Received:', event.data);
};
特点:
- 需要HTTPS或localhost环境
- 适合PWA应用
- 可以控制离线行为
5. WebSocket服务器
通过后端服务器中转消息:
// 所有标签页连接到同一个WebSocket服务器
const socket = new WebSocket('wss://example.com/ws');
// 发送消息
socket.send(JSON.stringify({
type: 'tab-communication',
data: 'Message content'
}));
// 接收消息
socket.onmessage = event => {
const data = JSON.parse(event.data);
if (data.type === 'tab-communication') {
console.log('Message from other tab:', data);
}
};
优势:
- 跨浏览器、跨设备通信
- 实时性强
- 不受同源策略限制
选择建议
- 对于简单的同源标签页通信,优先考虑
localStorage + storage事件 - 现代应用推荐使用
Broadcast Channel API - 复杂场景考虑
SharedWorker或Service Worker - 需要跨设备通信时使用
WebSocket方案
在实际应用中,可以根据具体需求组合使用这些技术,例如使用Broadcast Channel进行简单通信,同时使用WebSocket实现更复杂的消息路由。
12.http 的状态码有哪些?
1xx 信息类
- 100 Continue(继续)
- 101 Switching Protocols(切换协议)
2xx 成功类
- 200 OK(成功)
- 201 Created(已创建)
- 202 Accepted(已接受)
- 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(服务不可用)
- 504 Gateway Timeout(网关超时)
14.简述什么叫优雅降级和渐进增强?
优雅降级(Graceful Degradation)
优雅降级是一种设计策略,指的是网站在现代浏览器中提供完整功能,同时确保在老式浏览器或设备上仍能保持基本可用性。其核心思想是从复杂功能开始,然后为不支持的浏览器提供降级方案。
主要特点:
- 开发时首先针对高级浏览器实现完整功能
- 通过特性检测为老旧浏览器提供简化版本
- 保证所有用户都能获得可用的体验,只是功能丰富程度不同
典型应用场景:
- 使用CSS3动画时,为不支持浏览器提供静态替代方案
- 现代JavaScript功能不可用时显示基本表单
- 复杂布局在旧浏览器中降级为线性布局
实现步骤: (1) 开发完整功能版本 (2) 检测浏览器支持情况 (3) 为不支持的情况准备替代方案 (4) 确保核心功能在所有环境下都能工作
渐进增强(Progressive Enhancement)
渐进增强是另一种设计理念,强调从基础体验开始构建,然后逐步为支持新特性的浏览器添加增强功能。这种方法确保所有用户都能获得核心体验,而现代浏览器用户则能享受更丰富的交互。
主要特点:
- 从语义化HTML开始构建
- 分层添加CSS和JavaScript增强
- 确保基础功能不依赖高级特性
- 更符合Web标准的发展趋势
典型应用场景:
- 首先构建可访问的HTML结构
- 添加CSS改善视觉效果
- 使用JavaScript增加交互功能
- 为支持WebGL的浏览器添加3D效果
实现步骤: (1) 开发基础HTML结构和内容 (2) 添加基本样式保证可读性 (3) 实施增强的CSS布局和效果 (4) 加入JavaScript交互层
两者对比
| 维度 | 优雅降级 | 渐进增强 |
|---|---|---|
| 出发点 | 完整功能 | 基础体验 |
| 开发流程 | 先复杂后简化 | 先简单后增强 |
| 关注点 | 处理兼容性问题 | 构建可扩展架构 |
| 适用场景 | 现有项目维护 | 新项目开发 |
现代Web开发中,渐进增强被认为是更可持续的做法,因为它更符合Web标准的本质,同时能更好地适应新兴设备和浏览器特性。
15.解释什么是盒子模型?
盒子模型(Box Model)是CSS中用于描述网页元素布局的核心机制,它将每个HTML元素视为一个由四层结构组成的矩形盒子12。这四层从内到外依次为:
- 内容区(Content):显示实际文本、图像等元素内容,尺寸由
width和height属性控制。 - 内边距(Padding):内容与边框之间的透明缓冲区域,用于控制内容与边框的间距。
- 边框(Border):包裹内容和内边距的可见边界线,可设置样式、宽度和颜色。
- 外边距(Margin):元素与其他元素之间的透明间隔区,用于控制元素间距。
盒子模型的两种类型
-
标准盒子模型(Standard Box Model)
- 元素的
width和height仅包含内容区尺寸,不包含内边距和边框24。 - 总宽度计算公式:
width + padding-left/right + border-left/right + margin-left/right。
- 元素的
-
IE盒子模型(怪异盒子模型)
- 元素的
width和height包含内容区、内边距和边框24。 - 可通过
box-sizing: border-box切换为标准盒子模型
- 元素的
16.解释前端px 和em 的区别?
px (像素):
- 是 CSS 中最基础的绝对长度单位
- 1px 代表屏幕上的一个物理像素点
- 优点:精确控制,在不同设备上表现一致
- 缺点:无法根据用户设置或设备特性进行自适应调整
em:
- 是相对长度单位,基于当前元素的字体大小
- 1em 等于当前元素的字体大小(继承自父元素)
- 优点:具有继承性和可扩展性,适合响应式设计
- 缺点:计算复杂,容易出现嵌套问题
具体差异对比
-
计算方式不同:
- px:固定值,不随其他因素变化
- em:相对于当前元素的 font-size 计算
-
继承特性:
- px:无继承性,子元素需要单独设置
- em:具有继承性,子元素会基于父元素的 font-size 计算
-
响应式表现:
- px:在不同设备上大小固定
- em:会根据浏览器默认字体大小或用户设置自动调整
使用场景示例
px 适用场景:
- 边框宽度(border)
- 固定尺寸的图片
- 需要精确控制位置和大小的元素
.button {
width: 120px; /* 固定宽度 */
padding: 10px; /* 固定内边距 */
}
em 适用场景:
- 段落间距
- 行高(line-height)
- 响应式布局中的间距和尺寸
.article {
font-size: 16px;
line-height: 1.5em; /* 24px (16×1.5) */
margin-bottom: 2em; /* 32px (16×2) */
}
注意事项
-
em 的嵌套问题: 当 em 单位嵌套使用时,计算会基于最近的父元素的 font-size,可能导致意外的放大或缩小效果。
-
rem 作为替代方案: 现代前端开发中,rem (root em) 单位逐渐流行,它始终基于根元素(html)的字体大小计算,避免了 em 的嵌套问题。
-
浏览器默认值: 大多数浏览器默认字体大小为 16px,这是 em 计算的基础参考值。
17.xml 和json 的区别?
1. 基本概念
XML (eXtensible Markup Language):
- 是一种标记语言,使用标签来定义数据结构
- 源自 SGML (Standard Generalized Markup Language)
- 设计初衷是存储和传输数据,同时兼具可读性
- 示例:
<person><name>John</name><age>30</age></person>
JSON (JavaScript Object Notation):
- 是一种轻量级的数据交换格式
- 源于 JavaScript 的对象表示法
- 设计目标是易于人阅读和编写,也易于机器解析和生成
- 示例:
{"person": {"name": "John", "age": 30}}
2. 语法结构差异
XML 特点:
- 使用开始和结束标签,如
<tag></tag> - 标签名称区分大小写
- 属性值必须用引号包围
- 必须有根元素
- 支持注释
<!-- 注释内容 --> - 支持 CDATA 区块
<![CDATA[内容]]>
JSON 特点:
- 使用键值对表示数据
- 数据由逗号分隔
- 花括号保存对象
{} - 方括号保存数组
[] - 不支持注释
- 键名必须用双引号括起来
- 值可以是字符串、数字、布尔值、数组、对象或 null
3. 数据类型支持
XML:
- 所有数据都以文本形式存储
- 需要通过 DTD 或 XML Schema 定义数据类型
- 需要额外的解析来转换数据类型
JSON:
- 原生支持基本数据类型:
- 字符串(必须双引号)
- 数字(整数或浮点数)
- 布尔值(true/false)
- 数组(有序列表)
- 对象(无序键值对集合)
- null(空值)
4. 可读性和简洁性
XML:
- 标签结构使得可读性较好
- 但冗余度高(重复的标签名)
- 文件体积通常较大
- 示例对比:
<employees> <employee> <id>1</id> <name>John</name> </employee> </employees>
JSON:
- 语法更简洁,数据密度更高
- 对开发者更友好
- 相同数据的 JSON 表示:
{ "employees": [ { "id": 1, "name": "John" } ] }
5. 处理性能
XML:
- 解析较复杂,需要专门的 XML 解析器
- DOM 解析会将整个文档加载到内存
- SAX 解析是事件驱动的,内存占用较小
- 解析速度通常比 JSON 慢
JSON:
- 解析简单,大多数编程语言都有原生支持
- 可以直接映射到编程语言的数据结构
- 解析速度更快
- 内存占用更小
6. 扩展性和验证
XML:
- 支持通过 DTD 或 XML Schema 定义文档结构
- 可以进行严格的验证
- 支持命名空间,避免元素名冲突
- 适合需要严格数据格式的场景
JSON:
- 没有内置的验证机制
- 可以使用 JSON Schema 进行验证(但非原生支持)
- 扩展性较差
- 适合灵活的数据交换场景
7. 典型应用场景
XML 适用场景:
- 需要文档标记的场合(如 XHTML)
- 需要严格验证和复杂结构的配置
- Web 服务(SOAP)
- 文档存储和交换(如 Office Open XML)
- 需要注释和元数据的场景
JSON 适用场景:
- Web API 数据交换(RESTful 服务)
- 前后端数据传输
- NoSQL 数据库(如 MongoDB)
- 配置文件(如 package.json)
- 移动应用数据交换
8. 安全性考虑
XML:
- 容易受到 XML 注入攻击
- 需要防范 XXE (XML External Entity) 攻击
- 解析器需要配置安全选项
JSON:
- 可能受到 JSON 注入攻击
- 需要防范 JSONP 劫持
- 使用
eval()解析 JSON 有安全隐患(应使用JSON.parse())
9. 互操作性
XML:
- 几乎所有编程语言都有成熟的 XML 处理库
- 有统一的 W3C 标准
- 工具链成熟(XSLT、XPath 等)
JSON:
- 现代编程语言都原生支持
- 在 Web 领域已成为事实标准
- 工具支持不如 XML 丰富
10. 发展趋势
- 在 Web 领域,JSON 已逐渐取代 XML 成为主流数据交换格式
- XML 在需要严格验证、文档标记和企业级应用中仍有优势
- JSON 因其简洁性和性能优势,在新兴领域更受欢迎
- 一些系统同时支持 XML 和 JSON(如某些 REST API)
18.web worker 和websoket 的含义解释?
Web Worker
Web Worker 是 HTML5 提供的一种在后台线程中运行 JavaScript 的技术,它允许开发者在主线程之外创建额外的线程来执行脚本,从而避免长时间运行的脚本阻塞页面渲染和用户交互。
主要特点:
- 独立线程运行:Web Worker 运行在与主页面线程分离的后台线程中
- 不阻塞UI:计算密集型任务不会影响页面的响应性
- 通信机制:通过 postMessage API 与主线程进行数据交换
- 受限访问:不能直接操作DOM、window对象或document对象
应用场景:
- 图像处理(如滤镜应用、图片压缩)
- 大数据计算(如统计分析、复杂算法)
- 实时数据解析(如日志处理、格式转换)
- 其他CPU密集型任务
示例代码:
// 主线程
const worker = new Worker('worker.js');
worker.postMessage('开始计算');
worker.onmessage = function(e) {
console.log('收到结果:', e.data);
};
// worker.js
self.onmessage = function(e) {
const result = heavyComputation(e.data);
self.postMessage(result);
};
WebSocket
WebSocket 是 HTML5 提供的一种在单个TCP连接上进行全双工通信的协议,它使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。
主要特点:
- 全双工通信:客户端和服务器可以同时发送和接收数据
- 持久连接:建立连接后保持打开状态,避免重复握手
- 低延迟:相比HTTP轮询,大大减少了通信延迟
- 轻量级:数据帧头较小,传输效率高
应用场景:
- 实时聊天应用
- 多人协作编辑工具
- 股票行情实时更新
- 在线游戏状态同步
- 实时监控系统
协议特点:
- 使用ws://(非加密)或wss://(加密)协议
- 握手阶段使用HTTP协议,之后升级为WebSocket协议
- 默认端口与HTTP相同(ws:80, wss:443)
示例代码:
// 客户端
const socket = new WebSocket('wss://example.com/socket');
socket.onopen = function() {
socket.send('Hello Server!');
};
socket.onmessage = function(event) {
console.log('收到消息:', event.data);
};
socket.onclose = function() {
console.log('连接已关闭');
};
两者区别
| 特性 | Web Worker | WebSocket |
|---|---|---|
| 主要用途 | 后台计算,避免阻塞UI | 实时双向网络通信 |
| 通信对象 | 主线程与Worker线程之间 | 客户端与服务器之间 |
| 运行环境 | 浏览器内部的独立线程 | 基于TCP的网络协议 |
| 数据交换 | 通过postMessage/onmessage API | 通过send/onmessage API |
| 典型应用 | 图像处理、大数据计算 | 聊天应用、实时数据推送 |
19.简述对前端模块化的认识?
1. 前端模块化的概念
前端模块化是指将复杂的JavaScript代码拆分成独立的、可复用的模块,每个模块专注于特定功能的实现。模块化开发解决了传统前端开发中存在的全局变量污染、命名冲突、代码依赖混乱等问题。
2. 模块化的发展历程
早期方案
- IIFE(立即执行函数表达式):通过闭包隔离作用域
- 命名空间模式:将代码组织在特定对象下
- CommonJS:Node.js采用的模块规范(require/exports)
现代方案
- AMD(Asynchronous Module Definition):RequireJS推广的异步加载规范
- CMD(Common Module Definition):Sea.js推广的规范
- ES6 Modules:JavaScript官方模块标准(import/export)
3. 主流模块规范对比
| 规范 | 加载方式 | 特点 | 典型应用 |
|---|---|---|---|
| CommonJS | 同步加载 | 适合服务端,模块输出的是值的拷贝 | Node.js |
| AMD | 异步加载 | 适合浏览器端,提前执行 | RequireJS |
| CMD | 异步加载 | 按需执行,依赖就近 | Sea.js |
| ES6 | 静态编译 | 静态分析,输出值的引用 | 现代前端项目 |
4. 模块化的优势
- 代码复用:模块可以被多次引用,减少重复代码
- 作用域隔离:每个模块有独立作用域,避免变量污染
- 依赖管理:明确声明依赖关系,便于维护
- 工程化开发:支持按需加载,提高性能
- 团队协作:模块职责清晰,便于多人协作
5. 现代前端构建工具中的模块化
现代前端项目通常结合构建工具处理模块化:
- Webpack:支持CommonJS、AMD、ES6模块等多种规范
- Rollup:专注于ES6模块的打包工具
- Parcel:零配置的模块打包工具
- Vite:基于ESM的下一代前端工具
6. 实际应用场景示例
// ES6模块示例
// utils.js
export function formatDate(date) {
return new Date(date).toLocaleDateString();
}
// app.js
import { formatDate } from './utils.js';
console.log(formatDate('2023-01-01')); // 输出格式化后的日期
7. 发展趋势
随着ES6模块得到广泛支持,前端模块化呈现以下趋势:
- 原生ES模块逐渐成为主流
- 动态import()实现按需加载
- 模块联邦(Micro Frontends)概念的兴起
- 组件化与模块化结合更加紧密
20.简述expire 和 cache-control?
HTTP 缓存头部:Expire 与 Cache-Control 详解
Expire 头部
Expire 是 HTTP/1.0 引入的缓存控制头部,用于指定资源的过期时间。它是一个绝对时间点,告诉浏览器在该时间点之前可以直接使用缓存副本而无需重新请求服务器。
特点:
- 使用 GMT 格式表示时间(例如:Expires: Thu, 01 Dec 2023 16:00:00 GMT)
- 是绝对时间,依赖于客户端和服务器的时钟同步
- 如果客户端时间不准确可能导致缓存失效或持久化过久
- 在 HTTP/1.1 中被 Cache-Control 取代,但为了向后兼容仍然支持
示例场景: 假设今天是 2023 年 11 月 1 日,服务器返回:
Expires: Thu, 01 Dec 2023 16:00:00 GMT
表示该资源在 2023 年 12 月 1 日 16:00 GMT 之前都可以使用缓存。
Cache-Control 头部
Cache-Control 是 HTTP/1.1 引入的更灵活的缓存控制机制,提供多种指令来控制缓存行为。
主要指令:
max-age=<seconds>:资源的最大缓存时间(相对时间)no-cache:要求每次使用缓存前必须验证有效性no-store:禁止缓存任何内容public:表示响应可以被任何缓存存储private:表示响应仅供单个用户缓存,中间代理不能缓存must-revalidate:缓存必须在使用前验证过期资源
优势:
- 使用相对时间,不受客户端和服务器时间差异影响
- 提供更细粒度的控制选项
- 支持多种缓存策略组合
示例场景:
Cache-Control: public, max-age=604800
表示该资源可以被任何缓存(包括 CDN)存储,且有效期为 604800 秒(7 天)。
两者的主要区别
| 特性 | Expire | Cache-Control |
|---|---|---|
| 时间表示 | 绝对时间 | 相对时间 |
| 精度 | 秒级 | 秒级 |
| 兼容性 | HTTP/1.0 | HTTP/1.1 |
| 灵活性 | 单一 | 多指令组合 |
| 时钟依赖 | 是 | 否 |
最佳实践: 现代 Web 应用通常同时使用两者以确保兼容性,Cache-Control 优先级高于 Expire。例如:
Cache-Control: max-age=3600
Expires: Thu, 01 Dec 2023 17:00:00 GMT
23.webstroge 和cookie 的区别?
存储容量
- Cookie:通常限制在 4KB 左右
- Web Storage:
- LocalStorage:一般 5MB-10MB
- SessionStorage:一般 5MB-10MB
生命周期
- Cookie:
- 可设置过期时间(通过
expires或max-age属性) - 若不设置则默认为 会话级别(浏览器关闭时删除)
- 可设置过期时间(通过
- Web Storage:
- LocalStorage:永久存储,需手动清除
- SessionStorage:会话级别(标签页关闭时删除)
与服务器的交互
- Cookie:
- 每次 HTTP 请求都会自动携带(包括图片等静态资源请求)
- 可通过
HttpOnly属性禁止 JavaScript 访问
- Web Storage:
- 仅存储在客户端
- 不会自动随请求发送到服务器
访问方式
- Cookie:
- 通过
document.cookieAPI 访问 - 操作较复杂(需要手动解析字符串)
- 通过
- Web Storage:
- 提供更简单的 API:
localStorage.setItem('key', 'value'); sessionStorage.getItem('key');
- 提供更简单的 API:
应用场景
- Cookie:
- 用户身份验证(如 session ID)
- 跟踪用户行为(需符合隐私法规)
- Web Storage:
- LocalStorage:
- 持久化用户偏好设置(如主题、语言)
- 离线应用数据缓存
- SessionStorage:
- 单次会话的临时数据(如表单填写状态)
- 单页面应用的路由状态
- LocalStorage:
安全性
- Cookie:
- 支持
Secure属性(仅 HTTPS 传输) - 支持
SameSite属性(防止 CSRF 攻击)
- 支持
- Web Storage:
- 易受 XSS 攻击(因为始终可通过 JavaScript 访问)
- 没有内置的安全机制
浏览器支持
- Cookie:所有浏览器(包括非常旧的版本)
- Web Storage:
- 现代浏览器全面支持
- IE7 及以下不支持
存储数据类型
- Cookie:仅能存储字符串
- Web Storage:虽然也存储字符串,但可配合
JSON.stringify()存储复杂数据结构
24.cookie 和session 的区别?
Cookie 和 Session 的区别
基本概念
Cookie 是存储在用户本地终端上的小型文本文件,由服务器发送到浏览器并保存在客户端。当用户再次访问同一网站时,浏览器会将这些 Cookie 发送回服务器。
Session 是服务器端的一种机制,用于在服务器上存储用户的状态信息。每个 Session 都有一个唯一的标识符(Session ID),通常通过 Cookie 或 URL 重写的方式传递给客户端。
主要区别
1. 存储位置
- Cookie:存储在客户端的浏览器中
- Session:存储在服务器端的内存或数据库中
2. 安全性
- Cookie:安全性较低,容易被窃取或篡改
- Session:安全性较高,敏感信息保存在服务器端
3. 存储容量
- Cookie:单个 Cookie 通常不超过4KB,每个域名下 Cookie 数量有限制(通常20个左右)
- Session:理论上没有大小限制,取决于服务器配置
4. 生命周期
- Cookie:
- 可以设置过期时间(持久化 Cookie)
- 浏览器关闭即失效(会话 Cookie)
- Session:
- 通常与用户会话相关,浏览器关闭后可能失效
- 服务器可以设置 Session 超时时间
5. 网络传输
- Cookie:每次请求都会自动附加在 HTTP 头中发送
- Session:只传输 Session ID,实际数据保留在服务器
使用场景示例
Cookie 适用场景:
- 记住用户登录状态(如"记住我"功能)
- 保存用户偏好设置(如语言选择、主题样式)
- 跟踪用户行为(分析用户访问路径)
Session 适用场景:
- 保存敏感信息(如用户ID、权限级别)
- 购物车功能实现
- 多步骤表单数据暂存
- 防CSRF攻击(存储 token)
技术实现示例
Cookie 设置(PHP):
setcookie("username", "john_doe", time()+3600, "/");
Session 使用(PHP):
session_start();
$_SESSION['user_id'] = 12345;
性能考虑
- Cookie:会增加每次请求的传输量,但服务器负担小
- Session:减少网络传输,但会增加服务器内存/数据库负载
安全性建议
- 对于敏感数据,优先使用 Session
- Cookie 应该设置 HttpOnly 和 Secure 标志
- Session ID 应该定期更换
- 考虑使用加密的 Cookie 存储少量非敏感数据
25.简述对前端BFC 的理解?
什么是BFC
BFC(Block Formatting Context,块级格式化上下文)是Web页面的可视化CSS渲染的一部分,是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。BFC可以看作是一个独立的容器,里面的元素不会影响到外面的元素。
BFC的触发条件
以下CSS属性可以触发BFC:
- 根元素(
<html>) float属性不为noneposition属性为absolute或fixeddisplay属性为inline-block、table-cell、table-caption、flex、inline-flex、grid或inline-gridoverflow属性不为visible(常用hidden或auto)
BFC的特性
-
内部盒子垂直排列:在BFC中,块级元素会按照垂直方向一个接一个地放置。
-
外边距折叠:属于同一个BFC的两个相邻块级元素的外边距会发生折叠(margin collapse)。
-
BFC区域不会与浮动元素重叠:BFC可以阻止元素被浮动元素覆盖。
-
计算BFC高度时包含浮动元素:BFC可以包含浮动元素,解决父元素高度塌陷问题。
-
BFC是独立容器:BFC内部的元素不会影响外部元素,反之亦然。
BFC的应用场景
-
清除浮动:通过创建BFC让父元素包含浮动子元素,解决高度塌陷问题。
-
防止外边距重叠:通过在两个相邻元素之间创建一个BFC来防止外边距折叠。
-
自适应两栏布局:利用BFC区域不会与浮动元素重叠的特性,实现两栏自适应布局。
-
阻止元素被浮动元素覆盖:通过创建BFC来避免非浮动元素被浮动元素覆盖。
示例代码
<!-- 清除浮动示例 -->
<div style="overflow: hidden;"> <!-- 创建BFC -->
<div style="float: left;">浮动元素</div>
</div>
<!-- 防止外边距折叠示例 -->
<div style="margin-bottom: 20px;">元素1</div>
<div style="display: inline-block; width: 100%;"> <!-- 创建BFC -->
<div style="margin-top: 20px;">元素2</div>
</div>
<!-- 两栏布局示例 -->
<div style="float: left; width: 200px;">左侧栏</div>
<div style="overflow: hidden;"> <!-- 创建BFC -->
右侧内容区域,自适应宽度
</div>
BFC是CSS布局中一个重要的概念,理解并合理运用BFC可以帮助开发者解决许多常见的布局问题。
26.阐述异步加载和延迟加载?
异步加载 (Async Loading)
异步加载是一种网页性能优化技术,允许浏览器在加载和执行JavaScript文件的同时继续解析HTML文档,而不会阻塞页面渲染过程。
工作原理
- 浏览器遇到带有
async属性的<script>标签时 - 开始异步下载脚本文件
- 下载完成后立即执行脚本
- 执行过程会暂停HTML解析
- 执行完成后恢复HTML解析
特点
- 非阻塞加载:不会阻止HTML文档的解析
- 执行顺序不确定:多个async脚本的执行顺序取决于下载完成时间
- 适合场景:独立脚本、不依赖其他脚本的第三方库(如Google Analytics)
示例代码
<script async src="analytics.js"></script>
<script async src="widget.js"></script>
延迟加载 (Defer Loading)
延迟加载是另一种优化技术,它推迟脚本的执行直到HTML文档完全解析完成。
工作原理
- 浏览器遇到带有
defer属性的<script>标签时 - 开始异步下载脚本文件
- 等待HTML文档完全解析完成
- 按照在文档中出现的顺序依次执行所有延迟脚本
特点
- 非阻塞加载:不会阻止HTML文档的解析
- 执行顺序确定:保持脚本在文档中的声明顺序
- 执行时机:DOMContentLoaded事件之前执行
- 适合场景:需要访问DOM元素但无需立即执行的脚本
示例代码
<script defer src="main.js"></script>
<script defer src="utils.js"></script>
应用场景对比
| 特性 | Async | Defer |
|---|---|---|
| 执行顺序 | 下载完成即执行,顺序不确定 | 文档解析后按声明顺序执行 |
| DOM依赖 | 可能无法访问完整DOM | 可以访问完整DOM |
| 典型应用 | 独立第三方脚本 | 需要操作DOM的脚本 |
最佳实践
- 关键脚本:不使用async或defer,直接内联或正常加载
- 非关键第三方脚本:使用async
- DOM操作脚本:使用defer
- 现代实践:考虑使用
type="module",这会默认defer行为
性能影响
- 使用async/defer可减少约20-50%的页面加载时间
- 首屏渲染时间可提升30%以上
- 特别在移动设备上效果更显著
现代补充方案
除了async/defer,现代前端开发还可以考虑:
- 动态导入:
import()函数实现的代码分割 - 懒加载:Intersection Observer实现的图片/组件延迟加载
- 预加载:
<link rel="preload">提前获取关键资源
28.简述严格模式的限制?
严格模式是ECMAScript 5引入的一种特殊的JavaScript执行模式,通过在脚本或函数顶部添加"use strict";来启用。它改变了JavaScript的某些默认行为,主要限制包括:
变量声明限制
- 所有变量必须显式声明(禁止隐式全局变量)
- 对未声明的变量赋值会抛出
ReferenceError - 例如:
x = 10;在严格模式下会报错,必须写成var x = 10;
对象操作限制
- 禁止删除不可删除的属性(抛出
TypeError) - 对象属性名不能重复(非严格模式下会静默忽略)
- 例如:
var obj = {x:1, x:2};在严格模式下会报语法错误
函数相关限制
- 函数参数名不能重复
arguments对象的行为改变:arguments不再追踪参数变化- 禁止使用
arguments.callee和arguments.caller
- 例如:
function test(a,a){}在严格模式下会报错
this绑定限制
- 全局函数的
this值为undefined(非严格模式下指向全局对象) - 例如:
function f(){ console.log(this); }在严格模式下输出undefined
语法限制
- 禁止使用
with语句 - 禁止八进制字面量(如
0123) eval创建独立作用域,不会在外部作用域引入新变量- 新增保留字(如
interface,let,yield等)不能用作变量名
其他限制
- 禁止对只读属性赋值
- 禁止扩展不可扩展的对象
eval和arguments不能用作变量名或函数名- 禁止删除普通变量(只能删除对象属性)
严格模式通过这些限制帮助开发者编写更安全、更规范的代码,避免常见的编程错误,并为未来JavaScript版本预留语法空间。
29.阐述网络各种协议?
网络协议是计算机网络中进行数据交换而建立的规则、标准或约定的集合。它们定义了通信实体之间交换信息的格式、顺序以及收发动作。现代互联网和计算机网络依赖于多层次的协议体系,每种协议都有其特定的功能和应用场景。
主要网络协议分类
1. 应用层协议
应用层协议直接为用户应用程序提供网络服务:
-
HTTP (Hypertext Transfer Protocol)
- 用于传输超文本的标准协议
- 无状态协议,使用请求/响应模型
- 版本发展:HTTP/1.0 → HTTP/1.1 → HTTP/2 → HTTP/3
- 典型应用:网页浏览
-
HTTPS (HTTP Secure)
- HTTP的安全版本,使用TLS/SSL加密
- 默认端口443
- 提供身份验证和加密通信
-
FTP (File Transfer Protocol)
- 用于文件传输的标准协议
- 使用两个连接:控制连接(21端口)和数据连接(20端口)
- 支持匿名和认证两种访问方式
-
SMTP (Simple Mail Transfer Protocol)
- 电子邮件发送协议
- 使用25端口
- 负责将邮件从发送方传送到接收方邮件服务器
-
POP3/IMAP
- 邮件接收协议
- POP3(110端口)简单下载删除模式
- IMAP(143端口)服务器端管理邮件模式
-
DNS (Domain Name System)
- 域名解析协议
- 将域名转换为IP地址
- 使用UDP协议,端口53
2. 传输层协议
负责端到端的数据传输:
-
TCP (Transmission Control Protocol)
- 面向连接的可靠协议
- 提供流量控制、拥塞控制和错误恢复
- 三次握手建立连接,四次挥手终止连接
- 典型应用:网页浏览、文件传输、电子邮件
-
UDP (User Datagram Protocol)
- 无连接的不可靠协议
- 传输效率高,延迟低
- 无流量控制和错误恢复机制
- 典型应用:视频流、在线游戏、DNS查询
3. 网络层协议
负责数据包的路由和转发:
-
IP (Internet Protocol)
- 核心网络层协议
- 提供无连接的、尽最大努力交付的数据报服务
- 版本:IPv4(32位地址)和IPv6(128位地址)
- 负责寻址和路由功能
-
ICMP (Internet Control Message Protocol)
- 用于传递控制消息
- 支持网络诊断工具如ping和traceroute
- 报告错误和异常情况
-
ARP (Address Resolution Protocol)
- 将IP地址解析为MAC地址
- 工作在局域网内
- 维护ARP缓存表
4. 数据链路层协议
负责相邻节点间的数据传输:
-
以太网协议
- 最常用的局域网技术
- 使用CSMA/CD介质访问控制方法
- 定义帧格式和MAC地址
-
PPP (Point-to-Point Protocol)
- 点对点连接协议
- 常用于拨号上网和广域网连接
- 提供身份认证、压缩和加密功能
-
Wi-Fi协议(IEEE 802.11系列)
- 无线局域网标准
- 包括802.11a/b/g/n/ac/ax等版本
- 使用CSMA/CA介质访问控制方法
协议栈和分层模型
网络协议通常按照OSI七层模型或TCP/IP四层模型进行组织:
-
TCP/IP四层模型:
- 应用层(HTTP, FTP, SMTP等)
- 传输层(TCP, UDP)
- 网络层(IP, ICMP)
- 网络接口层(以太网, Wi-Fi)
-
OSI七层模型:
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层
协议交互示例
以访问网站为例,展示协议协作过程:
- 用户在浏览器输入URL,触发DNS查询(UDP协议)
- 获取服务器IP后,建立TCP连接(三次握手)
- 发送HTTP请求,可能升级为HTTPS(TLS握手)
- 服务器响应HTTP内容
- 浏览器解析渲染页面
- TCP连接关闭(四次挥手)
新兴协议和技术
-
HTTP/3
- 基于QUIC协议开发
- 使用UDP而非TCP作为传输层
- 减少连接建立时间和队头阻塞问题
-
QUIC
- 由Google开发的传输层协议
- 整合TCP和TLS功能
- 提供多路复用和快速连接建立
-
MQTT
- 轻量级发布/订阅消息协议
- 专为物联网设备设计
- 低功耗、低带宽要求
网络协议的不断演进支撑着互联网应用的发展,从基础的网页浏览到实时视频流、物联网等新兴应用,都依赖于这些协议的高效协作。
30.关于web 端iframe有哪些缺点?
主要缺点分析
-
性能问题
- iframe会创建独立的文档对象模型(DOM),导致内存占用增加
- 每个iframe都会发起独立的HTTP请求,增加页面加载时间
- 大量使用iframe可能导致浏览器性能下降,特别是在移动设备上
-
SEO优化困难
- 搜索引擎爬虫难以正确索引iframe中的内容
- iframe内容通常不会被计入主页面SEO价值
- 可能影响网站的整体搜索排名
-
安全性问题
- 容易成为点击劫持(clickjacking)攻击的目标
- 跨域iframe可能带来安全风险
- 难以控制iframe加载的第三方内容安全性
-
用户体验问题
- 浏览器后退按钮行为可能变得不可预测
- 滚动条可能出现嵌套问题
- 移动设备上的响应式设计更难实现
-
开发维护困难
- 样式继承和JavaScript交互复杂
- 难以实现iframe与父页面的通信
- 调试和测试更耗时
典型应用场景与替代方案
-
广告嵌入
- 缺点:可能被广告拦截插件屏蔽
- 替代方案:使用JavaScript API直接加载广告内容
-
第三方内容嵌入
- 缺点:加载速度慢,可能影响主页面性能
- 替代方案:考虑使用Web Components或微前端架构
-
跨域通信
- 缺点:postMessage API使用复杂,可能存在安全漏洞
- 替代方案:考虑使用CORS或JSONP等技术
-
隔离样式和脚本
- 缺点:资源重复加载,代码冗余
- 替代方案:使用CSS作用域技术或Shadow DOM
31.阐述一下 cookie 和localstroge 和 sessionStroge 的区别?
基本概念
Cookie
- 是服务器发送到用户浏览器并保存在本地的小型数据文件
- 每次HTTP请求都会自动携带
- 主要用于身份验证和会话管理
- 存储容量有限(约4KB)
- 可设置过期时间
LocalStorage
- HTML5新增的Web存储API
- 数据永久存储在客户端,除非手动清除
- 存储容量较大(通常5-10MB)
- 仅在客户端使用,不会随HTTP请求发送
- 同源策略限制
SessionStorage
- 也是HTML5的Web存储API
- 数据仅在当前会话期间有效(浏览器标签页关闭即清除)
- 存储容量与LocalStorage相同
- 同样不会随HTTP请求发送
- 同样是同源策略限制
主要区别对比
| 特性 | Cookie | LocalStorage | SessionStorage |
|---|---|---|---|
| 存储容量 | 约4KB | 5-10MB | 5-10MB |
| 生命周期 | 可设置过期时间 | 永久存储 | 会话结束即清除 |
| 是否随请求发送 | 是 | 否 | 否 |
| 访问范围 | 同源窗口 | 同源窗口 | 仅当前标签页 |
| 存储数据类型 | 字符串 | 字符串 | 字符串 |
| API易用性 | document.cookie | setItem/getItem | setItem/getItem |
使用场景示例
Cookie适用场景
- 用户登录状态保持
document.cookie = "username=JohnDoe; expires=Thu, 18 Dec 2025 12:00:00 UTC; path=/"; - 记住用户偏好设置
- 跨页面跟踪用户行为
LocalStorage适用场景
- 保存用户本地偏好
localStorage.setItem('theme', 'dark'); - 缓存应用数据
- 离线应用数据存储
SessionStorage适用场景
- 表单数据临时保存(防止刷新丢失)
sessionStorage.setItem('formData', JSON.stringify(formData)); - 单次会话的临时数据存储
- 敏感信息的临时存储(关闭页面即清除)
安全注意事项
-
Cookie:
- 应设置HttpOnly和Secure标志防止XSS攻击
- 敏感信息应考虑加密
-
Web Storage:
- 不应用于存储敏感信息
- 容易受到XSS攻击
- 应考虑数据加密存储
浏览器兼容性
- Cookie:所有浏览器完全支持
- LocalStorage/SessionStorage:
- IE8+支持
- 主流现代浏览器完全支持
- 移动端浏览器普遍支持
性能考虑
- Cookie因为每次请求都会携带,会影响性能
- Web Storage操作是同步的,大数据量可能阻塞UI
- 对于大量数据操作,建议使用Web Workers或IndexedDB
32.设计中使用了非标准的字体,该如何处理?
设计中非标准字体的处理方法
字体嵌入技术
Web字体嵌入方案
- @font-face规则:使用CSS的@font-face规则来引入非标准字体
@font-face {
font-family: 'MyCustomFont';
src: url('fonts/MyCustomFont.woff2') format('woff2'),
url('fonts/MyCustomFont.woff') format('woff');
}
- Web字体服务:考虑使用Google Fonts、Adobe Fonts或Typekit等专业字体服务
- 字体子集化:通过工具提取字体中实际使用的字符,减少文件大小
文档嵌入方案
- PDF文档:在导出PDF时选择"嵌入字体"选项
- Office文档:在Word/PowerPoint中使用"嵌入字体"功能(文件>选项>保存)
备选方案
字体替代策略
- 指定回退字体栈:在CSS中设置合理的字体回退方案
body {
font-family: 'CustomFont', Arial, sans-serif;
}
- 创建视觉相似的字体组合:寻找与目标字体视觉特征相似的免费/系统字体
图像替换方案
- 关键文本转为图片:对标题等关键元素使用图片
- SVG文本:使用SVG格式保留文本可编辑性同时确保字体显示
33.为什么用多个域名来提供网站资源会更有效?
使用多个域名来提供网站资源(也称为"域名分片")是一种常见的性能优化策略,主要基于以下几个原因:
- 浏览器并行下载限制
- 现代浏览器对单个域名有并发连接数限制(通常为6-8个)
- 使用多个域名可以绕过这个限制,实现更多资源并行下载
- 示例:将图片、CSS、JS等资源分别放在static1.example.com和static2.example.com
- CDN加速优化
- 不同域名可以指向不同的CDN节点
- 根据用户地理位置选择最优CDN资源
- 典型应用:视频网站常用video1.example.com、video2.example.com等子域名
- Cookie隔离
- 主域名下的请求会自动携带所有Cookie
- 使用独立资源域名可以避免传输不必要的Cookie数据
- 最佳实践:使用与主域名无关的cookie-free域名(如cdn.example.net)
- 资源分类管理
- 按资源类型划分域名(如img.example.com、js.example.com)
- 便于实施不同的缓存策略和安全策略
- 运维优势:可以独立扩展特定类型的资源服务器
- HTTP/2的影响
- 虽然HTTP/2的多路复用减少了域名分片的需求
- 但在高延迟网络环境下仍有一定优势
- 兼容性考虑:需要同时支持HTTP/1.1的用户
实施建议:
- 通常使用2-4个子域名即可获得最佳效果
- 过多域名会导致DNS查询开销增加
- 现代方案:结合HTTP/2和智能域名分配策略
注意:随着网络技术的发展,这个策略的效果会有所变化,需要根据实际网络环境和用户设备情况进行测试和调整。
34.解释什么是FOUC (无样式闪烁),如何避免?
什么是FOUC
FOUC (Flash of Unstyled Content) 即"无样式闪烁",是指网页在加载过程中,浏览器在完全加载CSS样式表之前短暂显示未应用样式的HTML内容的现象。这种闪烁通常持续几毫秒到几秒钟不等,表现为:
- 内容突然从无样式状态变为有样式状态
- 字体、颜色、间距等样式属性突然变化
- 布局发生明显跳变
FOUC产生的原因
-
CSS加载顺序问题:当CSS文件放在页面底部或通过JavaScript异步加载时,浏览器会先渲染HTML内容,然后才应用CSS样式
-
渲染阻塞:浏览器遇到
<script>标签时会暂停渲染,直到脚本执行完毕 -
@import规则:使用@import引入CSS会导致额外的网络请求,延迟样式应用
-
大型样式表:过大的CSS文件需要更长的加载和解析时间
避免FOUC的方法
1. 优化CSS加载顺序
- 将
<link>标签放在<head>中
<head>
<link rel="stylesheet" href="styles.css">
</head>
2. 使用内联关键CSS
- 将首屏关键CSS直接内联在HTML中
<style>
/* 关键CSS代码 */
body { font-family: Arial; }
.header { background: #333; }
</style>
3. 预加载CSS
- 使用
rel="preload"提示浏览器提前加载CSS
<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
4. 避免@import
- 直接使用
<link>标签替代@import
<!-- 避免 -->
<style>
@import url('styles.css');
</style>
<!-- 推荐 -->
<link rel="stylesheet" href="styles.css">
5. 使用媒体查询优化
- 为非关键CSS添加媒体查询,异步加载
<link rel="stylesheet" href="print.css" media="print" onload="this.media='all'">
6. 脚本加载优化
- 将JavaScript放在页面底部或使用
async/defer属性
<script src="app.js" defer></script>
7. 服务器端渲染(SSR)
- 服务端直接生成带有样式的HTML,避免客户端闪烁
实际应用场景
-
电商网站:产品图片和价格在样式加载前错位,影响用户体验和转化率
-
新闻网站:文章内容先以系统默认字体显示,然后突然变为自定义字体
-
单页应用(SPA):路由切换时可能出现的短暂无样式状态
通过以上方法可以有效减少或消除FOUC现象,提升页面的视觉稳定性和用户体验。
35.浏览器标准模式和怪异模式的区别?
浏览器渲染模式主要分为标准模式(Standards Mode)和怪异模式(Quirks Mode),这两种模式在页面渲染行为上存在显著差异。
主要区别
1. 文档类型声明(Doctype)
- 标准模式:需要有完整的DOCTYPE声明,如:
<!DOCTYPE html> - 怪异模式:当文档缺少DOCTYPE声明或使用旧的HTML版本声明时触发
2. 盒模型计算方式
-
标准模式:
- 使用W3C盒模型
- width = 内容宽度
- 元素总宽度 = width + padding + border + margin
-
怪异模式:
- 使用IE5.5及更早版本的盒模型
- width = 内容宽度 + padding + border
- 元素总宽度 = width + margin
3. 行内元素垂直对齐
- 标准模式:严格遵循CSS规范
- 怪异模式:可能采用浏览器特有的对齐方式
4. 表格单元格高度计算
- 标准模式:遵循CSS2.1规范
- 怪异模式:可能采用IE的传统计算方式
其他差异
-
字体大小:
- 标准模式:1em = 16px(默认)
- 怪异模式:可能使用不同的基准值
-
百分比高度:
- 标准模式:需要明确容器高度
- 怪异模式:可能自动计算某些情况下的百分比高度
-
JavaScript特性:
- 标准模式:严格遵循ECMAScript规范
- 怪异模式:可能保留旧浏览器的非标准行为
现代实践
现代网页开发应始终使用标准模式,可以通过以下方式确保:
- 使用HTML5的简洁DOCTYPE声明
- 避免使用过时的HTML标签和属性
- 遵循最新的Web标准进行开发
检查当前模式
开发者可以通过以下JavaScript代码检查当前页面所处的模式:
if (document.compatMode === "CSS1Compat") {
console.log("标准模式");
} else {
console.log("怪异模式");
}
36.如何网页需要支持多语言,怎么去做?
完整实现时建议采用i18n库(如i18next)简化开发流程,其提供语言检测、插值、复数处理等高级功能,可大幅降低维护成本
37.简述svg 样式?
SVG 样式可以通过以下方式设置:
- 内联样式:直接在 SVG 元素中使用
style属性
<rect style="fill: blue; stroke: red; stroke-width: 2"/>
- CSS 样式表:通过外部或内部 CSS 定义样式
rect {
fill: green;
stroke: black;
}
- 属性样式:使用 SVG 原生属性
<circle fill="yellow" stroke="purple" stroke-width="3"/>
支持常见的 CSS 属性如:
fill:填充颜色stroke:描边颜色stroke-width:描边宽度opacity:透明度
CSS 样式优先级:内联样式 > 内部样式表 > 外部样式表 > 默认样式
38.解释一下盒模型的,以及如何在css 中告诉浏览器使用不同的盒模型来渲染你的布局
CSS 盒模型详解
盒模型是CSS布局的基础概念,它定义了网页元素在页面中的呈现方式。每个HTML元素都可以看作是一个矩形的盒子,这个盒子由以下部分组成:
- 内容区(Content): 包含元素的实际内容,如文本、图片等
- 内边距(Padding): 内容区与边框之间的透明区域
- 边框(Border): 围绕内边距和内容的边界
- 外边距(Margin): 盒子与其他元素之间的透明间距
盒模型类型
CSS提供了两种主要的盒模型计算方式:
-
标准盒模型(content-box):
- 默认模式
- 元素的总宽度 = width + padding + border
- 元素的总高度 = height + padding + border
-
替代盒模型(border-box):
- 更直观的布局方式
- 元素的width/height直接指定了包括border和padding在内的总尺寸
- 内边距和边框不会增加元素的总尺寸
设置盒模型
通过box-sizing属性可以指定浏览器使用哪种盒模型:
/* 使用标准盒模型 */
.element {
box-sizing: content-box;
}
/* 使用替代盒模型 */
.element {
box-sizing: border-box;
}
/* 全局设置替代盒模型 */
* {
box-sizing: border-box;
}
现代网页开发中,通常会在CSS重置时全局设置border-box模型,这能简化布局计算并提高开发效率。
39.简述一个url 从输入到渲染出页面,都发生了什么?
1. 用户输入与URL解析
当用户在浏览器地址栏输入URL后,浏览器会首先解析URL结构,将其拆分为协议(如HTTP/HTTPS)、主机名、端口号、路径等组成部分。现代浏览器还会通过DNS预取技术提前解析可能访问的域名。
2. DNS解析与缓存检查
浏览器会依次检查本地缓存、操作系统缓存、路由器缓存,若未命中则向本地DNS服务器发起递归查询,最终获取目标域名的IP地址。若为HTTPS协议,还需建立TLS加密连接。
3. TCP连接建立
通过三次握手与服务器建立TCP连接,确保可靠通信。若服务器返回301/302状态码,浏览器会重定向到新地址。
4. 请求发送与响应处理
浏览器构造包含请求方法(GET/POST)、头部和主体的HTTP请求发送至服务器。服务器处理请求后返回响应,包含状态码(如200)、响应头和响应体。
5. 资源解析与渲染
浏览器根据响应内容类型(如HTML)启动渲染进程:
- DOM树构建:解析HTML标签生成DOM树
- CSSOM构建:解析CSS样式表形成样式树
- 布局计算:结合DOM和CSSOM计算元素位置和尺寸
- 绘制:将布局结果转换为屏幕像素
- JavaScript执行:动态修改DOM和样式实现交互效果
6. 资源加载与页面完成
解析过程中发现的子资源(JS/CSS/图片等)会触发额外HTTP请求。所有资源加载完成后,页面进入可交互状态
40.简述同步和异步的区别?
- 执行方式:
- 同步:任务按顺序依次执行,前一个任务完成才能开始下一个
- 异步:任务可以并行或交叉执行,无需等待前一个任务完成
- 控制流程:
- 同步:程序执行流程明确,代码顺序就是执行顺序
- 异步:执行顺序不确定,可能通过回调、事件或消息机制触发
- 性能表现:
- 同步:容易造成阻塞,资源利用率较低
- 异步:能提高系统吞吐量,但增加了编程复杂度
- 典型应用:
- 同步:简单的线性业务流程
- 异步:耗时操作、I/O密集型任务或需要高并发的场景
41.简述完整的http 事务是一个什么过程?
- 客户端建立 TCP 连接(通常通过三次握手完成)
- 客户端发送 HTTP 请求报文
- 服务器接收并处理请求
- 服务器返回 HTTP 响应报文
- 客户端接收并处理响应
- 根据 Connection 头字段决定是否关闭 TCP 连接
在 HTTP/1.1 中通常会保持连接复用(Keep-Alive),而 HTTP/2 则支持多路复用,可以同时处理多个请求/响应。整个过程遵循请求-响应模式,是无状态的协议交互。
42.阐述AMD 和 commonjs 的理解?
AMD(Asynchronous Module Definition)和CommonJS是两种主流的JavaScript模块化规范:
-
AMD:
- 采用异步加载机制,适合浏览器环境
- 通过define()定义模块,require()加载模块
- 典型实现是RequireJS
- 优势:模块并行加载,不阻塞页面渲染
-
CommonJS:
- 采用同步加载方式,主要用于Node.js环境
- 通过module.exports导出模块,require()导入模块
- 特点:模块加载是同步的,适合服务端场景
- 每个文件即是一个模块,具有独立作用域
主要区别:
- 加载方式:AMD异步 vs CommonJS同步
- 使用场景:AMD侧重浏览器端,CommonJS侧重服务端
- 语法差异:AMD需封装define(),CommonJS更简洁
43.web 应用从服务器主动推送data到客户端有哪些方式?
Web 应用中服务器向客户端主动推送数据的常见方式包括:
-
WebSocket
全双工通信协议,建立持久连接后服务器可随时推送数据 -
Server-Sent Events (SSE)
基于 HTTP 的单向推送机制,适合服务器到客户端的持续数据流 -
长轮询 (Long Polling)
客户端发起请求后,服务器保持连接直到有新数据才响应 -
HTTP/2 Server Push
服务器可主动推送资源,但主要用于预加载而非实时数据 -
Web Push API
通过浏览器推送服务实现离线消息推送,需配合 Service Worker -
MQTT over WebSocket
轻量级发布/订阅协议,适合物联网等场景 -
Comet
基于长连接的推送技术集合,包括隐藏 iframe 等实现方式 -
WebRTC 数据通道
支持点对点实时数据传输,但需要建立连接过程
每种方案各有优劣,需根据实时性要求、浏览器兼容性、开发复杂度等具体需求选择。
44.阐述cookie 的弊端?
1. 隐私泄露风险
Cookie可能被第三方追踪,记录用户的浏览历史、购物习惯等敏感信息,用于构建用户画像或定向广告推送。若网站未遵守隐私法规,数据可能被转卖甚至用于诈骗。例如访问显卡官网后电商平台立即推送相关产品,即追踪Cookie的作用。
2. 安全威胁
- 明文传输风险:Cookie默认以明文存储和传输,易被中间人攻击截获登录凭证。
- XSS攻击:恶意脚本可通过
document.cookie窃取Cookie数据。 - CSRF攻击:攻击者伪造请求利用用户Cookie执行非授权操作。
- 会话劫持:窃取会话ID或Cookie可直接冒充用户身份。
3. 存储与性能限制
- 数量限制:单个域名下通常仅允许20-50个Cookie。
- 大小限制:每个Cookie不超过4KB,超长内容会被截断。
- 性能影响:每次HTTP请求自动携带Cookie,增加带宽消耗。
4. 功能局限性
- 数据类型单一:仅支持字符串存储,复杂数据需JSON序列化。
- 跨域限制:受同源策略约束,无法跨域名共享数据。
5. 合规与用户体验问题
-
隐私合规:需遵循GDPR等法规明确告知用户数据用途。
-
广告轰炸:过度追踪行为可能导致用户反感。
应对策略建议
- 安全设置:启用
HttpOnly、Secure属性,强制HTTPS传输。 - 数据精简:避免存储敏感信息,使用服务器端Session管理关键数据。
- 替代方案:对复杂数据采用JWT等Token机制,或使用
localStorage
45.阐述Etag的概念和应用?
概念解析: ETag(实体标签)是 HTTP 协议提供的资源标识机制,由服务器为每个资源生成唯一字符串标识。其核心作用在于标识资源内容版本,当资源变更时 ETag 值随之改变。
工作原理:
- 首次请求时,服务器在响应头返回 ETag
- 后续请求中,客户端通过 If-None-Match 头携带该 ETag
- 服务器比对 ETag 判断资源是否变更,决定返回 304 或新内容典型应用场景:
- 缓存验证:与 Last-Modified 配合实现高效缓存策略
- 条件请求:确保并发修改的一致性(配合 If-Match 头)
- 断点续传:支持大文件分块传输的场景
技术优势:
- 比时间戳更精准:能识别内容级别的变更
- 支持弱验证:通过 W/ 前缀标识内容语义变更
- 降低带宽消耗:避免传输未修改的资源
实现注意事项:
- 建议采用哈希算法生成高辨识度 ETag
- 需确保集群环境下 ETag 生成的一致性
- 动态资源需考虑计算开销与实效性的平衡
46.网站伪静态和静态的区别?网站为什么要做静态url?
-
内容生成方式
- 静态网站:由预先生成的HTML文件直接返回,无需服务器端处理。
- 伪静态网站:通过URL重写技术(如Apache的
mod_rewrite)将动态URL伪装成静态路径(如/news/1.html),实际内容仍由后端动态生成。
-
资源消耗
- 静态网站仅需读取文件,服务器负载极低。
- 伪静态需额外处理URL重写规则,且每次请求仍可能触发数据库查询,CPU占用较高。
-
访问速度
- 静态网站响应最快(10-50ms),适合CDN缓存。
- 伪静态速度依赖后端处理效率,若未缓存则可能延迟(50-200ms)。
-
SEO与用户体验
- 静态URL(如
/product.html)更易被搜索引擎抓取,且用户友好。 - 伪静态通过隐藏动态参数(如
?id=123)提升SEO效果,但需服务器支持。
- 静态URL(如
网站采用静态URL的主要原因
-
SEO优化
- 静态URL结构清晰(如
/seo-guide.html),含关键词时更易被搜索引擎识别。 - 避免动态URL中的参数(如
?id=123&cat=1)导致重复内容问题。
- 静态URL结构清晰(如
-
性能与稳定性
- 静态文件直接返回,无数据库查询压力,可承载更高并发。
- 伪静态在高流量下可能因CPU过载崩溃(如300人访问即挂载)。
-
用户体验
- 静态URL简洁易记,便于用户输入和分享。
- 动态URL参数复杂,可能被用户视为不专业。
-
安全与维护
- 静态网站无服务器端脚本,减少SQL注入等攻击风险。
- 伪静态需依赖服务器配置,维护成本较高。
技术选型建议
- 内容固定(如企业官网):优先选择纯静态站点。
- 需动态更新(如博客):伪静态+缓存插件(如WordPress。
- 高并发场景:避免伪静态,改用静态化生成或CDN加速
48.web-garden 和 web-farm 的区别?
Web-Garden 和 Web-Farm 的区别
Web-Garden
指在单个服务器上运行多个应用程序实例(通常通过多个工作进程实现)。这些实例共享服务器的硬件资源,但能提高应用程序的并发处理能力。适用于中小型应用或需要提升单服务器性能的场景。
Web-Farm
指在多台物理服务器上部署应用程序副本,通过负载均衡器分发请求。这种方式能显著提升系统的可用性和扩展性,适合高流量、高可用性要求的大型应用。
主要区别
-
部署规模
- Web-Garden:单台服务器
- Web-Farm:多台服务器集群
-
资源隔离
- Web-Garden:进程级隔离,共享硬件
- Web-Farm:完全物理隔离
-
适用场景
- Web-Garden:快速提升单机处理能力
- Web-Farm:构建分布式高可用系统
1366

被折叠的 条评论
为什么被折叠?



