Skip to content

Commit

Permalink
changes
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] committed Oct 16, 2023
1 parent 27e9a17 commit e792c44
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 1 deletion.
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);
});
```
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,多路复用等特性,提高了访问速度
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这种方式来进行兜底。
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# 性能指标

## FCP
浏览器首次渲染DOM(包含文本、图像、svg等)的时间,能反映出用户等待看到页面的时间。

## LCP
浏览器渲染页面最大元素的时间,反应了用户能看到的主要内容时间。

## 页面加载时间
指用户发起请求到完全呈现页面的时间。

## 首字节时间
指从浏览器接收到服务器响应的第一个字节所经历的时间,反应了服务端的响应速度。

## 阻塞总时长(TBT)
表示页面加载过程中所有长任务阻塞主线程的总时间。它也可以通过监听页面上的长任务来计算。当一个长任务的执行时间超过 50 毫秒时,我们认为它阻塞了主线程。

## 可交互时间(TTI)
指从用户发起请求到页面可以正常响应用户操作所经过的时间。这个指标反映了用户等待页面可交互的时间,对用户体验有很大影响。
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"] });
```
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}`);
});
```
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ window.addEventListener("load", () => {

`firstPaintEnd`可以看做白屏时间的结束时间点。

`performance API`

```js
firstPaint = firstPaintEnd - performance.timing.navigationStart;
```

`performance.getEntriesByType`

```js
performanceData.domInteractive - performanceData.responseStart
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# prefetch和preload

## preload 提前加载

优先级:高

preload 顾名思义就是一种预加载的方式,它通过声明向浏览器声明一个需要提前加载的资源,当资源真正被使用的时候立即执行,就无需等待网络的消耗。


## prefetch

优先级:低

prefetch 会告诉浏览器未来可能会使用到的某个资源,浏览器就会在闲时去加载对应的资源。
13 changes: 12 additions & 1 deletion src/open-source/vitepress-plugin-vue-repl.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

## Preview

:::playground CodeMirror
:::playground
```vue
<template>
<div>playground test</div>
Expand All @@ -19,6 +19,17 @@ div {
}
</style>
```

```json
{
"imports": {
"ant-design-vue": "xxx"
},
"editorConfig": {
"layout": "vertical"
}
}
```
:::
## install

Expand Down

0 comments on commit e792c44

Please sign in to comment.