文章目录一、CDN1. CDN 的系统架构2. CDN 的核心作用3. CDN 工作原理从 DNS 开始传统访问 vs CDN 访问流程关键术语CNAME4. 典型应用场景二、懒加载 (Lazy Load) 与 预加载 (Preload)1. 懒加载 (Lazy Load) —— 按需分配核心价值实现原理与公式代码实战 (原生 JS)2. 预加载 (Preload)核心价值常用实现方式3. 深度对比懒加载 vs 预加载三、回流与重绘1. 回流与重绘的核心概念1. 回流 (Reflow / Layout)2. 重绘 (Repaint)2. 如何高效规避回流与重绘四、防抖与节流核心概念对比原理解析防抖 (Debounce)节流 (Throttle)五、图片优化1. 资源替代方案2. 传输与大小控制3. 常见图片格式深度对比与选型六、Webpack 性能优化1. 如何提升构建速度优化Loader 的文件搜索与转换范围利用多核 CPU并行化预编译与外部化2. 如何减小打包体积剔除冗余代码策略性拆分3. Webpack 3/4 vs Webpack 5一、CDN1. CDN 的系统架构一个完善的 CDN 系统通常由三个核心子系统协同工作分发服务系统Cache 层核心单元边缘 Cache 设备职责直接响应用户请求缓存本地内容并与源站保持同步。其服务能力由设备规模和总带宽决定负载均衡系统调度层两级调度分为GSLB全局负载均衡和SLB本地负载均衡职责根据用户的地理位置、运营商、节点负载等因素确定最优的 Cache 服务器 IP运营管理系统支撑层职责处理业务层面的统计、计费、客户管理及网络监控2. CDN 的核心作用性能提升低延迟用户从最近的数据中心获取内容减轻源站压力大量请求被边缘节点拦截降低了源站服务器的负载安全防御防御 DDoS通过边缘节点的流量分析限制异常请求避免源站崩溃防止 MITM中间人攻击支持全链路 HTTPS 加密按需扩展应对突发流量高峰如电商促销实现资源的弹性扩容3. CDN 工作原理从 DNS 开始CDN 与 DNS 系统紧密结合通过CNAME别名记录实现流量调度传统访问 vs CDN 访问流程步骤传统方式无 CDNCDN 方式DNS 解析获取源站主机的 IP获取CNAME指向的 CDN 专用 DNS IP寻址结果直接得到服务器 IP得到经过 GSLB 计算后的边缘节点 IP请求过程浏览器直连源服务器浏览器连接最近的 Cache 缓存服务器缺损处理服务器直接返回数据缓存缺失时由 Cache 节点向上级或源站发起回源请求关键术语CNAMECNAME别名记录它不直接映射 IP而是将一个域名指向另一个域名。CDN 正是利用这一点将你的网站域名“重定向”到 CDN 服务商的调度系统。4. 典型应用场景静态资源缓存将.js、.css、图片等不常变动的资源托管到 CDN实现首屏秒开流媒体/直播传送对于普通文件节点缺失会“回源”查找对于大体积的流媒体通常采用**主动推送Push**技术将内容提前下发到边缘节点保证播放不卡顿全站加速配合 SSL 证书托管实现全链路的快速、安全分发二、懒加载 (Lazy Load) 与 预加载 (Preload)1. 懒加载 (Lazy Load) —— 按需分配懒加载指的是在长网页中延迟加载非可视区域的资源直到用户滚动到该位置时才触发请求核心价值节省流量避免加载用户从未看过的图片首屏加速减少首屏 HTTP 请求数让核心内容更快呈现减轻服务器压力并发请求数降低提升整体吞吐量实现原理与公式懒加载的关键在于判断元素是否进入了浏览器可视窗口逻辑判断公式img.offsetTop window.innerHeight document.documentElement.scrollTopoffsetTop元素距离文档顶部的距离innerHeight可视窗口的高度scrollTop页面滚动的距离代码实战 (原生 JS)通过data-src存储真实路径滚动时动态替换srcfunctionlazyLoad(){constimgsdocument.querySelectorAll(img[data-src]);constviewHeightwindow.innerHeight;constscrollTopdocument.documentElement.scrollTop||document.body.scrollTop;imgs.forEach(img{// 判断图片是否进入可视区if(img.offsetTopviewHeightscrollTop){img.srcimg.dataset.src;// 加载后移除自定义属性避免重复处理img.removeAttribute(data-src);}});}// 监听滚动事件建议加节流函数优化window.addEventListener(scroll,lazyLoad);2. 预加载 (Preload)预加载指的是将所需的资源图片、脚本、字体等提前请求加载到本地缓存当真正需要用到时直接从缓存获取核心价值零等待体验用户点击或切换时资源瞬间加载解决闪烁防止字体或大图在渲染时出现明显的白块或跳动常用实现方式HTML 标签link relpreload hrefstyle.css asstyleJS 对象letimgnewImage();img.srcheavy-photo.jpg;// 浏览器会自动开始下载并存入缓存3. 深度对比懒加载 vs 预加载特性懒加载预加载加载时机滞后进入可视区再加载提前空闲或初始化时加载对服务器压力缓解压力减少并发增加压力可能加载无用资源主要目的优化首屏性能和流量提升后续交互的流畅度适用场景电商长列表、图片流游戏素材、大图背景、字体文件三、回流与重绘1. 回流与重绘的核心概念1. 回流 (Reflow / Layout)本质重新计算布局。当渲染树Render Tree中元素的尺寸、结构或几何属性发生变化时浏览器需要重新计算元素在设备视口内的确切位置和大小。由于浏览器采用流式布局一个节点的改变往往会引起其子节点、兄弟节点甚至整个页面的重新计算常见触发场景改变宽/高、修改边距、增删 DOM 节点、修改字体大小、窗口缩放、获取布局属性如offsetTop、getComputedStyle2. 重绘 (Repaint)本质重新像素填充。当元素的样式发生变化但不影响其在文档流中的位置和几何尺寸时例如改变背景颜色、文字颜色、阴影等浏览器会将受影响的像素点重新绘制到屏幕上重要规律回流必引起重绘但重绘不一定引起回流2. 如何高效规避回流与重绘频繁的触发会导致页面卡顿丢帧。我们可以通过以下策略进行优化操作DOM时尽量在低层级的DOM节点进行操作不要使用table布局 一个小的改动可能会使整个table进行重新布局使用CSS的表达式不要频繁操作元素的样式对于静态页面可以修改类名而不是样式使用absolute或者fixed使元素脱离文档流这样他们发生变化就不会影响其他元素避免频繁操作DOM可以创建一个文档片段documentFragment在它上面应用所有DOM操作最后再把它添加到文档中将元素先设置display: none操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘将DOM的多个读操作或者写操作放在一起而不是读写操作穿插着写。这得益于浏览器的渲染队列机制四、防抖与节流核心概念对比特性防抖 (Debounce)节流 (Throttle)形象比喻“电梯等待”最后一个人进来后等n nn秒再走中途有人进就重新等。“红绿灯/水龙头”固定每隔n nn秒放行一次不管中途积压了多少。执行逻辑连续触发事件时只执行最后一次。连续触发事件时按固定频率执行。重置机制每次触发都会重置计时器。计时器运行期间忽略新的触发。应用痛点按钮多次点击、搜索框输入校验Input、窗口缩放Resize。页面滚动Scroll、抢购点击、拖拽移动MouseMove。原理解析防抖 (Debounce)防抖的核心在于**“清空旧的开启新的”**如果用户操作很快短于等待时间之前的计时器会被clearTimeout杀掉只有最后一次操作能活到计时结束并执行函数节流 (Throttle)节流的核心在于**“锁状态”**时间戳版对比当前时间与上次执行时间的差值。优点是立即执行第一次触发就会运行定时器版通过判断timer是否为空来决定是否开启新的任务。优点是尾随执行停止触发后还会最后执行一次五、图片优化优化图片的本质是减少 HTTP 请求次数减小单个文件体积提升感知加载速度1. 资源替代方案CSS 代替修饰图圆角、渐变、阴影、几何图形等完全可以用 CSS 实现零网络请求SVG 代替位图对于 Icon、Logo、简单插画SVG矢量图具有无限放大不失真和体积极小的优势Iconfont字体图标将多个图标打包成字体文件通过 CSS 控制颜色和大小2. 传输与大小控制响应式加载 (Responsive Images)利用 CDN 动态裁剪功能根据用户设备的devicePixelRatio和屏幕宽度返回对应尺寸的图避免在手机端加载 4K 原图。Base64 内联对于 2KB 以下的小图可以使用 Base64 编码内联在 CSS 或 HTML 中减少一次 HTTP 往返延迟RTT。v雪碧图 (CSS Sprites)在 HTTP/1.1 时代非常重要将多个图标拼成一张大图减少 TCP 连接开销HTTP/2 下优先级降低。3. 常见图片格式深度对比与选型理解不同格式的原理才能在“清晰度”与“体积”之间找到最佳平衡点格式类型特点适用场景JPEG有损/点阵色彩丰富不支持透明照片、复杂背景图PNG-8无损/索引色体积小支持透明仅 256 色简单 Logo、色彩单一的插图PNG-24无损/直接色高保真完美透明体积大需要半透明效果的高质素材GIF无损/索引色支持动画仅 256 色简单动图复杂动图建议用 MP4SVG无损/矢量XML 格式无限放大不失真Logo、Icon、扁平化插画WebP混合/直接色谷歌推出体积比 JPEG/PNG 小 30%现代浏览器首选格式六、Webpack 性能优化Webpack 优化的本质是在开发阶段减少不必要的重复工作在生产阶段剔除不必要的冗余代码1. 如何提升构建速度优化Loader 的文件搜索与转换范围Loader 精度控制使用include包含业务代码如src使用exclude排除三方库如node_modules开启缓存给babel-loader加上cacheDirectorytrue利用多核 CPU并行化HappyPackWebpack 3/4 时代的利器将单线程的 Loader 转换变为多线程thread-loaderWebpack 5 时代的官方推荐原理类似放置在开销大的 Loader 之前即可预编译与外部化DllPlugin将不常变动的框架React/Vue预先打包成静态文件构建时直接引用跳过编译externals直接使用 CDN 引入资源不让 Webpack 处理这些庞大的类库2. 如何减小打包体积剔除冗余代码Tree Shaking基于 ES Module在生产模式production下自动开启。它能像摇晃树木一样把没用到的函数死代码从最终包里摇掉Scope Hoisting作用域提升将分散的模块函数合并到一个作用域中减少函数声明开销和内存占用策略性拆分Code Splitting代码分割路由按需加载通过import()动态导入实现页面级别的 JS 拆分首页只加载首页需要的代码SplitChunksPlugin将多个入口公用的代码抽离成单独的vendor.js利用浏览器缓存3. Webpack 3/4 vs Webpack 5很多手段如 HappyPack, DllPlugin在旧版项目中非常有效但 Webpack 5 已经内置了更高效的替代方案优化点Webpack 3/4 常用Webpack 5 推荐持久化缓存cache-loader内置filesystem缓存极其强大多线程HappyPackthread-loader压缩代码UglifyJS内置TerserPlugin支持多进程并行类库加速DllPlugin物理缓存性能提升DllPlugin 优先级降低
前端性能优化面试题
文章目录一、CDN1. CDN 的系统架构2. CDN 的核心作用3. CDN 工作原理从 DNS 开始传统访问 vs CDN 访问流程关键术语CNAME4. 典型应用场景二、懒加载 (Lazy Load) 与 预加载 (Preload)1. 懒加载 (Lazy Load) —— 按需分配核心价值实现原理与公式代码实战 (原生 JS)2. 预加载 (Preload)核心价值常用实现方式3. 深度对比懒加载 vs 预加载三、回流与重绘1. 回流与重绘的核心概念1. 回流 (Reflow / Layout)2. 重绘 (Repaint)2. 如何高效规避回流与重绘四、防抖与节流核心概念对比原理解析防抖 (Debounce)节流 (Throttle)五、图片优化1. 资源替代方案2. 传输与大小控制3. 常见图片格式深度对比与选型六、Webpack 性能优化1. 如何提升构建速度优化Loader 的文件搜索与转换范围利用多核 CPU并行化预编译与外部化2. 如何减小打包体积剔除冗余代码策略性拆分3. Webpack 3/4 vs Webpack 5一、CDN1. CDN 的系统架构一个完善的 CDN 系统通常由三个核心子系统协同工作分发服务系统Cache 层核心单元边缘 Cache 设备职责直接响应用户请求缓存本地内容并与源站保持同步。其服务能力由设备规模和总带宽决定负载均衡系统调度层两级调度分为GSLB全局负载均衡和SLB本地负载均衡职责根据用户的地理位置、运营商、节点负载等因素确定最优的 Cache 服务器 IP运营管理系统支撑层职责处理业务层面的统计、计费、客户管理及网络监控2. CDN 的核心作用性能提升低延迟用户从最近的数据中心获取内容减轻源站压力大量请求被边缘节点拦截降低了源站服务器的负载安全防御防御 DDoS通过边缘节点的流量分析限制异常请求避免源站崩溃防止 MITM中间人攻击支持全链路 HTTPS 加密按需扩展应对突发流量高峰如电商促销实现资源的弹性扩容3. CDN 工作原理从 DNS 开始CDN 与 DNS 系统紧密结合通过CNAME别名记录实现流量调度传统访问 vs CDN 访问流程步骤传统方式无 CDNCDN 方式DNS 解析获取源站主机的 IP获取CNAME指向的 CDN 专用 DNS IP寻址结果直接得到服务器 IP得到经过 GSLB 计算后的边缘节点 IP请求过程浏览器直连源服务器浏览器连接最近的 Cache 缓存服务器缺损处理服务器直接返回数据缓存缺失时由 Cache 节点向上级或源站发起回源请求关键术语CNAMECNAME别名记录它不直接映射 IP而是将一个域名指向另一个域名。CDN 正是利用这一点将你的网站域名“重定向”到 CDN 服务商的调度系统。4. 典型应用场景静态资源缓存将.js、.css、图片等不常变动的资源托管到 CDN实现首屏秒开流媒体/直播传送对于普通文件节点缺失会“回源”查找对于大体积的流媒体通常采用**主动推送Push**技术将内容提前下发到边缘节点保证播放不卡顿全站加速配合 SSL 证书托管实现全链路的快速、安全分发二、懒加载 (Lazy Load) 与 预加载 (Preload)1. 懒加载 (Lazy Load) —— 按需分配懒加载指的是在长网页中延迟加载非可视区域的资源直到用户滚动到该位置时才触发请求核心价值节省流量避免加载用户从未看过的图片首屏加速减少首屏 HTTP 请求数让核心内容更快呈现减轻服务器压力并发请求数降低提升整体吞吐量实现原理与公式懒加载的关键在于判断元素是否进入了浏览器可视窗口逻辑判断公式img.offsetTop window.innerHeight document.documentElement.scrollTopoffsetTop元素距离文档顶部的距离innerHeight可视窗口的高度scrollTop页面滚动的距离代码实战 (原生 JS)通过data-src存储真实路径滚动时动态替换srcfunctionlazyLoad(){constimgsdocument.querySelectorAll(img[data-src]);constviewHeightwindow.innerHeight;constscrollTopdocument.documentElement.scrollTop||document.body.scrollTop;imgs.forEach(img{// 判断图片是否进入可视区if(img.offsetTopviewHeightscrollTop){img.srcimg.dataset.src;// 加载后移除自定义属性避免重复处理img.removeAttribute(data-src);}});}// 监听滚动事件建议加节流函数优化window.addEventListener(scroll,lazyLoad);2. 预加载 (Preload)预加载指的是将所需的资源图片、脚本、字体等提前请求加载到本地缓存当真正需要用到时直接从缓存获取核心价值零等待体验用户点击或切换时资源瞬间加载解决闪烁防止字体或大图在渲染时出现明显的白块或跳动常用实现方式HTML 标签link relpreload hrefstyle.css asstyleJS 对象letimgnewImage();img.srcheavy-photo.jpg;// 浏览器会自动开始下载并存入缓存3. 深度对比懒加载 vs 预加载特性懒加载预加载加载时机滞后进入可视区再加载提前空闲或初始化时加载对服务器压力缓解压力减少并发增加压力可能加载无用资源主要目的优化首屏性能和流量提升后续交互的流畅度适用场景电商长列表、图片流游戏素材、大图背景、字体文件三、回流与重绘1. 回流与重绘的核心概念1. 回流 (Reflow / Layout)本质重新计算布局。当渲染树Render Tree中元素的尺寸、结构或几何属性发生变化时浏览器需要重新计算元素在设备视口内的确切位置和大小。由于浏览器采用流式布局一个节点的改变往往会引起其子节点、兄弟节点甚至整个页面的重新计算常见触发场景改变宽/高、修改边距、增删 DOM 节点、修改字体大小、窗口缩放、获取布局属性如offsetTop、getComputedStyle2. 重绘 (Repaint)本质重新像素填充。当元素的样式发生变化但不影响其在文档流中的位置和几何尺寸时例如改变背景颜色、文字颜色、阴影等浏览器会将受影响的像素点重新绘制到屏幕上重要规律回流必引起重绘但重绘不一定引起回流2. 如何高效规避回流与重绘频繁的触发会导致页面卡顿丢帧。我们可以通过以下策略进行优化操作DOM时尽量在低层级的DOM节点进行操作不要使用table布局 一个小的改动可能会使整个table进行重新布局使用CSS的表达式不要频繁操作元素的样式对于静态页面可以修改类名而不是样式使用absolute或者fixed使元素脱离文档流这样他们发生变化就不会影响其他元素避免频繁操作DOM可以创建一个文档片段documentFragment在它上面应用所有DOM操作最后再把它添加到文档中将元素先设置display: none操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘将DOM的多个读操作或者写操作放在一起而不是读写操作穿插着写。这得益于浏览器的渲染队列机制四、防抖与节流核心概念对比特性防抖 (Debounce)节流 (Throttle)形象比喻“电梯等待”最后一个人进来后等n nn秒再走中途有人进就重新等。“红绿灯/水龙头”固定每隔n nn秒放行一次不管中途积压了多少。执行逻辑连续触发事件时只执行最后一次。连续触发事件时按固定频率执行。重置机制每次触发都会重置计时器。计时器运行期间忽略新的触发。应用痛点按钮多次点击、搜索框输入校验Input、窗口缩放Resize。页面滚动Scroll、抢购点击、拖拽移动MouseMove。原理解析防抖 (Debounce)防抖的核心在于**“清空旧的开启新的”**如果用户操作很快短于等待时间之前的计时器会被clearTimeout杀掉只有最后一次操作能活到计时结束并执行函数节流 (Throttle)节流的核心在于**“锁状态”**时间戳版对比当前时间与上次执行时间的差值。优点是立即执行第一次触发就会运行定时器版通过判断timer是否为空来决定是否开启新的任务。优点是尾随执行停止触发后还会最后执行一次五、图片优化优化图片的本质是减少 HTTP 请求次数减小单个文件体积提升感知加载速度1. 资源替代方案CSS 代替修饰图圆角、渐变、阴影、几何图形等完全可以用 CSS 实现零网络请求SVG 代替位图对于 Icon、Logo、简单插画SVG矢量图具有无限放大不失真和体积极小的优势Iconfont字体图标将多个图标打包成字体文件通过 CSS 控制颜色和大小2. 传输与大小控制响应式加载 (Responsive Images)利用 CDN 动态裁剪功能根据用户设备的devicePixelRatio和屏幕宽度返回对应尺寸的图避免在手机端加载 4K 原图。Base64 内联对于 2KB 以下的小图可以使用 Base64 编码内联在 CSS 或 HTML 中减少一次 HTTP 往返延迟RTT。v雪碧图 (CSS Sprites)在 HTTP/1.1 时代非常重要将多个图标拼成一张大图减少 TCP 连接开销HTTP/2 下优先级降低。3. 常见图片格式深度对比与选型理解不同格式的原理才能在“清晰度”与“体积”之间找到最佳平衡点格式类型特点适用场景JPEG有损/点阵色彩丰富不支持透明照片、复杂背景图PNG-8无损/索引色体积小支持透明仅 256 色简单 Logo、色彩单一的插图PNG-24无损/直接色高保真完美透明体积大需要半透明效果的高质素材GIF无损/索引色支持动画仅 256 色简单动图复杂动图建议用 MP4SVG无损/矢量XML 格式无限放大不失真Logo、Icon、扁平化插画WebP混合/直接色谷歌推出体积比 JPEG/PNG 小 30%现代浏览器首选格式六、Webpack 性能优化Webpack 优化的本质是在开发阶段减少不必要的重复工作在生产阶段剔除不必要的冗余代码1. 如何提升构建速度优化Loader 的文件搜索与转换范围Loader 精度控制使用include包含业务代码如src使用exclude排除三方库如node_modules开启缓存给babel-loader加上cacheDirectorytrue利用多核 CPU并行化HappyPackWebpack 3/4 时代的利器将单线程的 Loader 转换变为多线程thread-loaderWebpack 5 时代的官方推荐原理类似放置在开销大的 Loader 之前即可预编译与外部化DllPlugin将不常变动的框架React/Vue预先打包成静态文件构建时直接引用跳过编译externals直接使用 CDN 引入资源不让 Webpack 处理这些庞大的类库2. 如何减小打包体积剔除冗余代码Tree Shaking基于 ES Module在生产模式production下自动开启。它能像摇晃树木一样把没用到的函数死代码从最终包里摇掉Scope Hoisting作用域提升将分散的模块函数合并到一个作用域中减少函数声明开销和内存占用策略性拆分Code Splitting代码分割路由按需加载通过import()动态导入实现页面级别的 JS 拆分首页只加载首页需要的代码SplitChunksPlugin将多个入口公用的代码抽离成单独的vendor.js利用浏览器缓存3. Webpack 3/4 vs Webpack 5很多手段如 HappyPack, DllPlugin在旧版项目中非常有效但 Webpack 5 已经内置了更高效的替代方案优化点Webpack 3/4 常用Webpack 5 推荐持久化缓存cache-loader内置filesystem缓存极其强大多线程HappyPackthread-loader压缩代码UglifyJS内置TerserPlugin支持多进程并行类库加速DllPlugin物理缓存性能提升DllPlugin 优先级降低