Node15以下的版本不支持M1芯片,需要在终端输入命令。
arch -x86_64 zsh
进入Rosetta模式,然后再进行低版本的安装就可以了。
具体细节可以查看https://github.com/nvm-sh/nvm/issues/2350#issuecomment-734132550
Node15以下的版本不支持M1芯片,需要在终端输入命令。
arch -x86_64 zsh
进入Rosetta模式,然后再进行低版本的安装就可以了。
具体细节可以查看https://github.com/nvm-sh/nvm/issues/2350#issuecomment-734132550
chrome现在有一个高大上的fps观测工具,你可以不用再去分析performance面板的跑分了。
打开devTools,如果你是mac请按组合键 commend + shift + p (win系统自行翻译),然后再搜索框中输入fps,你会看到如下的状态。
选择第一个结果回车即可
在更多工具的Rendering面板下面,选中“Frame Rendering Stats”即可
这个工具有个缺点是位置不能移动。
看下面这张图就够了
总结来说就是:
你可以通过performance标签下面的learn more,
或者直接跳转
来学习官方的教程。
这里对重点部分做一个摘要来方便你的快速使用。
1、在DevTools中,单击记录 。当页面运行时,DevTools捕获性能指标。
2、等待一段时间,期间可以执行一些自己想要检测的操作
3、点击红点或者点击stop停止录制查看结果
官方已经写得很通俗易懂了不需要再概括了,请直接看官方教程
文中也给了一些优化建议,有兴趣也可以看看。
注:教程中fps分析部分已经过时这里可以查看页面FPS分析
原始版本的工具叫profiles,chrome87+以后一部分改为了memory和performance。
开发过程中难免会遇到内存问题,本次笔记主要是记录一下项目运行过程中内存情况的解析工具。
如果只想查看当前浏览器的各个 tab 正在使用的内存量,则在设置 - 更多工具 - 任务管理器
即可。效果如下图:
上面有三个按钮:
下面详细介绍一下三个功能(时间关系这里直接粘贴了原文内容)
给个 html,里面只有一句 js 代码 var _____testArray_____ = [ {value: 'hello'} ];
,打个堆栈看看:
右上那块区域,从左到右有三个操作:查看方式、对象归类的筛选、对象选择。
左边有 Summary
字样的那个,可以选择查看内存快照的方式,可选方式如下:
附上 Comparison 效果,大致如下:
代码:
var _____testArray_____ = [{ value: 'hello' }] function someTodo() { _____testArray_____.push({ value: ':::::::::' }) } document.querySelector('#btn').addEventListener('click', someTodo, false)
点击按钮后,数组中 push 了新的一项对象
图(array 那块列表展开就看不到下面列表了,就没展开):
附上 Containment 视图,它的排列稍微有些不同,大致如下:
入口有:
中间的 Class filter
只能够按照列出来的 Constructor 值进行筛选。
右边的 All objects
能够选择查看哪些阶段的对象、如”Objects allocated before Snapshot1″、”Objects allocated between Snapshot1 and Snapshot2″
右中那块区域显示的内存快照信息,可以在各个数据上右键选择一些操作( Reveal in Summary view
),各个字段代表信息如下:
右下那块区域显示的是被选中对象的详细信息,如上面图片的内容一样一样的…可以在各个数据上右键选择一些操作( Reveal in Summary view
)。
注意:图中最最下面那块最有用,就是搜索,ctrl/command + f 唤出
最后,根据上面的图来分析一下上面代码产生的效果,根据 js 的类型和引用的关系来分析,变量_____testArray_____
在列表中的情况是:
"hello" -> 在(string)列表里 -> string@353953 -> value in Object @362113 Object -> 在 Object 列表里 -> [0] in Array @356493 Array -> 在(array)列表里 -> _____testArray_____ in Window / @353829 Windows -> 在 Windows 列表里 -> Window / @353829
看完静态的快照,再来看看动态的。
代码如下:
var _____testArray_____ = [{ value: 'hello' }] var count = 1 function someTodo() { // 每次点击 字符串长度都以上一次为基础增加到5倍,拉大差异突出效果,并且之后在字符串头部加上count值做区分 count *= 5 var str = new Array(count * 10).join(':') _____testArray_____.push({ value: count + str }) } document.querySelector('#btn').addEventListener('click', someTodo, false)
选择 Allocation instrumentation on timeline
点击开始记录的按钮,然后得到如图所示:
每条线的高度与最近分配的对象大小对应,竖线的颜色表示这些对象是否仍然显示在最终的堆快照中。蓝色竖线表示在时间线最后对象仍然显示,灰色竖线表示对象已在时间线期间分配,但曾对其进行过垃圾回收。(这图中不是很明显,放大 devtool 面板后,图中的蓝色线顶部是有部分是灰色的…)
可以选择时间范围,查看该时间范围内的内存变化情况,如上图 5 次变化的情况分别是:
# 前面的数字代表本次记录索引,点击了5次 # 0 Shallow Size : 112 Constructor Distance Shallow Size Retained Size - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (array)×9 3 5008 0% 5008 0% (system)×60 3 2416 0% 2640 0% (closure)×1 3 4768 0% 2928 0% Object×3 3 144 0% 768 0% MouseEvent×3 4 112 0% 7200 0% (string)×2 5 96 0% 96 0% (concatenated string)×2 4 64 0% 160 0% Event 5 56 0% 2040 0% UIEvent 5 32 0% 648 0% # 1 (string)×2 5 296 0% 296 0% (concatenated string)×2 4 64 0% 360 0% Object 3 32 0% 392 0% # 2 (string)×2 5 1296 0% 1296 0% (concatenated string)×2 4 64 0% 1360 0% Object 3 32 0% 1392 0% # 3 (string)×2 5 6296 0% 6296 0% (concatenated string)×2 4 64 0% 6360 0% Object 3 32 0% 6392 0% # 4 (string)×2 5 31296 0% 31296 0% (array) 4 80 0% 80 0% (concatenated string)×2 4 64 0% 31360 0% (system) 4 32 0% 32 0% Object 3 32 0% 31392 0%
当勾选 Record allocation stacks
框后,还可以在 Allocation stack
面板里打印出调用堆栈。
如上面代码的效果:
这个功能仅根据名称和说明的话,不是很能看得懂是什么…
但是,还是通过一些案例给出了效果图,可以看出这块的功能应该是:哪些函数影响了内存的分配,并且该函数所耗内存在内存分配中占比多少。效果图如下:
图中函数可以直接点击跳转到函数定义的文件和位置。
这里主要以谷歌的技术文章为依据,此处主要是对参考文章的总结和摘要。
为了确保用户体验,我们通常围绕以下问题来进行性能的相关优化:
Is it happening? | 发生了么 | Did the navigation start successfully? Has the server responded? | 导航是否成功启动?服务器响应了吗? |
Is it useful? | 是有用的么 | Has enough content rendered that users can engage with it? | 是否渲染了足够的内容给用户? |
Is it usable? | 可以使用了么 | Can users interact with the page, or is it busy? | 用户可以与页面进行交互,还是页面仍在忙碌中? |
Is it delightful? | 流畅么 | Are the interactions smooth and natural, free of lag and jank? | 交互是否流畅,没有延迟和卡顿? |
计算公式:layout shift score = impact fraction * distance fraction
Frames Per Second(FPS): 是指画面每秒传输帧数
该处的内容会有一个专题来描述每个指标具体怎么看。
注意参考值中的“参考”,表示以下标准适用于大多数场景,但具体情况仍需要具体分析,不可一概而论。
最近项目中关于授权登录的内容比较多,涉及的同学比较多,但是大家的知识点有些参差不齐,这边的专题科普一下相关点,并抛出一个我关注的iframe中的第三方页面登录态问题
Single Sign-On,简单说就是一次访问,多处可用。
了解SSO之前,我们也可以了解一下CAS( Central Authentication Service ),来帮助我们跟深入的了解这个能力的背景:https://developer.ibm.com/zh/articles/os-cn-cas/
从官方文档总结来看,基础模式的SSO流程主要有以下步骤:
多点登录用一句话概括是,一个账号可以在多个端登录,但是每个端只能有一个该账号的登录实例。
IM是典型的多点登录应用。
多点登录一般不用于第三方登录,这里不做讨论。
第三方单点登录主要目的是授权,Oauth2.0,是现在最为推荐使用的授权机制。
入门:http://www.ruanyifeng.com/blog/2019/04/oauth_design.html
进阶:https://tools.ietf.org/html/rfc6749
既然有2.0,那就也有1.0,想要了解历史可以看下面的文章
说到授权我们通常会有3个角色:
该文章主要会从授权方和接入方角度分别讨论。
文章的所有讨论基于以下前提
写这篇文章的背景是因为chrome在80版本以上彻底禁止了iframe中第三方页面通过js操作cookie,但是接口可以通过设置sameSite来设置跨域的cookie。
当前这个问题在需要使用cookie的前提下还没有解决方案:https://support.google.com/analytics/thread/35313442?hl=en。
关于sameSite可以参考该文章:https://cloud.tencent.com/developer/article/1589715
safari也有同样的问题:http://vitr.github.io/safari-cookie-in-iframe/
而这个问题并不是覆盖所有的浏览器,那么项目中我们怎么对这个问题进行兼容,可以参考下面的策略。
cookie.set('the_cookie', 'the_value', '', '', { expires: 365, path: '/' }); const postData = { id: 'checkCookie', state: '0' }; if (cookie.get('the_cookie')) { postData.state = '1'; window.postMessage({ id: 'checkCookie', state: '1' }, '*'); } window.parent.postMessage(JSON.stringify(postData), '*'); if (window.opener) { window.opener.postMessage(JSON.stringify(postData), '*'); }
该段代码的功能就是通过postMessage通知父级页面(父级不仅是iframe的引用页面,也可以是通过window.open打开当前页面的网页)当前页面是否可以通过js操作cookie。
父级页面可以通过接收这个消息来决定sso登录授权的相关策略,是打开新页面还是直接在iframe里面完成业务操作。
这个场景是,我是个平台,我提供给第三方一些接口和SSO登录授权,第三方帮我开发一些功能然后通过iframe的方式嵌入到我的页面,让用户可以使用到这个功能。
Web Storage标准: https://www.w3.org/TR/webstorage/
这里主要从localStorage角度去描述。
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/localStorage
只读的localStorage 属性允许你访问一个Document 源(origin)的对象 Storage;存储的数据将保存在浏览器会话中。localStorage 类似 sessionStorage,但其区别在于:存储在 localStorage 的数据可以长期保留;而当页面会话结束——也就是说,当页面被关闭时,存储在 sessionStorage 的数据会被清除 。应注意,无论数据存储在 localStorage 还是 sessionStorage ,它们都特定于页面的协议。
另外,localStorage 中的键值对总是以字符串的形式存储。 (需要注意, 和js对象相比, 键值对总是以字符串的形式存储意味着数值类型会自动转化为字符串类型).
localStorage的API比较简单,只有增删查,改则是通新增覆盖原有的key,这里不做赘述,直接看文档。
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/localStorage
当前页面使用的storage被其他页面修改时会触发StorageEvent事件
这里在理解概念时着重注意的是,“当前页面使用”,“其他页面修改”,“才会触发当前页面的StorageEvent”。
言外之意是,当前页面使用当前页面修改不会触发当前页面的StorageEvent。
事件返回的event对象详情看文档:
https://developer.mozilla.org/zh-CN/docs/Web/API/StorageEvent
跨页面也是依赖该事件
LocalStorage 在大部分浏览器的存储大小为5MB
如果不确定可以通过工具(或者自己写代码)去探测
https://web.dev/storage-for-the-web/
Beware. This specification is no longer in active maintenance and the Web Applications Working Group does not intend to maintain it further.
This document was on the W3C Recommendation track but specification work has stopped. The specification reached an impasse: all interested implementors have used the same SQL backend (Sqlite), but we need multiple independent implementations to proceed along a standardisation path.
从上面的信息来看,简单说就是不建议使用该技术,请继续阅读IndexedDB或Web Storage的部分
http://www.ruanyifeng.com/blog/2018/07/indexeddb.html
通俗地说,IndexedDB 就是浏览器提供的本地数据库,它可以被网页脚本创建和操作。IndexedDB 允许储存大量数据,提供查找接口,还能建立索引。这些都是 LocalStorage 所不具备的。就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。IndexedDB 具有以下特点。
(1)键值对储存。 IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以”键值对”的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误。
(2)异步。 IndexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作,这与 LocalStorage 形成对比,后者的操作是同步的。异步设计是为了防止大量数据的读写,拖慢网页的表现。
(3)支持事务。 IndexedDB 支持事务(transaction),这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
(4)同源限制 IndexedDB 受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。
(5)储存空间大 IndexedDB 的储存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有上限。
(6)支持二进制储存。 IndexedDB 不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。
需要稳定的大存储的时候可以选用该方案处理。
另外indexedDB的操作主要是异步的,避免阻塞应用程序,如果需要同步操作可以另行查看资料。
AP简单来说主要是创建数据库和增删改查等操作。
这里的数据库还有一个版本的概念,并且在更新版本时(大于数据库的版本时)会触发upgradeneeded
事件
你可以通过这个事件来监听异步操作的完成,来处理后续逻辑。
其他API可以直接看文档,这里就不直接搬运了。
这里每个浏览器的策略各有不同,总结来看具备以下共通特征
关于存储的限制可以看一下资料: