跳转到内容

减少代码体积

本节非常重要,优劣不同的写法会有明显的代码体积差异,而代码体积越小,会获得更快的加载速度。

推荐级别:强烈

统一支持 Treeshaking 是非常重要的,因为它可以在打包编译时移除未使用的代码,减小输出的文件大小。

在进行 JavaScript 封装时,请牢记以下两点:

  • 在能使用函数实现的情况下,优先使用函数而非 class 或 Object。只有需要频繁创建实例的情况才需要考虑使用 class。

  • 慎重使用 export default 导出。如果你的模块有多个导出,可以考虑逐个导出而非使用 default 导出,这样可以更好地遵循 Treeshaking 的原则,因为 default 导出整个模块会被引入,而逐个导出只会引入需要的部分。

反例 1

对象捆绑导出

const a = 1
const b = () => {}
// 未使用的变量仍会被打包
export default { a, b }

反例 2

class 方法捆绑

// 即使只使用单个方法也会引入整个类
export default class Utils {
a() {}
b() {}
}

反例 3

构造函数导出

// 方法被绑定在实例上无法分离
export default function Utils() {
this.a = () => {}
this.b = () => {}
}

反例 4

返回对象函数

// 方法仍会整体打包
export default function Utils() {
return {
a() {},
b() {},
}
}

正例 1

具名导出

const a = 1
const b = () => {}
export { a, b }

正例 2

独立导出

export const a = 1
export const b = () => {}

推荐级别:强烈

精准导入所需内容,避免引入冗余代码。

反例 1

多引入未使用

import { sayHi, sayBye } from './say.js'
sayHi('Vance') // sayBye 未被使用但仍会打包

反例 2

全量引入

import * as say from './say.js'
say.sayHi('Vance') // 引入整个模块

正例

精准引入

import { sayHi } from './say.js'
sayHi('Vance') // 仅引入必要方法

推荐级别:强烈

虽然平台支持 require,但应始终使用 ESM 规范以支持 TreeShaking。

反例

使用 require

const userInfo = require('./userInfo.js') // 无法 TreeShaking

正例

ESM 导入

import userInfo from './userInfo.js'
// 注意实际情况应避免全量导入,按需解构更佳

推荐级别:强烈

常量更易维护且利于 TreeShaking 识别未使用变量。

反例

对象打包

const a = { a1: 'a1', a2: 'a2', a3: 'a3' } // 全部属性会被打包
const b = ['a1', 'a2', 'a3'] // 数组元素无法分离

正例

独立常量

const a1 = 'a1' // 未使用时可被 TreeShaking
const a2 = 'a2'
const a3 = 'a3'
const a = { a1, a2, a3 }
const b = [a1, a2, a3]

推荐级别:建议

优先评估包体积,必要时进行源码裁剪。

反例

全量引入

import _ from 'lodash' // 引入完整包(代码量大)
export default {
onInit() {
_.join(['a', 'b', 'c'], '~') // 仅使用单个方法
},
}

正例

原生实现

export default {
onInit() {
;['a', 'b', 'c'].join('~') // 使用原生方法
},
}

推荐级别:强烈

避免全局样式引入导致冗余 CSS 打包。

反例

全量引入

<template>
<div class="yellow">黄色</div>
<div class="black">黑色</div>
<div class="green">绿色</div>
</template>
<style>
@import './color.css'; /* 可能包含未使用的样式 */
</style>

正例

<template>
<div class="yellow">黄色</div>
<div class="black">黑色</div>
<div class="green">绿色</div>
</template>
<style>
.yellow {
background: yellow;
}
.black {
background: black;
}
.green {
background: green;
}
</style>

推荐级别:鼓励

采用模块化设计原则,建议将不同功能模块拆分为独立页面文件。避免在单个页面中使用条件渲染实现多状态视图,这会导致模板复杂度增长。

反例

模板臃肿

<!-- 单一页面承载多状态视图 -->
<div>
<div if="{{status === 1}}">
<div>A功能视图组件</div>
<!-- 50+ 嵌套节点 -->
</div>
<div if="{{status === 2}}">
<div>B功能视图组件</div>
<!-- 50+ 嵌套节点 -->
</div>
</div>

正例

模块化拆分

<!-- pageA.ux -->
<template>
<div class="module-container">
<text>A功能核心组件</text>
<!-- 精简DOM结构 -->
</div>
</template>
<!-- pageB.ux -->
<template>
<div class="module-container">
<text>B功能核心组件</text>
<!-- 独立维护的视图 -->
</div>
</template>

推荐级别:建议

严格遵循最小权限原则,manifest.json 中应仅声明实际使用的 API 及权限。冗余配置会增加应用审核风险并影响启动性能。

推荐级别:建议

当应用仅支持单一语言时,建议直接使用硬编码文本而非国际化方案。多语言场景下应及时清理未使用的 i18n 键值。

推荐级别:建议

箭头函数相比传统函数表达式具有更简洁的语法结构,在代码压缩阶段能获得更好的优化效果。

反例

function fetchData() {
// 业务逻辑
}

正例

const fetchData = () => {
// 箭头函数实现
}

推荐级别:建议

对象属性名称应保持语义明确且简洁。由于 JavaScript 引擎无法对属性名进行 tree-shaking,建议采用短命名策略,特别是在高频使用的属性上。

反例

const userProfile = {
userIdentification: 'UXP-001',
profileModificationDate: '2024-03',
}

正例

const user = {
id: 'UXP-001',
update: '2024-03', // 上下文明确的短命名
}

推荐级别:建议

避免将调试阶段的数据、代码带到生产环境上,应该用编译时参数而非运行时参数来区分 编译环境变量

推荐级别:鼓励

采用原子化 CSS 设计模式,将高频样式声明抽象为可复用类。可以使用 Sass/Less 预处理工具管理样式资源。

反例

<style>
.component-a {
width: 80px;
margin: 16px;
border-radius: 8px;
}
.component-b {
width: 80px;
padding: 16px;
border-radius: 8px;
}
</style>

正例

<style>
/* 基础原子类 */
.full-width {
width: 80px;
}
.padding-md {
padding: 16px;
}
.margin-md {
margin: 16px;
}
.rounded {
border-radius: 8px;
}
/* 组件专属样式 */
.component-b {
background: #f0f2f5;
}
</style>