浏览器缓存技术指南

浏览器缓存(Browser Cache)是指浏览器会将访问过的资源(如 HTML、CSS、JS、图片等)存储在本地,以便在后续请求时可以直接从缓存中获取,而不是重新向服务器请求。在 Web 开发中,浏览器缓存是一项至关重要的优化技术,它能够减少网络请求,提升页面加载速度,提高用户体验,同时降低服务器负载。

缓存机制主要通过 HTTP 头部控制,包括强缓存(Strong Cache)和协商缓存(Negotiated Cache)。强缓存会直接读取本地缓存,协商缓存则是与服务器协商读取。缓存未过期使用强缓存机制,过期了则使用协商缓存机制。

%%{
  init: {
    'theme': 'base',
    'themeVariables': {
      'primaryBorderColor': '#7C0000',
      'lineColor': '#fff',
      'tertiaryColor': '#fff',
      'fontSize': '12px',
      'max-width': '10000px'
    }
  }
}%%

graph TD;
    A[浏览器请求资源] --> B{是否存在缓存}
    B -- 否
no-store --> C[向服务器请求资源] C --> D{决策返回
200 or 304?} D -- 200 --> E[设置缓存信息
Last-Modified, ETag] E --> F[使用资源] D -- 304 --> G[更新缓存信息
Last-Modified, ETag] G --> F B -- 是 --> H{是否可直接使用} H -- 否
no-cache --> I[获取验证信息
If-Modified-Since / If-None-Match] I --> C H -- 是 --> K{是否过期
expires/max-age/s-maxage} K -- 是 --> I K -- 否 --> L[从缓存中获取资源] L --> F

(缓存控制流程图)

Read More

WASM 中 AES 加解密实现

最近对项目所有的 HTTP 请求响应进行了 AES 加解密改造,但在 JavaScript 中保管 AES Key 有着非常大的安全风险,将加解密逻辑交由难以反编译的 WebAssembly 实现,则是一种比较安全的选择。

Read More

Component 组件的函数调用

1
2
3
4
5
6
7
8
9
10
<van-popup v-model:show="visiblePopup">
<Comp v-if="visiblePopup" :some-props="someProps" />
</van-popup>

<script lang="ts" setup>
import {ref, reactive} from 'vue'

const visiblePopup = ref(false)
const someProps = reactive()
</script>

像上面这样的模板式弹框代码,在项目中是最常见不过的,以 Component 方式调用弹框,如果代码组织不好,会使得 template 变得异常凌乱,更重要的是其中充斥着诸如 visiblePopupsomeProps 等这样的中间变量,显得尤为不优雅。而像下面这样以函数方式调用则简洁得多。

1
2
3
const handleOpenComp = () => {
showPopup(comp, someProps)
}
Read More

TypeScript 接口和类型生成

接口和类型的定义是一件耗时费力的工作,通过解析 OpenAPI/Swagger 文档,自动化生成接口是一种很好的解决方案,这也便于接口更新时做 git diff,清晰的显示接口更新的内容。

1
2
3
4
5
6
7
8
9
10
11
export interface AppResetPasswordReq {
email: string
password: string
code: string
}

export function resetPassword(params: AppResetPasswordReq): Promise<Result<boolean>> {
return axios.post('/app/reset/password', params)
}

// more...
Read More

WebSocket 连接共享

1000 多个用户同时在线,用户打开多个 Tab 页,每个 Tab 页都会创建一个 WS 连接,最终创建了 140000 多个 WS 连接,导致服务端奔溃。通过使用 SharedWorker 转发 WS 消息,让所有页面共用一个 WS 连接来解决问题。

Read More

Typescript 类型编程

泛型编程

泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性,主要作用是对不特定数据类型的支持,以实现函数、接口(Interface)、类的复用。

Read More

Docker Guide

在现代软件开发和部署中,Docker 作为一种容器技术,极大地简化了运行环境的搭建和应用程序的部署。与传统的虚拟机(VM)不同,Docker 容器利用宿主机的操作系统内核,而不是虚拟出一整套硬件和操作系统,从而实现轻量级和高效的资源利用。

Read More

Scratch 编程

Scratch

Read More

用户角色权限设计

在多角色的系统中(比如管理端)一般会给不同角色的用户分配不同的权限。权限一般有以下分类:

1
2
3
4
* 页面权限
* 操作权限
* 数据权限
* API 权限

页面一般通过路由分发,所以页面权限也叫做路由权限。在这些权限中,API 权限是后端权限,其他都是前端权限,下面从前端角度介绍用户角色权限的设计。

Read More

使用二进制设计课堂权限

使用二进制能很方便的表达和计算(组合、切换和校验)权限,以 Linux 文件权限为例。

权限 字母表示 数字表示 二进制
r 4 0b100
w 2 0b010
执行 x 1 0b001
Read More