-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
27e9a17
commit e792c44
Showing
9 changed files
with
267 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# TreeShaking | ||
|
||
1. 尽量使用export {} 导出代码 | ||
|
||
使用这样的写法,webpack才能做tree-shaking | ||
```js | ||
export { | ||
xxx | ||
} | ||
``` | ||
|
||
2. 不要使用babel将esm转为cjs | ||
|
||
若代码是`commonjs`代码,将失去tree-shaking优化,需要设置`baberc`配置中的`modules: false` | ||
|
||
3. lib库酌情使用 sideEffects | ||
|
||
通过设置`package.json`中的`sideEffects`字段,可以告诉webpack哪些是纯的(无副作用) | ||
|
||
4. 使用 unplugin-vue-components 或 babel-plugin-import 按需引入组件 | ||
|
||
|
||
5. 可以使用 /*#__PURE__ */ 标记哪些函数调用没有副作用,进而tree-shaking | ||
|
||
6. 异步模块标记哪些导出被使用 | ||
```js | ||
import(/* webpackExports: ["foo", "default"] */ "./foo").then((module) => { | ||
console.log(module.foo); | ||
}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# 构建性能优化 | ||
|
||
|
||
## 构建速度优化 | ||
2. 使用 webpack5 持久化缓存,能明显提高构件速度 | ||
3. 使用lazyCompilation 可以懒编译,能明显提高开发构建速度 | ||
4. 约束loader的`include`和`exclude` | ||
5. 使用`module.noParse` 可以跳过对某些文件的编译,因为有些三方库是已经编译过的 | ||
6. 新版本组件 eslint-webpack-plugin 替代旧版 eslint-loader, 旧版出现错误会中断编译。 | ||
7. 优化`source-map`的配置,使用`eval-cheap-source-map`可以提高构建速度 | ||
8. 借助`swc`, `esbuild`等高性能编译器,优化构建速度, 例如terser插件可以指定使用`swc`或`esbuild`对代码进行压缩 | ||
9. 采用并行压缩,例如:`thread-loader`、`terser`插件自带的`parallel`参数 | ||
|
||
|
||
|
||
## 构建体积优化 | ||
1. 尽量使用export {} 导出代码 | ||
使用这样的写法,webpack才能做tree-shaking | ||
```js | ||
export { | ||
xxx | ||
} | ||
``` | ||
2. 不要使用babel将esm转为cjs | ||
若代码是`commonjs`代码,将失去tree-shaking优化,需要设置`baberc`配置中的`modules: false` | ||
|
||
3. lib库酌情使用 sideEffects | ||
|
||
通过设置`package.json`中的`sideEffects`字段,可以告诉webpack哪些是纯的(无副作用) | ||
|
||
4. 使用 unplugin-vue-components 或 babel-plugin-import 按需引入组件 | ||
|
||
5. 可以使用 /*#__PURE__ */ 标记哪些函数没有副作用,进而tree-shaking | ||
|
||
6. 合理配置`split-chunk-plugin`,例如其中的`maxInitialRequests`和`maxAsyncRequests`属性,用于控制异步模块和入口模块的拆分粒度。能有效减少重复打包的模块。 | ||
|
||
7. 三方模块,尽量提取为CDN, 可以增加访问速度,突破HTTP 1.x 的请求并发限制。 | ||
|
||
8. 使用http2,多路复用等特性,提高了访问速度 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# 上报埋点或数据的方式 | ||
|
||
## 1. 使用img的src做请求发送 | ||
优点:不用做特殊处理,没有跨域的限制,script标签,img标签都可以直接发送跨域的GET请求,兼容性比较好,有些页面可能禁用了脚本,这时script标签久不能使用了。img就没有这个限制。 | ||
|
||
当我们使用img的src标签访问的时候,就会触发访问这个get请求。这个时候服务端就会接收到前端发送的请求。 | ||
|
||
## 2. navigator.sendBeacon() | ||
sendBeacon的优点: | ||
|
||
- 使用sendBeacon()方法会使用户代理在浏览器空闲时异步的向服务器发送数据,不会和主要业务代码抢占资源, | ||
- 在页面卸载的时也能保证请求成功发送,同时不会延迟页面的卸载或影响下一页面的载入性能。 | ||
|
||
缺点: | ||
- sendBeacon是有浏览器兼容问题的,所以我们使用的时候为了完善,还是要用img这种方式来进行兜底。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# 性能指标 | ||
|
||
## FCP | ||
浏览器首次渲染DOM(包含文本、图像、svg等)的时间,能反映出用户等待看到页面的时间。 | ||
|
||
## LCP | ||
浏览器渲染页面最大元素的时间,反应了用户能看到的主要内容时间。 | ||
|
||
## 页面加载时间 | ||
指用户发起请求到完全呈现页面的时间。 | ||
|
||
## 首字节时间 | ||
指从浏览器接收到服务器响应的第一个字节所经历的时间,反应了服务端的响应速度。 | ||
|
||
## 阻塞总时长(TBT) | ||
表示页面加载过程中所有长任务阻塞主线程的总时间。它也可以通过监听页面上的长任务来计算。当一个长任务的执行时间超过 50 毫秒时,我们认为它阻塞了主线程。 | ||
|
||
## 可交互时间(TTI) | ||
指从用户发起请求到页面可以正常响应用户操作所经过的时间。这个指标反映了用户等待页面可交互的时间,对用户体验有很大影响。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# 性能监控 | ||
|
||
`performance.timing`这个api已经被慢慢废弃了。 | ||
|
||
`performance.timing`与`performance.getEntriesByType('navigation')[0]`两个时间统计会有点差异,前者是`绝对时间`,后者统计的时间都是相对本次请求开始作为起始时间,这点比较重要。 | ||
|
||
```js | ||
window.addEventListener('load', function() { | ||
const [performanceData] = performance.getEntriesByType("navigation"); | ||
}) | ||
``` | ||
|
||
|
||
## 计算页面加载时间 | ||
```js | ||
performanceData.loadEventEnd - performanceData.domComplete | ||
``` | ||
|
||
## 计算请求响应时间 | ||
```js | ||
performanceData.responseEnd - performanceData.requestStart | ||
``` | ||
|
||
## 计算DNS查询时间 | ||
```js | ||
performanceData.domainLookupEnd - performanceData.domainLookupStart | ||
``` | ||
|
||
## 计算TCP连接时间 | ||
```js | ||
performanceData.connectEnd - performanceData.connectStart; | ||
``` | ||
|
||
## 计算白屏时间 | ||
```js | ||
performanceData.domInteractive - performanceData.responseStart | ||
``` | ||
|
||
## 计算FCP | ||
```js | ||
let fcpTime = 0; | ||
const [fcpEntry] = performance.getEntriesByName("first-contentful-paint"); | ||
if (fcpEntry) { | ||
fcpTime = fcpEntry.startTime; | ||
} | ||
``` | ||
|
||
## 计算LCP | ||
|
||
```js | ||
let lcpTime = 0; | ||
const lcpEntries = performance.getEntriesByType("largest-contentful-paint"); | ||
if (lcpEntries.length > 0) { | ||
lcpTime = lcpEntries[lcpEntries.length - 1].renderTime || lcpEntries[lcpEntries.length - 1].loadTime; | ||
} | ||
``` | ||
|
||
## 计算 TBT、TTI | ||
```js | ||
// 监听长任务 | ||
let tti = 0; | ||
let tbt = 0; | ||
const observer = new PerformanceObserver((entryList) => { | ||
for (const entry of entryList.getEntries()) { | ||
// 计算 TBT | ||
if (entry.duration > 50) { | ||
tbt += entry.duration - 50; | ||
} | ||
} | ||
|
||
// 计算 TTI | ||
if (tti === 0 && tbt < 50) { | ||
tti = performance.now(); | ||
} | ||
}); | ||
observer.observe({ entryTypes: ["longtask"] }); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# 资源监控 | ||
|
||
获取资源数据: | ||
|
||
```js | ||
let resourceData = performance.getEntriesByType('resource'); | ||
``` | ||
|
||
计算时间: | ||
|
||
```js | ||
resourceData.forEach(function(resource) { | ||
// 获取资源的相关信息,例如名称、类型、大小等 | ||
let name = resource.name; | ||
let type = resource.initiatorType; | ||
let size = resource.transferSize; | ||
|
||
// 可计算的资源时间 | ||
console.log(`== 资源 [${i}] - ${resource.name}`); | ||
// 重定向时间 | ||
let t = resource.redirectEnd - resource.redirectStart; | ||
console.log(`… 重定向时间 = ${t}`); | ||
|
||
// DNS时间 | ||
t = resource.domainLookupEnd - resource.domainLookupStart; | ||
console.log(`… DNS查询时间 = ${t}`); | ||
|
||
// TCP握手时间 | ||
t = resource.connectEnd - resource.connectStart; | ||
console.log(`… TCP握手时间 = ${t}`); | ||
|
||
// 响应时间 | ||
t = resource.responseEnd - resource.responseStart; | ||
console.log(`… 响应时间 = ${t}`); | ||
|
||
// 获取直到响应结束 | ||
t = | ||
resource.fetchStart > 0 ? resource.responseEnd - resource.fetchStart : "0"; | ||
console.log(`… 获取直到响应结束时间 = ${t}`); | ||
|
||
// 请求开始直到响应结束 | ||
t = | ||
resource.requestStart > 0 | ||
? resource.responseEnd - resource.requestStart | ||
: "0"; | ||
console.log(`… 请求开始直到响应结束时间 = ${t}`); | ||
|
||
// 开始直到响应结束 | ||
t = | ||
resource.startTime > 0 ? resource.responseEnd - resource.startTime : "0"; | ||
console.log(`… 开始直到响应结束时间 = ${t}`); | ||
}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# prefetch和preload | ||
|
||
## preload 提前加载 | ||
|
||
优先级:高 | ||
|
||
preload 顾名思义就是一种预加载的方式,它通过声明向浏览器声明一个需要提前加载的资源,当资源真正被使用的时候立即执行,就无需等待网络的消耗。 | ||
|
||
|
||
## prefetch | ||
|
||
优先级:低 | ||
|
||
prefetch 会告诉浏览器未来可能会使用到的某个资源,浏览器就会在闲时去加载对应的资源。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters