前端性能优化原理与实践
2021-03-17 09:05:52 512 举报
AI智能生成
前端性能
作者其他创作
大纲/内容
从输入 URL 到页面加载完成,发生了什么
DNS 解析
TCP 连接
HTTP 请求
HTTP 响应
浏览器解析
网络层面
请求过程的优化
HTTP请求优化
构建工具性能优化
webpack
优化点
减少打包体积
减少构建时间
构建过程提速
loader
在loader中配置 include/exclude
开启缓存,将转译结果缓存至文件系统
plguin
webpack.DllPlugin
HappyPack
构建结果体积压缩
plguin
包组成可视化工具(webpack-bundle-analyzer)
删除冗余代码
Tree-Shaking
sideEffect
Code-Splitting
webpack需要配置
业务代码需要修改
Gzip压缩原理
如何做
图片优化
前置知识:二进制位数与色彩的关系
JPEG/JPG
关键字
有损压缩、体积小、加载快、不支持透明
优点
缺点
不支持透明度处理
当它处理矢量图形和 Logo 等线条感较强、颜色对比强烈的图像时,人为压缩导致的图片模糊会相当明显
场景: 复杂的、色彩层次丰富的图片
大的背景图
轮播图
Banner 图
PNG
关键字
无损压缩、质量高、体积大、支持透明
优点
是一种无损压缩的高保真的图片格式
分类
PNG-8
为了规避体积的问题,我们一般不用PNG去处理较复杂的图像
PNG-24
追求最佳的显示效果、并且不在意文件体积大小时,是推荐使用 PNG-24
场景: 小的 Logo、颜色简单且对比强烈的图片或背景等
小的 Logo,如:淘宝的logo
颜色简单且对比强烈的图片或背景等
SVG
关键字
文本文件、体积小、不失真、兼容性好
优点
SVG 与 PNG 和 JPG 相比,文件体积更小,可压缩性更强
最显著的优势还是在于图片可无限放大而不失真
SVG 是文本文件。我们既可以像写代码一样定义 SVG,灵活性较强
缺点
渲染成本比较高
SVG 存在着其它图片格式所没有的学习成本(它是可编程的)
场景
将 SVG 写入 HTML
将 SVG 写入独立文件后引入 HTML
iconfont-阿里巴巴矢量图标库
Base64
关键字
文本文件、依赖编码、小图标解决方案
前置知识
雪碧图(CSS Sprites)
别名
雪碧图、CSS 精灵、CSS Sprites、图像精灵
含义
一种将小图标和背景图像合并到一张图片上,然后利用 CSS 的背景定位来显示其中的每一部分的技术
MDN文档
优点
相较于一个小图标一个图像文件,单独一张图片所需的 HTTP 请求更少,对内存和带宽更加友好
Base64 和雪碧图一样,是作为小图标解决方案而存在的
Base64 图片的出现,也是为了减少加载网页图片时对服务器的请求次数,从而提升网页性能。Base64 是作为雪碧图的补充而存在的
Base64 图片的出现,也是为了减少加载网页图片时对服务器的请求次数,从而提升网页性能。Base64 是作为雪碧图的补充而存在的
含义
Base64 是一种用于传输 8Bit 字节码的编码方式,通过对图片进行 Base64 编码,我们可以直接将编码结果写入 HTML 或者写入 CSS,从而减少 HTTP 请求的次数
优点
缺点
Base64 编码后,图片大小会膨胀为原文件的 4/3(这是由 Base64 的编码原理决定的)。
如果把大图也编码到 HTML 或 CSS 文件中,后者的体积会明显增加,即便我们减少了 HTTP 请求,也无法弥补这庞大的体积带来的性能开销,得不偿失
如果把大图也编码到 HTML 或 CSS 文件中,后者的体积会明显增加,即便我们减少了 HTTP 请求,也无法弥补这庞大的体积带来的性能开销,得不偿失
场景(满足以下条件可以使用Base64)
图片的实际尺寸很小
图片无法以雪碧图的形式与其它小图结合(合成雪碧图仍是主要的减少 HTTP 请求的途径,Base64 是雪碧图的补充)
图片的更新频率非常低(不需我们重复编码和修改文件内容,维护成本较低)
Base64 编码工具推荐
webpack 的 url-loader
它除了具备基本的 Base64 转码能力,还可以结合文件大小,帮我们判断图片是否有必要进行 Base64 编码
WebP
关键字
年轻的全能型选手
是什么
Google 专为 Web 开发的一种旨在加快图片加载速度的图片格式,它支持有损压缩和无损压缩
优点
像 PNG 一样支持透明
GIF 一样可以显示动态图片
像 JPEG 一样处理细节丰富的图片
缺点
太年轻,兼容性不好,只有Chrome完全支持
场景
限制我们使用 WebP 的最大问题不是“这个图片是否适合用 WebP 呈现”的问题,而是“浏览器是否允许 WebP”的问题,即我们上文谈到的兼容性问题。
具体来说,一旦我们选择了 WebP,就要考虑在 Safari 等浏览器下它无法显示的问题,也就是说我们需要准备 PlanB,准备降级方案。
具体来说,一旦我们选择了 WebP,就要考虑在 Safari 等浏览器下它无法显示的问题,也就是说我们需要准备 PlanB,准备降级方案。
如何做
程序会根据浏览器的型号、以及该型号是否支持 WebP 这些信息来决定当前浏览器显示的是 .webp 后缀还是 .jpg 后缀
在浏览器环境支持 WebP 的情况下,优先使用 WebP 格式,否则就把图片降级为 JPG 格式(本质是对图片的链接地址作简单的字符串切割)
CDN
how
静态资源部署到CDN,并且不与主域名在同一个域下,
可以避免每次请求都携带cookie
what
离用户较近的静态服务器,
用户访问网站时,首先会访问到CDN,如果CDN存在资源,则直接返回,如果不存在,则取根服务器的资源,再通过转发给用户,同时在CDN上资源备份
减少网络请求
本地存储(存储篇)
Cookie
劣势
Cookie 最大只能有 4KB。超过 4KB 时,会被裁剪
过量的 Cookie 会带来巨大的性能浪费
作用
Cookie 说白了就是一个存储在浏览器里的一个小小的文本文件,它附着在 HTTP 请求上,在浏览器和服务器之间“飞来飞去”。
它可以携带用户信息,当服务器检查 Cookie 的时候,便可以获取到客户端的状态。
它可以携带用户信息,当服务器检查 Cookie 的时候,便可以获取到客户端的状态。
WEB Storage
特点
存储容量大: Web Storage 根据浏览器的不同,存储容量可以达到 5-10M 之间
仅位于浏览器端,不与服务端发生通信
分类
Local Storage
含义
Local Storage 是持久化的本地存储,存储在其中的数据是永远不会过期的,使其消失的唯一办法是手动删除
场景
考虑到 Local Storage 的特点之一是持久,有时我们更倾向于用它来存储一些内容稳定的资源。
比如图片内容丰富的电商网站会用它来存储 Base64 格式的图片字符串
比如图片内容丰富的电商网站会用它来存储 Base64 格式的图片字符串
存储一些不经常更新的 CSS、JS 等静态资源
Session Storage
含义
Session Storage 是临时性的本地存储,它是会话级别的存储,当会话结束(页面被关闭)时,存储内容也随之被释放
特点
Session Storage 特别的一点在于,即便是相同域名下的两个页面,只要它们不在同一个浏览器窗口中打开,那么它们的 Session Storage 内容便无法共享
场景
存储本次会话的浏览足迹
缺点
大规模的、结构复杂的数据时,无法胜任
IndexedDB
what
运行在浏览器上的非关系型数据库
不仅可以存储字符串,还可以存储二进制数据
mdn文档
场景
当数据的复杂度和规模上升到了 LocalStorage 无法解决的程度,我们毫无疑问可以请出 IndexedDB 来帮忙
浏览器的缓存机制
离线存储技术
PWA
渲染层面
服务端渲染的探索与实践
前置知识
客户端渲染
是什么
浏览器执行JS来生成相应DOM,
特点
页面上呈现的内容,在 html 源文件里里找不到
服务端渲染
含义
当用户第一次请求页面时,由服务器把需要的组件或页面渲染成 HTML 字符串,然后把它返回给客户端。
客户端拿到手的,是可以直接渲染然后呈现给用户的 HTML 内容,不需要为了生成 DOM 内容自己再去跑一遍 JS 代码。
客户端拿到手的,是可以直接渲染然后呈现给用户的 HTML 内容,不需要为了生成 DOM 内容自己再去跑一遍 JS 代码。
特点
页面上呈现的内容,我们在 html 源文件里也能找到
本质
服务端渲染本质上是本该浏览器做的事情,分担给服务器去做
缺点
提高了服务器压力,吃CPU,内存等资源,提高成本
是什么”(服务端渲染的运行机制)
为什么”(服务端渲染解决了什么性能问题 )
提升首屏加载速度
有利于SEO优化
怎么做”(服务端渲染的应用实例与使用场景)
如何做
React
Vue
场景
浏览器的渲染机制解析
前置知识
浏览器
引擎
渲染引擎
JS引擎
内核
Blink(Chrome、Opera)
Gecko(火狐)
Webkit(Safari)
Trident(IE)
渲染过程
前置知识
一
HTML 解释器:
将 HTML 文档经过词法分析输出 DOM 树
CSS 解释器:
解析 CSS 文档, 生成样式规则
图层布局计算模块:
布局计算每个对象的精确位置和大小
视图绘制模块:
进行具体节点的图像绘制,将像素渲染到屏幕上
JavaScript 引擎:
编译执行 Javascript 代码
二
DOM 树
CSSOM 树
布局渲染树
绘制渲染树
流程
解析HTML
计算样式
计算图层布局
绘制图层
整合图层 得到页面
CSS性能方案
前置知识
CSS 引擎查找样式表,对每条规则都按从右到左的顺序去匹配
CSS 会阻塞渲染
如果不阻塞可能导致页面布局等混乱
CSS选择器方案
避免使用通配符,只对需要用到的元素进行选择
关注可以通过继承实现的属性,避免重复匹配重复定义
少用标签选择器。如果可以,用类选择器替代
不要画蛇添足,id 和 class 选择器不应该被多余的标签选择器拖后腿
减少嵌套。后代选择器的开销是最高的,因此我们应该尽量将选择器的深度降到最低(最高不要超过三层),尽可能使用类来关联每一个标签元素
CSS引入位置方案
早: 将 CSS 放在 head 标签里
快: 启用 CDN 实现静态资源加载速度的优化
JS性能方案
前置知识
JS会阻塞渲染
如果阻止可能导致界面交互混乱
JS加载方案-放在HTML文档最后
<script src="index.js"></script>
<script async src="index.js"></script>
当脚本与 DOM 元素和其它脚本之间的依赖关系不强时使用
<script defer src="index.js"></script>
当脚本依赖于 DOM 元素和其它脚本的执行结果时使用
DOM优化
前置知识
DOM 为什么这么慢
JS引擎通过 "桥接接口" 与渲染引擎 联系
对 DOM 的修改引发样式的更迭
回流
重绘
如何使 DOM 变快
减少 DOM 操作:少交“过路费”、避免过度渲染
如:使用 DocumentFragment 来渲染非常多的元素
原理与基本思路
事件循环(Event Loop)与异步更新
前置知识
微任务
process.nextTick
Promise
MutationObserver
....
宏任务
setTimeout
setInterval
setImmediate
script(整体代码)
I/O 操作、UI 渲染
宏任务/微任务执行顺序
如何优化
更新 DOM 的时间点,应该尽可能靠近渲染的时机。当我们需要在异步任务中实现 DOM 修改时,把它包装成 micro 任务是相对明智的选择。
回流(Reflow)与重绘(Repaint)
哪些实际操作会导致回流与重绘
改变 DOM 元素的几何属性
width、height、padding、margin、left、top、border......
改变 DOM 树的结构
节点的增减、移动等操作
获取一些特定属性的值
offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight
getComputedStyle 方法
IE 里的 currentStyle
如何规避回流与重绘
将计算结果缓存起来
避免逐条改变样式,使用类名去合并样式
将 DOM “离线”
首屏渲染提速
懒加载
经典面试题
懒加载(Lazy-Load )
作用
针对图片加载时机的优化
含义
事件节流与防抖
背景
本质
这两个东西都以闭包的形式存在。
它们通过对事件对应的回调函数进行包裹、以自由变量的形式缓存时间信息,最后用 setTimeout 来控制事件的触发频率。
它们通过对事件对应的回调函数进行包裹、以自由变量的形式缓存时间信息,最后用 setTimeout 来控制事件的触发频率。
节流(throttle)
思想
在某段时间内,不管你触发了多少次回调,我都只认第一次,并在计时结束时给予响应
场景
每当用户触发了一次 scroll 事件,我们就为这个触发操作开启计时器。
一段时间内,后续所有的 scroll 事件——它们无法触发新的 scroll 回调。
直到“一段时间”到了,第一次触发的 scroll 事件对应的回调才会执行,而“一段时间内”触发的后续的 scroll 回调都会被节流阀无视掉
一段时间内,后续所有的 scroll 事件——它们无法触发新的 scroll 回调。
直到“一段时间”到了,第一次触发的 scroll 事件对应的回调才会执行,而“一段时间内”触发的后续的 scroll 回调都会被节流阀无视掉
面试题: 手写代码实现
防抖(debounce)
思想
我会等你到底。在某段时间内,不管你触发了多少次回调,我都只认最后一次
缺点
如果用户的操作十分频繁——他每次都不等 debounce 设置的 delay 时间结束就进行下一次操作,
于是每次 debounce 都为该用户重新生成定时器,回调函数被延迟了不计其数次。
频繁的延迟会导致用户迟迟得不到响应,用户同样会产生“这个页面卡死了”的观感。
于是每次 debounce 都为该用户重新生成定时器,回调函数被延迟了不计其数次。
频繁的延迟会导致用户迟迟得不到响应,用户同样会产生“这个页面卡死了”的观感。
面试题: 手写代码实现
用 Throttle 来优化 Debounce
思想
我们需要借力 throttle 的思想,打造一个“有底线”的 debounce——等你可以,
但我有我的原则:delay 时间内,我可以为你重新生成定时器;
但只要delay的时间到了,我必须要给用户一个响应
但我有我的原则:delay 时间内,我可以为你重新生成定时器;
但只要delay的时间到了,我必须要给用户一个响应
性能监测
可视化工具
Performance
LightHouse
W3C性能API
0 条评论
下一页