weixin-minigame-dev
SkillFiles & storageA curated guide to convention files AI agents read, write, and act on: AGENTS.md, CLAUDE.md, SKILL.md, llms.txt, MCP configs, rules, and examples.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the weixin-minigame-dev skill
What this skill tells your AI
The instructions your AI receives, as published by itamarzand88/awesome-agent-conventions in conventions/skill-md/examples/domain-specific-niche/weixin-minigame-dev/SKILL.md and read by ahel’s review.
name: weixin-game description: 微信小游戏开发技术限制与最佳实践指南,帮助 Claude Code 在开发微信小游戏时遵循正确的 API 和技术规范。 version: 1.0.0 author: community tags:
- weixin
- minigame
- game-development
- canvas
微信小游戏开发技术限制与最佳实践
指导 Claude Code 在开发微信小游戏时遵循技术限制和实现规范。
触发条件
TRIGGER when:
- 用户提到"微信小游戏"、"小游戏开发"、"微信游戏"
- 代码中使用
wx.API(如wx.createCanvas、wx.onTouchStart等) - 项目包含
game.json或project.config.json(微信小游戏配置文件) - 用户询问关于 Canvas 游戏在微信环境的适配
DO NOT trigger when:
- 开发普通 Web 应用或 H5 页面
- 使用其他小程序框架(如 uni-app、taro 开发普通小程序)
- 纯浏览器环境游戏开发
核心技术限制
1. 运行环境差异
微信小游戏运行在 JavaScriptCore/V8 引擎中,不是浏览器环境:
| 特性 | 浏览器 | 微信小游戏 |
|---|---|---|
| 全局对象 | window | globalThis |
| DOM | document.* | 不支持 |
| Canvas 创建 | document.createElement('canvas') | wx.createCanvas() |
| 图片加载 | new Image() | wx.createImage() |
| 存储 | localStorage | wx.setStorageSync() |
| 音频 | new Audio() | wx.createInnerAudioContext() |
| 网络 | fetch() / XMLHttpRequest | wx.request() |
2. 包大小限制
主包限制: 4MB
分包总限制: 20MB
单分包限制: 2MB(建议不超过 1.5MB)
应对策略:
- 使用分包加载(
subpackages配置) - 资源远程加载(CDN)
- 图片压缩、音频压缩
- 代码混淆和压缩
3. Canvas API 限制
// ❌ 不支持的 API
ctx.roundRect() // 需手动实现圆角矩形
ctx.toDataURL() // 部分限制
ctx.getImageData() // 性能敏感
// ✅ 手动实现圆角矩形
function drawRoundRect(ctx, x, y, w, h, r) {
ctx.beginPath()
ctx.moveTo(x + r, y)
ctx.lineTo(x + w - r, y)
ctx.quadraticCurveTo(x + w, y, x + w, y + r)
ctx.lineTo(x + w, y + h - r)
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h)
ctx.lineTo(x + r, y + h)
ctx.quadraticCurveTo(x, y + h, x, y + h - r)
ctx.lineTo(x, y + r)
ctx.quadraticCurveTo(x, y, x + r, y)
ctx.closePath()
}
4. 颜色格式限制
// ❌ 部分格式不支持或不稳定
ctx.fillStyle = '#00d4ff40' // 带透明度的简写 hex
ctx.fillStyle = 'hsl(200, 100%, 50%)' // HSL 格式
// ✅ 推荐使用 rgba
ctx.fillStyle = 'rgba(0, 212, 255, 0.25)'
ctx.fillStyle = '#00d4ff' // 标准 hex
5. 网络请求限制
// 必须配置合法域名(小程序后台配置)
// 仅支持 HTTPS
// 请求超时默认 60 秒
// ❌ 不支持
fetch('https://api.example.com/data')
// ✅ 使用 wx.request
wx.request({
url: 'https://api.example.com/data',
method: 'GET',
success(res) {
console.log(res.data)
},
fail(err) {
console.error(err)
}
})
// WebSocket 限制
wx.connectSocket({
url: 'wss://socket.example.com' // 必须是 wss
})
API 适配指南
全局变量
// ❌ 浏览器写法
window.gameState = {}
window.myGlobal = value
// ✅ 微信小游戏写法
// 方案1: 使用 globalThis
globalThis.gameState = {}
// 方案2: 文件顶层定义
let gameState = {} // 模块级变量
// 方案3: 创建全局管理器
// GameGlobal.js
export const GameGlobal = {
state: {},
config: {}
}
Canvas 管理
// 主 Canvas(屏幕 Canvas)
const mainCanvas = wx.createCanvas()
const ctx = mainCanvas.getContext('2d')
// 离屏 Canvas(用于缓存、预渲染)
const offCanvas = wx.createOffscreenCanvas({
type: '2d',
width: 512,
height: 512
})
// 获取实际显示尺寸
const { windowWidth, windowHeight } = wx.getSystemInfoSync()
mainCanvas.width = windowWidth
mainCanvas.height = windowHeight
图片加载
// ✅ 微信小游戏图片加载
function loadImage(src) {
return new Promise((resolve, reject) => {
const img = wx.createImage()
img.onload = () => resolve(img)
img.onerror = (err) => reject(err)
img.src = src // 相对路径或配置的 CDN 域名
})
}
// 加载多张图片
async function loadAssets() {
const assets = {
player: await loadImage('images/player.png'),
enemy: await loadImage('images/enemy.png'),
bg: await loadImage('images/background.png')
}
return assets
}
触摸事件
// 微信使用全局触摸事件,不是 Canvas 上的事件
class TouchManager {
constructor() {
this.touches = new Map()
this.callbacks = {
start: [],
move: [],
end: []
}
this.init()
}
init() {
wx.onTouchStart(e => this.handleTouch('start', e))
wx.onTouchMove(e => this.handleTouch('move', e))
wx.onTouchEnd(e => this.handleTouch('end', e))
wx.onTouchCancel(e => this.handleTouch('end', e))
}
handleTouch(type, e) {
e.touches.forEach(touch => {
this.callbacks[type].forEach(cb => cb(touch))
})
}
on(type, callback) {
this.callbacks[type].push(callback)
}
}
// 使用
const touchManager = new TouchManager()
touchManager.on('start', (touch) => {
console.log('Touch at:', touch.clientX, touch.clientY)
})
音频播放
// 音频管理器
class AudioManager {
constructor() {
this.sounds = new Map()
this.music = null
this.muted = false
}
// 加载音效
loadSound(name, src) {
const audio = wx.createInnerAudioContext()
audio.src = src
this.sounds.set(name, audio)
return audio
}
// 播放音效
playSound(name, volume = 1.0) {
if (this.muted) return
const audio = this.sounds.get(name)
if (audio) {
audio.volume = volume
audio.stop()
audio.play()
}
}
// 播放背景音乐
playMusic(src, loop = true) {
if (this.music) {
this.music.stop()
this.music.destroy()
}
this.music = wx.createInnerAudioContext()
this.music.src = src
this.music.loop = loop
this.music.play()
}
// 销毁所有音频
destroy() {
this.sounds.forEach(audio => audio.destroy())
this.sounds.clear()
if (this.music) {
this.music.destroy()
this.music = null
}
}
}
本地存储
// ✅ 微信存储 API
// 同步存储
wx.setStorageSync('playerData', { level: 5, score: 1000 })
const data = wx.getStorageSync('playerData') || {}
// 异步存储(推荐用于大数据)
wx.setStorage({
key: 'largeData',
data: largeObject,
success() { console.log('Saved') },
fail(err) { console.error(err) }
})
// 删除
wx.removeStorageSync('key')
wx.clearStorageSync() // 清空所有
布局注意事项
1. 右上角菜单按钮区域
微信小游戏右上角有固定的操作菜单按钮("..."按钮),点击后显示菜单选项。必须避开此区域放置关键UI元素。
┌─────────────────────────────────┐
│ [≡] [•••] │ ← 右上角菜单按钮区域(约44px高度)
│ │
│ 安全区 (safeArea) │ ← 主要内容区域
│ │
│ │
│ │
│ _______________________________│ ← 底部安全区域(iPhone X系列手势条)
└─────────────────────────────────┘
避开区域尺寸:
- 右上角菜单按钮:高度约 44px,宽度约 87px(iOS)/ 48px(Android)
- 状态栏:
systemInfo.statusBarHeight - 底部手势条:iPhone X系列约 34px
// 获取安全区域信息
const systemInfo = wx.getSystemInfoSync()
const { safeArea, statusBarHeight } = systemInfo
// 安全区域边界
console.log('安全区域:', {
top: safeArea.top, // 安全区域顶部 y 坐标
bottom: safeArea.bottom, // 安全区域底部 y 坐标
left: safeArea.left, // 安全区域左侧 x 坐标
right: safeArea.right, // 安全区域右侧 x 坐标
width: safeArea.width, // 安全区域宽度
height: safeArea.height // 安全区域高度
})
// 右上角按钮区域(保守估计)
const menuButtonArea = {
top: statusBarHeight,
height: 44,
right: systemInfo.windowWidth,
width: 87 // iOS 较宽,Android 较窄
}
2. 安全区域适配方案
class SafeAreaManager {
constructor() {
const systemInfo = wx.getSystemInfoSync()
this.safeArea = systemInfo.safeArea
this.screenWidth = systemInfo.windowWidth
this.screenHeight = systemInfo.windowHeight
this.statusBarHeight = systemInfo.statusBarHeight
// 计算危险区域(需要避开)
this.dangerAreas = {
// 顶部:状态栏 + 菜单按钮
top: {
y: 0,
height: Math.max(this.safeArea.top, this.statusBarHeight + 44)
},
// 右上角:菜单按钮
topRight: {
x: this.screenWidth - 100,
y: 0,
width: 100,
height: this.statusBarHeight + 44
},
// 底部:手势条区域(iPhone X系列)
bottom: {
y: this.safeArea.bottom,
height: this.screenHeight - this.safeArea.bottom
}
}
}
// 检查坐标是否在安全区域
isInSafeArea(x, y, width = 0, height = 0) {
const danger = this.dangerAreas
// 检查是否与顶部危险区域重叠
if (y < danger.top.height) return false
// 检查是否与右上角危险区域重叠
if (x + width > danger.topRight.x && y < danger.topRight.height) return false
// 检查是否与底部危险区域重叠
if (y + height > danger.bottom.y) return false
return true
}
// 获取建议的安全布局边界
getSafeBounds() {
return {
top: this.dangerAreas.top.height,
bottom: this.safeArea.bottom,
left: this.safeArea.left,
right: this.safeArea.right
}
}
// 调整元素位置到安全区域
adjustToSafeArea(x, y, width, height) {
const bounds = this.getSafeBounds()
// 调整 x 坐标
if (x < bounds.left) x = bounds.left
if (x + width > bounds.right) x = bounds.right - width
// 调整 y 坐标
if (y < bounds.top) y = bounds.top
if (y + height > bounds.bottom) y = bounds.bottom - height
return { x, y }
}
}
// 使用示例
const safeArea = new SafeAreaManager()
// 放置按钮时检查
const button = { x: 10, y: 10, width: 100, height: 44 }
if (!safeArea.isInSafeArea(button.x, button.y, button.width, button.height)) {
// 调整到安全区域
const adjusted = safeArea.adjustToSafeArea(button.x, button.y, button.width, button.height)
button.x = adjusted.x
button.y = adjusted.y
}
3. 常见布局问题
// ❌ 错误:按钮放在右上角菜单按钮下方
const button = { x: screenWidth - 120, y: 20 }
// ✅ 正确:按钮放在安全区域内
const safeY = safeArea.top + 10
const button = { x: screenWidth - 120, y: safeY }
// ❌ 错误:忽略底部手势条
const bottomButton = { y: screenHeight - 50 }
// ✅ 正确:考虑底部安全区域
const safeBottomY = safeArea.bottom - 50 - 10
const bottomButton = { y: safeBottomY }
4. 多设备适配
// 获取设备信息
const deviceInfo = wx.getDeviceInfo()
const isIPhoneX = deviceInfo.model.includes('iPhone X') ||
deviceInfo.model.includes('iPhone 1') // iPhone 11, 12, 13, 14, 15 系列
// iPhone X 系列特殊处理
if (isIPhoneX) {
// 底部额外留白
this.bottomPadding = 34
}
屏幕适配方案
class ScreenAdapter {
constructor(designWidth = 375, designHeight = 667) {
this.designWidth = designWidth
this.designHeight = designHeight
const info = wx.getSystemInfoSync()
this.screenWidth = info.windowWidth
this.screenHeight = info.windowHeight
this.pixelRatio = info.pixelRatio
this.safeArea = info.safeArea
// 计算缩放(保持宽高比)
this.scale = Math.min(
this.screenWidth / designWidth,
this.screenHeight / designHeight
)
// 计算偏移(居中)
this.offsetX = (this.screenWidth - designWidth * this.scale) / 2
this.offsetY = (this.screenHeight - designHeight * this.scale) / 2
}
// 屏幕坐标 -> 游戏坐标
screenToGame(x, y) {
return {
x: (x - this.offsetX) / this.scale,
y: (y - this.offsetY) / this.scale
}
}
// 游戏坐标 -> 屏幕坐标
gameToScreen(x, y) {
return {
x: x * this.scale + this.offsetX,
y: y * this.scale + this.offsetY
}
}
// 获取安全区域(避开刘海屏、底部手势条)
getSafeArea() {
return {
top: this.safeArea.top,
bottom: this.safeArea.bottom,
left: this.safeArea.left,
right: this.safeArea.right
}
}
}
性能优化建议
1. 渲染优化
// ❌ 每帧都清除整个画布
ctx.clearRect(0, 0, canvas.width, canvas.height)
// ✅ 只清除变化区域(对于静态背景)
ctx.clearRect(obj.x - 1, obj.y - 1, obj.width + 2, obj.height + 2)
// ✅ 使用离屏 Canvas 缓存静态元素
const cacheCanvas = wx.createOffscreenCanvas({ width: 200, height: 200 })
const cacheCtx = cacheCanvas.getContext('2d')
// 绘制一次
cacheCtx.drawImage(backgroundImg, 0, 0)
// 主循环中直接绘制缓存
ctx.drawImage(cacheCanvas, 0, 0)
2. 对象池
class ObjectPool {
constructor(createFn, initialSize = 10) {
this.createFn = createFn
this.pool = []
this.active = []
// 预创建对象
for (let i = 0; i < initialSize; i++) {
this.pool.push(createFn())
}
}
get() {
const obj = this.pool.pop() || this.createFn()
this.active.push(obj)
return obj
}
release(obj) {
const index = this.active.indexOf(obj)
if (index > -1) {
this.active.splice(index, 1)
this.pool.push(obj)
}
}
releaseAll() {
while (this.active.length) {
this.pool.push(this.active.pop())
}
}
}
// 使用示例:子弹池
const bulletPool = new ObjectPool(() => ({ x: 0, y: 0, active: false }), 20)
3. 资源管理
// 资源预加载
class AssetLoader {
constructor() {
this.images = new Map()
this.audios = new Map()
}
async loadImages(list) {
const promises = list.map(item =>
loadImage(item.src).then(img => {
this.images.set(item.name, img)
return { name: item.name, img }
})
)
return Promise.all(promises)
}
getImage(name) {
return this.images.get(name)
}
}
// 使用
const loader = new AssetLoader()
await loader.loadImages([
{ name: 'player', src: 'images/player.png' },
{ name: 'enemy', src: 'images/enemy.png' }
])
高级功能与限制
1. 开放数据域(排行榜)
微信小游戏的好友排行榜必须在开放数据域中实现,主域无法直接访问好友数据。
项目结构:
├── game.js # 主域入口
├── open-data-context/ # 开放数据域
│ └── index.js # 排行榜逻辑
└── game.json # 配置
game.json 配置:
{
"openDataContext": "open-data-context"
}
主域与开放数据域通信:
// 主域 game.js
const openDataContext = wx.getOpenDataContext()
// 发送消息到开放数据域
openDataContext.postMessage({
type: 'updateScore',
score: 1000,
level: 5
})
// 创建共享 Canvas(用于显示排行榜)
const sharedCanvas = openDataContext.canvas
sharedCanvas.width = 300
sharedCanvas.height = 400
// 在主 Canvas 上绘制共享 Canvas
const mainCtx = mainCanvas.getContext('2d')
mainCtx.drawImage(sharedCanvas, 50, 100)
开放数据域 index.js:
// 接收主域消息
wx.onMessage(data => {
if (data.type === 'updateScore') {
// 更新用户数据到云端
wx.setUserCloudStorage({
KVDataList: [{
key: 'score',
value: JSON.stringify({ score: data.score, level: data.level })
}],
success() {
console.log('分数上传成功')
// 刷新排行榜
getFriendRanking()
}
})
}
if (data.type === 'getRanking') {
getFriendRanking()
}
})
// 获取好友排行榜
function getFriendRanking() {
wx.getFriendCloudStorage({
keyList: ['score'],
success(res) {
// res.data 是好友数据数组
const sorted = res.data.sort((a, b) => {
const scoreA = JSON.parse(a.KVDataList[0].value).score
const scoreB = JSON.parse(b.KVDataList[0].value).score
return scoreB - scoreA
})
// 绘制排行榜到 Canvas
drawRanking(sorted)
}
})
}
// 绘制排行榜
function drawRanking(data) {
const canvas = wx.createCanvas()
const ctx = canvas.getContext('2d')
ctx.fillStyle = '#fff'
ctx.fillRect(0, 0, canvas.width, canvas.height)
ctx.fillStyle = '#333'
ctx.font = '14px Arial'
data.forEach((player, index) => {
const score = JSON.parse(player.KVDataList[0].value).score
ctx.fillText(`${index + 1}. ${player.nickname}: ${score}`, 10, 30 + index * 25)
})
}
重要限制:
wx.getFriendCloudStorage()只能在开放数据域调用- 开放数据域无法使用大部分
wx.API(如网络请求受限) - 开放数据域有独立的 Canvas,通过
sharedCanvas与主域共享
2. 多线程 Worker
用于将耗时计算放到后台线程,避免阻塞主线程。
// 主线程
const worker = wx.createWorker('workers/physics.js')
// 发送数据
worker.postMessage({
type: 'calculate',
bodies: physicsData
})
// 接收结果
worker.onMessage(res => {
if (res.type === 'result') {
// 更新物理状态
updatePhysics(res.data)
}
})
// workers/physics.js
worker.onMessage(data => {
if (data.type === 'calculate') {
// 执行耗时计算
const result = heavyPhysicsCalculation(data.bodies)
// 返回结果
worker.postMessage({
type: 'result',
data: result
})
}
})
3. 内存管理
微信小游戏对内存敏感,需要主动管理:
// 监听内存警告
wx.onMemoryWarning((res) => {
console.log('内存警告,级别:', res.level) // level: 0-5,越大越严重
// 清理缓存
textureCache.clear()
audioCache.clear()
// 释放未使用的资源
gc()
})
// 主动触发垃圾回收(调试用)
wx.triggerGC()
// 获取内存使用情况
const performance = wx.getPerformance()
const memory = performance.getEntriesByType('memory')
console.log('内存使用:', memory)
内存优化建议:
// 1. 及时销毁音频
const audio = wx.createInnerAudioContext()
audio.src = 'sound.mp3'
audio.play()
audio.onEnded(() => {
audio.destroy() // 播放完毕后销毁
})
// 2. 图片对象池
class ImagePool {
constructor(maxSize = 20) {
this.pool = new Map()
this.maxSize = maxSize
}
get(src) {
if (this.pool.has(src)) {
return this.pool.get(src)
}
const img = wx.createImage()
img.src = src
if (this.pool.size >= this.maxSize) {
// 移除最旧的
const firstKey = this.pool.keys().next().value
this.pool.delete(firstKey)
}
this.pool.set(src, img)
return img
}
}
// 3. 避免内存泄漏
class GameManager {
constructor() {
this.listeners = []
}
addListener(callback) {
this.listeners.push(callback)
}
destroy() {
// 清除所有监听器
this.listeners = []
}
}
4. 分享功能
// 被动分享(用户点击右上角菜单)
wx.onShareAppMessage(() => {
return {
title: '来挑战我的高分!',
imageUrl: 'images/share.png',
query: 'level=5&score=1000' // 参数会传递给被分享者
}
})
// 主动分享
wx.shareAppMessage({
title: '我通关了第5关!',
imageUrl: 'images/share-level5.png',
query: 'from=share&level=5',
success() {
console.log('分享成功')
},
fail(err) {
console.error('分享失败', err)
}
})
// 分享到群
wx.shareAppMessage({
title: '一起来玩!',
imageUrl: 'images/share.png',
toGroup: true
})
5. 虚拟支付
// 发起支付(需在小程序后台开通)
wx.requestMidasPayment({
mode: 'game',
env: 0, // 0: 正式环境, 1: 沙箱环境
offerId: '123456', // 商品ID
currencyType: 'CNY',
buyQuantity: 10,
success(res) {
console.log('支付成功', res)
// 发放道具
},
fail(err) {
console.error('支付失败', err)
}
})
6. 版本兼容
// 检查 API 是否可用
if (wx.canIUse('getDeviceInfo')) {
const deviceInfo = wx.getDeviceInfo()
}
// 比较基础库版本
function compareVersion(v1, v2) {
v1 = v1.split('.')
v2 = v2.split('.')
const len = Math.max(v1.length, v2.length)
while (v1.length < len) v1.push('0')
while (v2.length < len) v2.push('0')
for (let i = 0; i < len; i++) {
const num1 = parseInt(v1[i])
const num2 = parseInt(v2[i])
if (num1 > num2) return 1
if (num1 < num2) return -1
}
return 0
}
const systemInfo = wx.getSystemInfoSync()
const baseVersion = systemInfo.SDKVersion
if (compareVersion(baseVersion, '2.10.0') >= 0) {
// 使用新 API
} else {
// 降级处理
}
常见错误与解决
错误 1: window is not defined
// ❌ 使用 window
window.myVar = value
// ✅ 使用 globalThis 或模块变量
globalThis.myVar = value
错误 2: document is not defined
// ❌ 使用 document
const el = document.getElementById('xxx')
document.createElement('canvas')
// ✅ 使用微信 API
const canvas = wx.createCanvas()
错误 3: 图片加载失败
// 检查路径是否正确
// 检查是否配置了 download 域名(网络图片)
// 检查图片格式(支持 png, jpg, gif)
wx.createImage()
img.onerror = (e) => {
console.error('Image load failed:', e)
}
错误 4: 音频无法播放
// 用户交互后才能播放音频
// 首次播放需要在 touchstart/touchend 回调中触发
let audioInitialized = false
wx.onTouchStart(() => {
if (!audioInitialized) {
// 初始化音频
audioInitialized = true
}
})
项目结构建议
my-minigame/
├── game.json # 游戏配置
├── game.js # 入口文件
├── project.config.json # 项目配置
├── js/
│ ├── Game.js # 游戏主类
│ ├── scenes/ # 场景
│ │ ├── MenuScene.js
│ │ └── GameScene.js
│ ├── entities/ # 实体类
│ │ ├── Player.js
│ │ └── Enemy.js
│ ├── managers/ # 管理器
│ │ ├── AudioManager.js
│ │ ├── InputManager.js
│ │ └── SceneManager.js
│ └── utils/ # 工具类
│ ├── ObjectPool.js
│ └── ScreenAdapter.js
├── images/ # 图片资源
├── audio/ # 音频资源
└── subpackages/ # 分包
├── level2/
└── level3/
game.json 配置示例
{
"deviceOrientation": "portrait",
"showStatusBar": false,
"networkTimeout": {
"request": 10000,
"connectSocket": 10000,
"uploadFile": 10000,
"downloadFile": 10000
},
"subpackages": [
{
"name": "level2",
"root": "subpackages/level2"
},
{
"name": "level3",
"root": "subpackages/level3"
}
],
"plugins": {}
}
检查清单
开发微信小游戏时,Claude Code 应确保:
基础 API 适配
- 不使用
window、document、DOMAPI - 使用
wx.createCanvas()创建 Canvas - 使用
wx.createImage()加载图片 - 使用
wx.createInnerAudioContext()播放音频 - 使用
wx.onTouchStart/Move/End处理触摸 - 使用
wx.setStorageSync/getStorageSync存储 - 使用
wx.request()进行网络请求 - 手动实现
roundRect()等不支持的 API - 颜色使用
rgba()或标准#RRGGBB格式
布局与安全区域
- 避开右上角菜单按钮区域(约 44px 高度)
- 使用
wx.getSystemInfoSync().safeArea获取安全区域 - 处理刘海屏顶部安全区域
- 处理底部手势条(iPhone X 系列约 34px)
- 关键 UI 元素不要放置在危险区域
性能与资源
- 实现屏幕适配和像素比适配
- 音频资源在用户交互后才能播放
- 实现对象池优化性能
- 使用分包加载控制包大小(主包 ≤4MB)
- 及时销毁音频、图片等资源
- 监听
wx.onMemoryWarning处理内存警告
高级功能
- 排行榜功能使用开放数据域实现
- 耗时计算使用 Worker 多线程
- 使用
wx.canIUse()检查 API 兼容性 - 分享功能配置正确的图片和参数
测试与调试
- 真机测试(开发者工具行为可能不同)
- 测试不同机型(刘海屏、全面屏、iPhone X 系列)
- 测试弱网环境
- 测试内存占用
Signals
- GitHub stars
- 31
- Forks
- 3
- Last commit
- Jul 2026
Advanced
- Catalog kind
- skill
- Gateway key
weixin-minigame-dev- Source
- github.com/itamarzand88/awesome-agent-conventions