博弈论概论
多年前导师的博弈论,最近想着重温记录下来,便有此文。博弈论的核心,是掌握「策略化思考」的底层逻辑—— 从 “只算自己的最优解”,变成 预判他人选择、再选自己最优解。
经典场景案例有两个嫌疑犯 A 和 B,被警察抓住,关在不同房间审讯。警察告诉他们:
A的选择 \ B的选择
沉默
招供
沉默
(1,1)
(5,0)
招供
(0,5)
(3,3)
用收益表表示(数字越小越好,因为是刑期)。
方案:纳什均衡没有任何一个参与者可以通过单独改变自己的策略来提高收益,它只要求 “稳定”,不要求 “最好”。对于A而言,若B沉默,A的最优解时选择招,不用坐牢,若B招供,A的最优解还是选择招,只判三年。针对B也是一样。所以,此处的纳什均衡,就是(3,3)。但是很明显都沉默才是集体的最优解。个体理性 → 导致集体最差结果(纳什均衡),但集体最优结果却不稳定(不是纳什均衡)。
canvas离屏渲染详解
本文通过实例介绍下,针对canvas,如何通过离屏渲染做性能优化业务场景某些场景下,我们需要在canvas进行诸多的绘制渲染的操作,当渲染量达到一定程度时,例如绘制的图形个数巨大,渲染耗时大到页面处于暂时性卡死,该如何破?离屏渲染
实现思路在主线程中,通过transferControlToOffscreen,将渲染的工作给到worker处理,以此规避卡死主线程的目的。
演示react核心代码
const drawCanvasOne = () => {
if (!canvasOneRef.current || !canvasTwoRef.current) return
const canvas:HTMLCanvasElement = canvasOneRef.current
const ctx = canvas.getContext('2d');
if (!ctx) return
let frameCount = 0;
const render = () => {
frameCount++;
...
基于opensumi的编辑器问题
本文简单整理下,公司编辑器项目遇到的坑,及对应的解决方案这段时间在整公司的一个web3的编辑器,基于opensumi开发的,主要是支持编写各种合约语言然后编译、部署的一整套流程。总结下过程中遇到的问题。
性能问题这是绝对的大头。比如一个文件10MB+,用户需要编辑,但是用 OpenSumi 打开后,就会出现明显的卡顿(输入文字时光标滞后 0.5-1 秒)、滚动不流畅,甚至偶尔白屏。方案:
Monaco Editor 层优化
开启「增量渲染」:设置 editor.maxTokenizationLineLength = 500(超过 500 行的文件仅渲染可视区域,滚动时再渲染其他区域);
禁用大文件语法高亮:通过 OpenSumi 的 IEditorService 扩展,判断文件大小 > 5MB 时,自动切换为「纯文本模式」,关闭语法高亮和代码补全;
OpenSumi层 文件缓存策略优化重写 IFileService 的 readFile 方法,大文件采用「流式读取」(createReadStream),而非一次性读取全量内容,类似视频流。
自定义插件与第三方插件加载顺 ...
Webkit系列:第二回(HTML解释器和DOM模型)
本文将尽可能的解释Webkit的HTML解释器流程及Dom模型相关的知识点在前文介绍从输入url到页面的最终呈现的过程,其中有一步:渲染器进程获取到资源后会将html资源给到html解释器,用来生成dom节点最终生成dom树形结构的对象。那么html解释器具体做了啥呢?
总体流程:字节流被解码成字符流,字符流通过词法分析器被解释成词语,词语通过语法分析器构建成节点,最后节点组合成dom树。
1. 字节 —> 字符收到字节流之后,解释器会根据网页内容所使用的编码格式,将字节流解析成对应的字符串。如果没有特别指定编码格式,直接进入下一步的词法分析。
2. 字符 —> 词语HTMLTokenizerHTMLTokenizer类负责词法解析。输入字符串,输出是一个个的词语。解释完成的词语会经过XSSAuditor安全验证,干嘛的呢?实质就是将一些可能会导致安全问题的词语过滤掉。只有通过安全验证的词语,才会继续下一步。
3. 词语 —> 节点HTMLTreebuilder类的construcTree由词语创建节点过程中,坑会遇到js代码。这就是为什么全局执行的js无法访问dom ...
Webkit系列:第一回(先验内容)
一些关于浏览器的先验内容
2005年苹果开源了自家的safari浏览器内核webkit,2008年,谷歌改造webkit为blink,开发出了chromium,最终推出chrome。
chrome是一个典型的多进程的架构,即chrome这么个应用,是由多个子进程组成的,具体包括如下:
浏览器进程: 负责管理除了页面显示的其他区域,也就是及页面地址栏那些东西,当然还包括书签等。
渲染进程: 该进程又称为内核,将请求资源转换为可视化(可听化)的图像结果,就是浏览器内核。渲染进程又有多个重要的子线程组成,
GUI线程: 浏览器拿到请求资源后,有一步操作就是,根据html和css文件分别生成dom树和样式树,然后生成渲染树和布局树,这部分的工作,就是gui线程负责实现的。
JS线程:又称为js主线程,就是执行js代码的。
合成器线程:该线程获得布局树后,通过栅格化确定一帧的每个像素点数据,最终交由GPU进程处理。
定时器线程: 如果当js主线程执行代码时,遇到settimeout和setInterval两定时器的时候,主线程会把定时器函数扔给定时器线程处理,自己继续往下执行。定时线程等待设 ...
谷歌插件流程:第三回
前面我们通过两篇文章,介绍了一个插件的完整开发过程。本文,我们从更加细致的层面,梳理下开发谷歌插件的必知规则
先看看我们的manifest.json文件内容{
"name": "Ta-da",
"description": "zhihu_small_video_down",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"permissions": ["storage", "activeTab", "scripting"],
"action": {
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"j ...
打通最后一公里:项目部署
本文介绍前后端分离项目,部署相关的细枝末节,打通最后一公里
静态站点部署这类的项目部署,很简单,都不需要关注域名服务器那些东西,可以借助vercel这样的第三方,一键部署。具体流程:前端项目挂在github上,然后去vercel上面导入即可
非静态站点部署一般这种项目会涉及两部分,前端、后端。前端负责视图,后端负责数据接口。具体流程:
前端
通过npm run build,打包生成生产环境所需文件。
后端
将后端应用打包成可执行文件部署到服务器上。
配置后端服务器:部署后端应用到服务器上,确保后端应用能够正常运行。你可能需要安装相应的运行环境和依赖。
配置数据库:如果后端应用需要连接数据库,确保数据库服务已经正确配置并运行。
配置域名和端口:确保后端服务器的域名和端口设置正确,以便前端应用可以与后端应用通信。
当然这个流程涉及诸多的细枝末节,我们慢慢道来…
基于cesium开发应用之问题
本文主要记录cesium开发过程中的坑加载模型太多导致卡顿加载上千个地标、模型、轨迹线等 Cesium Entity 时,页面帧率(FPS)骤降,操作视角卡顿,甚至浏览器内存溢出。原因:Cesium 默认对每个 Entity 单独渲染,海量实体导致 DrawCall(绘制调用)激增;解决方案:
数据分块 + 视域剔除:基于Cesium.ScreenSpaceCameraController监听视角变化,仅渲染当前视域内的实体,远距实体暂存 / 销毁;// 批量点优化(10万+点)
const pointCollection = new Cesium.PointPrimitiveCollection({
frustumCulling: true, // 开启视口剔除
});
开启性能优化配置viewer.scene.fog.enabled = true; // 开启雾效,远距模型自动淡化
viewer.scene.debugShowFramesPerSecond = true; // 监控帧率
viewer.scene.maximumAliasedLi ...
