阿里妹导读:随着前端的范畴逐渐扩大,深度逐渐下沉,富前端必然带来的一个问题就是性能。特别是在大型复杂项目中,重前端业务可能因为一个小小的数据依赖,导致整个页面卡顿甚至崩溃。本文基于Quick BI(数据可视化分析平台)历年架构变迁中性能的排查、解决和总结出的“个性”问题,尝试总结整个前端层面相对“共性”的问题,提供一些前端性能解决思路。
文末福利:超全学习资料,免费领。
-
弱(普通)网络下,首屏资源下载耗时长
-
资源解压解析执行慢
const FooComponent = () => {
const data = useSelector(state => state.fullData);
return <Bar baz={data.bar.baz} />;
};
// a.tsx
export const a = {
name: 'a',
};
// b.tsx
import { a } = b;
saveData(_.cloneDeep(a)); // 假设需要克隆后落库到后端数据库
const Foo = () => { // 1. Foo可用React.memo,避免无props变更时渲染
const result = calc(); // 2. 组件内不可使用直接执行的逻辑,需要用useEffect等封装
return <Bar result={result} />; // 3.render处可用React.useMemo,仅对必要的数据依赖作渲染
};
const a = { b: { c: { d: 123 }, c2: { d2: 321 } } };
const merged = fp.defaultsDeep({ b: { c3: 3 } }, a);
console.log(merged.b.c === a.b.c); // 打印 false
-
按entry入口构建。
-
一个或多个共享包供多entry使用。
-
entry入口轻量化。
-
共享代码以chunk方式自动生成,并建立依赖关系。
-
大资源包动态导入(异步import)。
{ =
//...
optimization: {
splitChunks: {
chunks: 'async',
minSize: 20000,
minRemainingSize: 0,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 30,
maxInitialRequests: 30,
automaticNameDelimiter: '~',
enforceSizeThreshold: 50000,
cacheGroups: {
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
};
-
模块被共享或模块来自于node_modules。
-
chunk必须大于20kb。
-
同一时间并行加载的chunk或初始包不得超过30。
“你项目中有60%以上的代码并没有被使用到!”
-
在package.json中标记sideEffects为false。
-
或 在webpack配置中 module.rules 添加sideEffects过滤。
-
[必须] 模块务必es6 module化(即export 和 import)。
-
[必须] 三方包或数据文件(如地图数据、demo数据)超过 400KB 必须动态按需加载(异步import)。
-
[禁止] 禁止使用export * as方式输出(可能导致tree-shaking失效并且难以追溯)。
-
[推荐] 尽可能引入包中具体文件,避免直接引入整个包(如:import { Toolbar } from '@alife/foo/bar')。
-
[必须] 依赖的三方包必须在package.json中标记为sideEffects: false(或在webpack配置中标记)。
constob j= {
prop: 42
};
Object.freeze(obj);
obj.prop=33; // Throws an error in strict mode
-
属性在什么地方被读取。
-
属性在什么地方被变更。
-
属性对应的访问链路是什么。
const a = { b: { c: { d: 123 } } };
watchObject(a);
const c =a.b.c;
c.d =0; // Print: Modify: "a.b.c.d"
-
尽可能memo耗时逻辑。
-
无多余memo依赖项。
const a = { b: { c: { d: 123 }, c2: { d2: 321 } } };
const merged = immutableDefaultsDeep(a, { b: { c3: 3 } });
console.log(merged === a); // 打印 false
console.log(merged.b.c === a.b.c); // 打印 true
开发者如何自我提升?如何拓展自身技能,补齐技术短板?阿里巴巴有哪些技术沉淀,如何学习借鉴?阿里技术免费开放超全开发者学习资料,含上百本阿里系技术电子书、各技术大会资料合集、知识图谱、面试宝典等,助力所有开发者共同学习进步!
识别下方二维码加「阿里妹」微信好友,回复 “资料大全” 立即领取吧~
文章评论