性能优化
- 使用CDN资源
- Nginx 开启 gzip 在浏览器的请求头里包含着这样一句话Accept-Encoding:gzip, deflate,这告诉我们浏览器是可以识别gzip压缩的.浏览器可以自己解析出gzip的文件。gzip 和 http2 是怎么进行压缩的?说白了就是复用重复内容,拼装不重复内容
- 浏览器缓存
- 路由懒加载
- 关键资源的预加载,preload 将提升资源加载的优先级
<link rel="preload" href="xxxx">
与<link rel="prefetch" href="xxxx">
Tree-shaking
Tree-shaking的本质是消除无用的js代码。无用代码消除在广泛存在于传统的编程语言编译器中,编译器可以判断出某些代码根本不影响输出,然后消除这些代码,这个称之为DCE(dead code elimination)。Tree-shaking 是 DCE 的一种新的实现。
实现原理
tree-shaking的消除原理是依赖于ES6的模块特性。 ES6模块依赖关系是确定的,在编译时就能确定模块的依赖关系,以及输入和输出的变量。和运行时的状态无关,可以进行可靠的静态分析,这就是tree-shaking的基础。
特点
- es6模块中import只能在模块顶层出现;
- import 的模块名只能是字符串常量,不能像require(CommonJS的实现)一样动态引入模块;
- import binding 是 immutable(不可改变的)的,引入的模块不能再进行修改;
- 代码擦除: uglify 阶段删除无用代码。uglify是著名的代码压缩优化工具,uglify完成了javascript的DCE 参考Tree-Shaking性能优化实践 - 原理篇
es6转es5的实现
webpack中通过babel实现这个转化过程
- ES6 语法解析为 AST抽象语法树
- AST 语法树转换为ES5对应的AST抽象语法树
- 将新的AST语法树转为可识别的ES5语法
- Parser解析 第一步主要是将 ES6 语法解析为 AST 抽象语法树。简单地说就是将代码打散成颗粒组装的对象。这一步主要是通过 babylon 插件来完成。
- Transformer 转换 第二步是将打散的 AST 语法通过配置好的 plugins 和 presets 转换成新的 AST 语法。这一步主要是由 babel-transform 插件完成。plugins 和 presets 通常在 .babelrc 文件中配置。
- Generator 生成 第三步是将新的 AST 语法树对象再生成浏览器都可以识别的 ES5 语法。这一步主要是由 babel-generator 插件完成。
微前端
微前端是将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用还可以独立运行、独立开发、独立部署。微前端不是单纯的前端框架或者工具,而是一套架构体系
微前端实现方案
- Nginx路由转发
- iframe嵌套
- Web Components
- 组合式应用路由分发 组合式应用路由分发是目前应用最广泛的一种实现。该方案的核心是“主从”思想,即包括一个基座(MainApp)应用和若干个微(MicroApp)应用,基座应用大多数是一个前端SPA项目,主要负责应用注册,路由映射,消息下发等,而微应用是独立前端项目,这些项目不限于采用React,Vue,Angular或者JQuery开发,每个微应用注册到基座应用中,由基座进行管理,但是如果脱离基座也是可以单独访问。
eventBus和vuex的对比
- vuex是官方推出的,事件总线是高手在民间
- 在大型应用方面,vuex确实是一个比EventBus更好的解决方案。在小型项目上,可以用事件总线或者简单状态管理
- vuex更加易于调试与管理。因为vuex解决无法追踪状态变化的问题,无法直接修改store.state,必须通过commit来实现
- vuex的modules解决namespace的可能重复的问题 参考EventBus & Vuex?
vue3中使用reactive需要注意的地方
proxy实现响应式其实是将一个raw对象(原始对象)包装了一层,产生了一个新的对象,这个对象跟原始对象是不相等的,也就是说,可能会存在原始对象占用内存并且无法释放的问题,所以我们在将一个对象声明响应式时,尽量不要用任何的变量去引用原始对象,而是直接将该对象放在reactive中。
不推荐的做法
<script>
import {reactive} from 'vue'
export default {
setup() {
let obj = { name: 'xiaoming', age: 15 } // 原始对象
const state = reactive(obj) // 将obj包装成响应式
return {state}
}
}
</script>
推荐的做法
<script>
import {reactive} from 'vue'
export default {
setup() {
// 不再先声明原始对象
const state = reactive({ name: 'xiaoming', age: 15 })
return {state}
}
}
</script>
使用技巧 添加定时器时,可以不用找到beforeDestroy()生命周期里移除,可以巧妙利用$once
let timer = setInterval(() => {
//...
}, 10000)
this.$once('hook:beforeDestroy', function() {
clearInterval(timer)
});
虚拟dom的优缺点
优点:
- 保证性能下限: 虚拟DOM可以经过diff找出最小差异,然后批量进行patch,这种操作虽然比不上手动优化,但是比起粗暴的DOM操作性能要好很多,因此虚拟DOM可以保证性能下限
- 无需手动操作DOM: 虚拟DOM的diff和patch都是在一次更新中自动进行的,我们无需手动操作DOM,极大提高开发效率
- 跨平台: 虚拟DOM本质上是JavaScript对象,而DOM与平台强相关,相比之下虚拟DOM可以进行更方便地跨平台操作,例如服务器渲染、移动端开发等等 缺点:
- 无法进行极致优化: 在一些性能要求极高的应用中虚拟DOM无法进行针对性的极致优化,比如VScode采用直接手动操作DOM的方式进行极端的性能优化
首字节时间
TTFB-首字节时间,是指从客户端开始和服务端交互到服务端开始向客户端浏览器传输数据的时间(包括DNS、socket连接和请求响应时间),是能够反映服务端响应速度的重要指标,获取在接收到响应的首字节前花费的毫秒数。lTime = Response.TTFB返回值 lTime As Long:首字节响应时间(以毫秒为单位)。
TTFB:httpwatch的timechart中的一列参数。
课外学习部分:
什么是TTFB呢?1.TTFB (Time To First Byte),是最初的网络请求被发起到从服务器接收到第一个字节这段时间,它包含了 TCP连接时间,发送HTTP请求时间和获得响应消息第一个字节的时间。注意:网页重定向越多,TTFB越高,所以要减少重定向TTFB优化的方法有:
1.减少DNS查询
2.使用CDN
3.提早Flush
4.添加周期头