作者:卡颂
简介:《React技术揭秘》作者
来源:SegmentFault 思否社区
大家好,我是卡颂。
当聊到Chrome,你第一反应是啥?
市占率第一的浏览器?鼎鼎大名的V8引擎?浏览器调试的标配——DevTools?
对于Chrome团队成员来说,第一反应很可能是这两个指标(KPI):
作为开发者,相信你能感受到诸多围绕这两个指标的改进:当一切都做到极致后,围绕这两个指标还有什么可挖掘的呢(KPI能写啥呢)?让我们一起看看Chrome团队为了更好的web体验,做了哪些曲线救国的努力。逻辑要顺
当今世界大部分web项目依赖开源工具
更好的开源工具带来更好的web体验
按照这个逻辑,只要我们(Chrome团队)与开源项目合作,让他们变得更好,那就是为更好的web体验做贡献(也就能拯救KPI了)。所以,只需要挑选合适的项目,根据其适合的优化类型(UX、DX),展开深度合作就行。接下来,让我们看看一些与Chrome团队合作的项目。
与Next.js合作
Next.js作为基于React的全功能生产可用框架,其SSR功能一直与React团队深度合作。Chrome团队基于SSR这一场景,为Next.js定制了一系列Timing API。新Timing API将SSR相关指标纳入统计(比如hydrate时间)。同时,LightHouse工具可以收集更多SSR相关数据供参考:
与Babel合作
我们常用@babel/preset-env根据目标浏览器版本将高级ES语法编译为ES5语法。这种降级编译的实现思路为:每个高级语法可以看作一或多个语法转换的集合。举个例子:函数参数可以作为解构、参数默认值、剩余参数这3个特性的集合。对于如下源代码:const foo = ({ a = 1 }, b = 2, ...args) => [a,b,args];
经过@babel/preset-env编译后的输出包含了解构、参数默认值、剩余参数这3个特性的实现:const foo = function foo(_ref, b) {
let { a = 1 } = _ref;
if (b === void 0) { b = 2; }
for (
var _len = arguments.length,
args = new Array(_len > 2 ? _len - 2 : 0),
_key = 2; _key < _len; _key++
) {
args[_key - 2] = arguments[_key];
}
return [a, b, args];
};
某些高级语法,现代浏览器可能或多或少已经支持了,只是支持度不好。对于以上例子中的语法,只有一款现代浏览器由于自身bug导致不支持。解决办法是:将{ a = 1 }替换为{ a: a = 1 }。所以,以上代码只需编译为如下形式在现代浏览器都能运行:const foo = ({ a: a = 1 }, b = 2, ...args) => [a,b,args];
这种浏览器间差异带来的优化空间,Babel团队很难独自完成。所以,Chrome团队与其合作开发了@babel/preset-modules,并且已经作为bugfixes参数集成到@babel/preset-env中。与React合作
作为前端领域运行时最重的视图库,React一直在寻找运行时的优化空间。navigator.scheduling.isInputPending API就是其与Chrome团队合作的产物。该API返回一个函数,调用该函数后如果当前有input事件正在调度,则返回true。比如如下例子,当有鼠标、键盘事件在调度时,暂停JS线程执行:while (workQueue.length > 0) {
if (navigator.scheduling.isInputPending(['mousedown', 'mouseup', 'keydown', 'keyup'])) {
break;
}
let job = workQueue.shift();
job.execute();
}
输入框的输入能够更快被浏览器渲染,显著减少浏览器调帧(表现为输入框输入内容卡顿)。总结
当项目发展到一定时期,没有多少内部可优化空间时,需要主动出击,赋能其他垂直领域,聚焦用户感知赛道,采用复用打法达成持久收益!
点击左下角阅读原文,到 SegmentFault 思否社区 和文章作者展开更多互动和交流,扫描下方”二维码“或在“公众号后台“回复“ 入群 ”即可加入我们的技术交流群,收获更多的技术文章~