Webcourse/13-前端面试/02-性能优化/前端性能优化(一):静态资源优化.md

371 lines
12 KiB
JavaScript
Raw Normal View History

2020-12-15 21:34:51 +08:00
## 图片格式和应用场景
### JPEG 格式
JPEGJoint Photographic Experts Group是一种针对彩色照片而广泛使用的有损压缩图形格式属于位图
常用文件扩展名为`.jpg`也有 `.jpeg``.jpe`JPEG 在互联网上常被应用于存储和传输照片
- 适合颜色丰富的照片彩色图大焦点图通栏 banner 结构不规则的图形
- 不适合线条图形和文字图标图形因为它的压缩算法不太这些类型的图形并且不支持透明度
### PNG 格式
PNGPortable Network Graphics是一种无损压缩的位图图形格式支持索引灰度RGB 三种颜色方案以及 Alpha 通道等特性
PNG 最初是作为替代 GIF 来设计的能够显示 256 文件比 JPEG 或者 GIF 但是 PNG 非常好的保留了图像质量支持 Alpha 通道的半透明和透明特性最高支持 24 位彩色图像PNG-24 8 位灰度图像PNG-8
- 适合纯色**透明**线条绘图图标边缘清晰有大块相同颜色区域需要带**半透明**的图片
- 适合由于是无损存储所以不太适合体积太大的彩色图像
比如说如果你需要带透明背景的图片此时就可以用 png 格式的图
### GIF 格式
GIFGraphics Interchange Format是一种位图图形格式 8 位色 256 种颜色重现真彩色的图像采用 LZW 压缩算法进行编码
支持 256 仅支持完全透明和完全不透明如果需要带动画效果的图片GIF 是比较通用的选择
- 适合动画图标
- 不适合每个像素只有 8 比特不适合存储彩色图片
### Webp 格式
Webp 是一种现代图像格式可为图像提供无损压缩和有损压缩这使得它非常灵活 Google 在购买 On2 Technologies 后发展出来 BSD 授权条款发布
Webp的优秀算法能同时保证图像质量和较小体积可以插入多帧实现动画效果可以设置透明度采用 8 位压缩算法
无损的 Webp PNG 26%有损的 Webp JPEG 25-34 GIF 有更好的动画
- 适合适用于图形和半透明图像
### 总结
- banner图大图可以用 jpgwebp格式
- 图标带透明背景的图可以用 png 格式
- 带动画效果的图可以用 gif 格式
## 图片优化的常见方法
### 1用工具压缩图片
**压缩 PNG 图片**
- 工具[node-pngquant-native](https://www.npmjs.com/package/node-pngquant-native)
- 介绍跨平台压缩比特别高压缩png24非常好
安装方法
```
npm install node-pngquant-native
```
**压缩 JPEG 图片**
- 工具[jpegtran](https://www.npmjs.com/package/jpegtran)
- 官网<https://www.npmjs.com/package/jpegtran>
- 介绍跨平台但压缩的比率只有80-90%
安装方法
```bash
npm install g jpegtran
```
使用方法
```bash
jpegtran -copy none -optimize -outfile output_file.jpg input_file.jpg
```
**压缩 GIF **
- 工具Gifsicle
- 官网含安装方法<https://www.lcdf.org/gifsicle/>
- 介绍Gifsicle 通过改变每帧比例减小 gif文件大小同时可以使用透明来达到更小的文件大小是目前公认的最好的解决方案
使用方法
```bash
# 压缩命令注意这里是将压缩级别设置为3如果将压缩级别设置为1或者2则基本不压缩
gifsicle --optimize=3 -o out_file.gif in_file.gif
# 裁掉透明部分
gifsicle --optimize=3 --crop-transparency -o out_file.gif in_file.gif
```
### 2将图片尺寸跟随网络环境进行变化
**具体方案**不同网络环境Wifi/4G/3G加载不同尺寸和像素的图片通过在图片 URL 中添加参数来改变
图片 url 举例1图片的原始url链接
```
https://img12.360buyimg.com/img/s3866x3866_jfs/t1/149913/14/18648/719436/5fd8b9b5Eb697b825/7c23f3028aff8e2b.jpg
```
图片 url 举例2通过图片的url参数将这张图的尺寸设置为200px
```
https://img12.360buyimg.com/img/s200x200_jfs/t1/149913/14/18648/719436/5fd8b9b5Eb697b825/7c23f3028aff8e2b.jpg
```
### 3响应式图片
**方法1**通过 JavaScript 绑定事件检测窗口大小以此设置图片大小
**方法2**CSS媒体查询
代码举例 640px的窗口大小里设置图片的尺寸为640px
```css
@media screen and (max-width:640px) {
my_image{
width:640px;
}
}
```
**方法3**img标签的 `srcset` 属性这个是 H5的新特性
代码举例
```html
<img srcset="img-320w.jpg, img-640w.jpg 2x, img-960w.jpg 3x" src=img-960w.jpg
alt=img> x 描述符表示图像的设备像素
```
### 4逐步加载图像lazyloadLQIPLQIP
**方法1**使用统一占位符俗称图片的`懒加载lazyload`
**方法2**使用 **LQIP** 的图片加载方式也就是说在大图没有完全加载出来的情况下先这张图对应的的低质量图片进行占位
LQIPLow Quality Image Placeholders低质量图像占位符这种技术背后的想法是在网络环境较差的情况下你可以尽快向用户展示完全可用的网页为他们提供更好的体验即使在更好的网络连接上这仍然为用户提供了更快的可用页面并且改善了体验
- 安装 LQIP 工具`npm install lqip`
- GitHub源码https://github.com/zouhir/lqip-loader
代码举例将目标图片转换为 LQIP 形式的图
```js
const lqip = require('lqip');
//文件路径
const file = './in.png';
//将输入的图片转为base64
lqip.base64(file).then(res => {
// 色值
console.log(res);
});
lqip.palette(file).then(res => {
//这里输出的是base64的图片地址
console.log(res);
});
```
另外我们还可以使用 **SQIP** 的图片加载方式
SQIPSVG Quality Image Placeholders SVG 格式的图像占位符
- 安装 SQIP 工具`npm install sqip`
- GitHub 源码<https://github.com/axe312ger/sqip>
代码举例将目标图片转换为 SQIP 形式的图
```js
const sqip = require('sqip');
const result = sqip({
filename: './input_file.png',
numberOfPrimitives: 10 //可根据不同应用场景设置大小
});
console.log(result.final_svg);
```
### 5雪碧图Image spriting
雪碧图是比较常见的图片优化方式也就是把多张小图合并成一张大图这样的话就只需做一次网络请求减少图片的 http 请求次数
读者们可以自行查阅
### 6有些场景下并不需要图片文件
有些场景下并不需要图片我们可以用其他的方式来代替图片
举例
- Web Font 代替图片
- 使用 Data URI 代替图片base64就是属于 Data URI的方式
2021-01-14 17:05:23 +08:00
### 7在服务器端进行图片自动优化
2020-12-15 21:34:51 +08:00
图片服务器自动化优化是可以在图片 URL 链接上增加不同特殊参数服务器自动化生成通过这些参数可以设置图片的不同格式大小质量
2021-01-14 17:05:23 +08:00
**常见处理方式**
2020-12-15 21:34:51 +08:00
- 图片裁剪按长边短边填充拉伸等缩放
- 图片格式转换支持 JPGGIFPNGWebP 支持不同的图片压缩率
- 图片处理添加图片水印高斯模糊重心处理裁剪边框等
- AI 能力鉴黄涉政智能抠图智能排版智能配色智能合成等 AI 功能
2021-01-14 17:05:23 +08:00
**图片举例**
比如JD公司的图片链接就会在服务器端做优化处理通过修改图片链接中的参数就能自动达到相应的优化效果
2020-12-15 21:34:51 +08:00
原始图片链接
```
https://img12.360buyimg.com/img/s3866x3866_jfs/t1/149913/14/18648/719436/5fd8b9b5Eb697b825/7c23f3028aff8e2b.jpg
```
将图片压缩为 200*150
```
https://img12.360buyimg.com/img/s200x200_jfs/t1/149913/14/18648/719436/5fd8b9b5Eb697b825/7c23f3028aff8e2b.jpg
```
将图片转换为 webp 格式
```
https://img12.360buyimg.com/img/s200x200_jfs/t1/149913/14/18648/719436/5fd8b9b5Eb697b825/7c23f3028aff8e2b.webp
```
将图片质量压缩至10%
```
https://img12.360buyimg.com/img/s3866x3866_jfs/t1/149913/14/18648/719436/5fd8b9b5Eb697b825/7c23f3028aff8e2b.jpg.q10
```
2021-01-14 17:05:23 +08:00
## HTML优化
### 1精简 HTML 代码
- 减少 HTML 的嵌套
- 减少 DOM 节点数
- 减少无语义代码比如: <div class=clear></div> css
- 删除 http 或者 https如果URL的协议头和当前页面的协议头一致的或者此 URL 在多个协议头都是可用的则可以考虑删除协议头
- 删除多余的空格换行符缩进和不必要的注释
- 省略冗余标签和属性
- 使用相对路径的 URL
### 2文件放在合适位置
- CSS 样式文件链接尽量放在页面头部
CSS 加载不会阻塞 DOM tree 解析但是会阻塞 DOM Tree 渲染也会阻塞后面 JS 执行
任何 body 元素之前可以确保在文档部分中解析了所有 CSS 样式内联和外联从而减少了浏览器必须重排文档的次数
如果放置页面底部就要等待最后一个 CSS 文件下载完成此时会出现"白屏"影响用户体验
- JS 引用放在 HTML 底部
防止 JS 在加载解析执行时阻塞了页面后续元素的正常渲染
### 4增强用户体验
- 设置 favicon.ico
网站如果不设置 favicon.ico控制台会报错另外页面加载过程中如果没有图标则会出现 loading 过程也不利于记忆网站品牌建议统一添加
- 增加首屏必要的 CSS JS
页面如果需要等待所的依赖的 JS CSS 加载完成才显示则在渲染过程中页面会一直显示空白影响用户体验建议在首屏增加必要的 CSS JS比如页面框架背景图片或者loading 图标内联在 HTML 页面中这样做首屏能快速显示出来缓解用户焦虑现在很多网页在初始化的时候流行做**骨架屏**小伙伴们也可以研究下
## CSS优化
### 1提升 CSS 渲染性能
- 谨慎使用 expensive 属性这类属性比较耗浏览器的性能比如`nth-child` 伪类`position: fixed` 定位
- 尽量减少样式的层级数
比如`div ul li span i {color: blue;}`这样的层级就太深了建议给 i 标签设置 class属性然后通过class直接设置样式属性可以提升浏览器的查询效率
- 尽量避免使用占用过多 CPU 和内存的属性比如`text-indnt:-99999px`
- 尽量少使用耗电量大的属性比如CSS3 3D transformsCSS3 transitionsOpacity 这样的属性会消耗GPU
### 2合适使用 CSS 选择器
- 尽量避免使用 CSS 表达式
比如 `background-color: expression( (new Date()).getHours()%2 ? "#FFF" : "#000" );`这个属性的意思是每间隔两小时改变白景色
- 尽量避免使用通配选择器
比如 `body > a {font-weight:blod;}`这样的属性可能会把 body 里所有的标签遍历一遍才找到 a 标签比较耗时
- 尽量避免类正则的属性选择器`*= |= ^= $=`
### 3提升 CSS 文件加载性能
- 使用外链的 CSS
我们知道内联的 css 是在html 内部写的相比之下外链的 CSS文件是放在CDN上的可以缓存既能减少 html 页面的体积大小也能利用缓存减少资源的请求
- 尽量避免使用 @import 方法
整个CSS加载完成后浏览器会把 import 中所有依赖的文件全部加载完成后浏览器才会接着往下渲染这个过程会阻塞CSS文件的加载过程
### 4精简 CSS 代码
- 使用缩写语句
- 删除不必要的零比如 0.2 可以写成 .2
- 删除不必要的单位比如 0px 可以写成 0
- 删除过多的空格注释言简意赅
- 尽量减少样式表的大小
当然很多地方可以在编译时通过压缩工具来处理但是我们在写代码时也应该有良好的编码习惯
### 5合理使用 Web Fonts
- 将字体文件部署在 CDN
- 或者将字体以 base64 形式保存在 CSS 中并通过 localStorage 进行缓存
- Google 字体库因为某些不可抗拒原因应该使用国内托管服务
### 6CSS 动画优化
- 尽量避免同时出现过多动画
- 延迟动画初始化让其他的重要的CSS样式优先渲染
- 结合 SVG