# 优化
工程化阶段的优化和原理级别优化(即打包工具帮你做到的事情)是不一样的。
我们尽可能的避免单个文件超过300行。
状态多级嵌套,应尽可能的约束在父子级。
## 图片
大的图片(业务),使用静态http加载
小的图片(图标),打包到html页面中(base64等)
原因:小的图片加载,会导致页面不够友好。大的图片打包会导致用户加载html时间过久。
### svg
#### 🥰 采用原生svg,可以通过svgo等插件优化svg图片的大小(质量降低)
优势:多色,配置灵活
劣势:代码冗长
解决方案:svg组件封装
#### 😨 市面其他方案(iconfont):
优势为使用方便。
unicode、fontclass方式
基于字体,会被浏览器最小限制12px,以及不支持多色
symbol
无法保证宽高比,也就是即使viewbox=“0,0,20,20”约束了宽高比,
那么在实际使用时,style=“width:50px;height:auto”,高度也无法正常变成50px
## JS打包
异步载入JS。对于优先于样式布局的代码可以通过async载入,对于业务逻辑相关的可以使用defer或type="module"。
区别在于,async虽然是异步,但一旦载入完成后会进行同步阻塞dom执行逻辑,而其余两种均等待dom解析完成后再执行逻辑。
实际做法:使用ES导入导出,打包工具就会自动帮你做tree shaking优化。
原理:
Nodejs为了解决模块化提出了CommonJS方案。
在cjs中,模块的导入导出是动态的(require)。即如果代码块不运行到这里,它也不知道会有哪些代码被使用。
而mjs的import、export是静态的,也就是打包工具可以在编译阶段,通过识别AST来判断所导入的函数是否有在当前模块中被使用。如果没有则不对其声明函数进行打包。
即:
```js
// export.js
// import.js
import test from './export.js'
function a() {
console.log('a')
}
function b() {
console.log('b')
}
export default { a, b }
test.a()
```
上述代码中,b不会被打包。
而如果存在副作用,即:
```js
// export.js
// import.js
import test from './export.js'
function a() {
console.log('a')
}
function b() {
console.log('b')
}
function c() {
console.log('c')
}
c()
export default { a, b }
test.a()
```
则a与c都会被打包,如果我们已知c是无用代码,就可以使用/*#_PURE*/通知打包工具,前提是打包工具使用的是tarser进行代码优化。因为基于压缩工具的不同其shaking的方式可能也有所不同。
## 样式
避免重排(对形状产生影响的),减少重绘(色彩)
合并样式文件,每个1k文件加载10次,也不如10k的文件加载一次好。
实际做法:基于postcss、配置cssnano。
详情:
http分析css是阻塞性质的,会导致css的识别延缓了dom的识别,但是浏览器没有提供对其异步加载的策略。
我们可以通过使用媒体查询的方式来伪造异步:
```html
```
但实际上,异步的做法可能会增加多次不可预见性的重排、重绘。
在css中,避免使用@import的做法,因为使用了模块化css之后,css的加载就变成串行的了。
上述做法都不是我们要担心的,因为编译器会帮助我们完成这些,我们只需要配置postcss即可:
cssnano:代码压缩。
autoprefixer:浏览器适配.