DevDino 🦖

我曾七次鄙视自己的灵魂

  1. 使用多态代替条件判断

  2. 参数传入使用平铺参数代替对象参数
    没有必要包裹一层对象,增加创建和 GC 开销 benchmark

  3. 高频调用函数避免使用 rest/spread 运算符,编译到 ES5 要使用循环,还要创建数组,要避免在高频场景下使用(相比正常写法相差 6 倍) benchmark,还有额外的 GC 开销

  4. 手写 map 性能不如原生 benchmark

  5. 局部化极高频变量, 例如原来是 o.a.b,优化后直接访问 a benchmark

  6. instanceof 的条件判断可以用 map 优化

// setup.js
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var Origin = /** @class */ (function () {
function Origin() {
}
return Origin;
}());
var Base = /** @class */ (function (_super) {
__extends(Base, _super);
function Base() {
return _super !== null && _super.apply(this, arguments) || this;
}
return Base;
}(Origin));
var A = /** @class */ (function (_super) {
__extends(A, _super);
function A() {
return _super !== null && _super.apply(this, arguments) || this;
}
return A;
}(Base));
var B = /** @class */ (function (_super) {
__extends(B, _super);
function B() {
return _super !== null && _super.apply(this, arguments) || this;
}
return B;
}(Base));
var C = /** @class */ (function (_super) {
__extends(C, _super);
function C() {
return _super !== null && _super.apply(this, arguments) || this;
}
return C;
}(Base));
var D = /** @class */ (function (_super) {
__extends(D, _super);
function D() {
return _super !== null && _super.apply(this, arguments) || this;
}
return D;
}(Base));
var E = /** @class */ (function (_super) {
__extends(E, _super);
function E() {
return _super !== null && _super.apply(this, arguments) || this;
}
return E;
}(Base));
var F = /** @class */ (function (_super) {
__extends(F, _super);
function F() {
return _super !== null && _super.apply(this, arguments) || this;
}
return F;
}(Base));
var list = [];
for (var i = 0; i < 1000; i++) {
list.push(new D());
}
function a() {}
function b() {}
function c() {}
function d() {}
function e() {}
function f() {}
const HANDLER_BY_CONSTRUCTOR = new Map([
[A, a],
[B, b],
[C, c],
[D, d],
[E, e],
[F, f]
]);

function getCommonElementCreator(element) {
// 对于大多数单层继承的类,使用更快的方法
if (HANDLER_BY_CONSTRUCTOR.get(element.constructor) !== undefined) {
return HANDLER_BY_CONSTRUCTOR.get(element.constructor);
}
// 其他情况使用循环查找
let prototype = Object.getPrototypeOf(Object.getPrototypeOf(element));

while (prototype && prototype !== Base.prototype) {
const elementType = HANDLER_BY_CONSTRUCTOR.get(prototype.constructor);
if (elementType !== undefined) {
return elementType;
}
prototype = Object.getPrototypeOf(prototype);
}
return;
}

// case 1
list.forEach(function (element) {
if (element instanceof A) {
a();
}
else if (element instanceof B) {
b();
}
else if (element instanceof C) {
c();
}
else if (element instanceof D) {
d();
}
else if (element instanceof E) {
e();
}
else if (element instanceof F) {
f();
}
});

// case 2
list.forEach(function (element) {
const handler = getCommonElementCreator(element);

if (handler)(
handler()
)
});

阅读全文 »

  在做一个工具内截图的功能时发现的问题,Unit8Array 类型的数据转换成 blob 二进制数据然后上传到后端时出现错误。这里记录一下解决方法

Uint8Array ImageData的关系

阅读全文 »

背景

某日发布节点后,监控平台发现包体积超限,增长很多,于是拉了各个业务方进行排查

阅读全文 »