[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fteam-documents\u002F07":3,"knowledge-related-\u002Fknowledge\u002Fteam-documents\u002F07":734,"knowledge-series-\u002Fknowledge\u002Fteam-documents\u002F07":758},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":16,"pinned":17,"draft":17,"body":18,"seo":730,"stem":731,"id":732,"extension":733},"\u002Fknowledge\u002Fteam-documents\u002F07","企业微信群工具打开缓慢原因分析","企业微信群工具首次打开耗时明显偏长，通过构建体积、静态资源阻塞、路由鉴权链路、SDK 初始化四个方向逐层排查，定位主要耗时集中在 wx.agentConfig 初始化，并给出排查步骤与优化建议。","团队文档",[12,13,14,15],"team","wecom","performance","geo","2020-04-12",false,{"type":19,"value":20,"toc":713},"minimark",[21,24,28,32,35,53,56,173,176,221,230,234,277,290,293,382,386,415,418,490,493,512,515,518,606,609,629,632,685,688,709],[22,23,8],"h1",{"id":8},[25,26,27],"h2",{"id":27},"背景",[29,30,31],"p",{},"企业微信群工具是嵌在企业微信「群」场景下的内嵌应用，用户从群聊侧边栏或群工具入口点击进入。由于入口路径较深、用户对「点开即用」的耐心更低，首次打开耗时过长会直接影响功能使用率，因此该问题被列为专项排查。",[25,33,34],{"id":34},"现象",[36,37,38,47,50],"ul",{},[39,40,41,42,46],"li",{},"用户反馈首次打开群工具耗时明显偏长，部分场景下超过 ",[43,44,45],"code",{},"1.5s"," 才可交互；",[39,48,49],{},"二次进入（缓存命中）速度明显更快，说明耗时与「首次初始化链路」强相关；",[39,51,52],{},"耗时并非稳定复现于所有用户，登录态是否有效、网络环境不同会导致耗时波动。",[25,54,55],{"id":55},"原因分析树",[57,58,63],"pre",{"className":59,"code":60,"language":61,"meta":62,"style":62},"language-mermaid shiki shiki-themes material-theme-lighter github-light github-dark","flowchart TD\n  A[群工具打开缓慢] --> B[构建产物体积偏大]\n  A --> C[静态资源存在阻塞]\n  A --> D[路由拦截链路较重]\n  A --> E[企业微信 SDK 初始化链路重复]\n\n  B --> B1[依赖未拆分，大型依赖打进主包]\n  B --> B2[未启用 gzip\u002Fbrotli 压缩]\n\n  C --> C1[关键资源未预加载]\n  C --> C2[未做 DNS 预解析]\n\n  D --> D1[登录态依赖 OAuth 跳转获取 code]\n  D --> D2[JSAPI 权限初始化链路长]\n  D1 --> D1a[\"拉取企业配置 → wx.config → wx.ready → wx.agentConfig\"]\n\n  E --> E1[同时引入 jweixin 与 wecom-jssdk]\n  E --> E2[wx.config 与 wx.agentConfig 各自初始化一次]\n","mermaid","",[43,64,65,73,79,85,91,97,104,110,116,121,127,133,138,144,150,156,161,167],{"__ignoreMap":62},[66,67,70],"span",{"class":68,"line":69},"line",1,[66,71,72],{},"flowchart TD\n",[66,74,76],{"class":68,"line":75},2,[66,77,78],{},"  A[群工具打开缓慢] --> B[构建产物体积偏大]\n",[66,80,82],{"class":68,"line":81},3,[66,83,84],{},"  A --> C[静态资源存在阻塞]\n",[66,86,88],{"class":68,"line":87},4,[66,89,90],{},"  A --> D[路由拦截链路较重]\n",[66,92,94],{"class":68,"line":93},5,[66,95,96],{},"  A --> E[企业微信 SDK 初始化链路重复]\n",[66,98,100],{"class":68,"line":99},6,[66,101,103],{"emptyLinePlaceholder":102},true,"\n",[66,105,107],{"class":68,"line":106},7,[66,108,109],{},"  B --> B1[依赖未拆分，大型依赖打进主包]\n",[66,111,113],{"class":68,"line":112},8,[66,114,115],{},"  B --> B2[未启用 gzip\u002Fbrotli 压缩]\n",[66,117,119],{"class":68,"line":118},9,[66,120,103],{"emptyLinePlaceholder":102},[66,122,124],{"class":68,"line":123},10,[66,125,126],{},"  C --> C1[关键资源未预加载]\n",[66,128,130],{"class":68,"line":129},11,[66,131,132],{},"  C --> C2[未做 DNS 预解析]\n",[66,134,136],{"class":68,"line":135},12,[66,137,103],{"emptyLinePlaceholder":102},[66,139,141],{"class":68,"line":140},13,[66,142,143],{},"  D --> D1[登录态依赖 OAuth 跳转获取 code]\n",[66,145,147],{"class":68,"line":146},14,[66,148,149],{},"  D --> D2[JSAPI 权限初始化链路长]\n",[66,151,153],{"class":68,"line":152},15,[66,154,155],{},"  D1 --> D1a[\"拉取企业配置 → wx.config → wx.ready → wx.agentConfig\"]\n",[66,157,159],{"class":68,"line":158},16,[66,160,103],{"emptyLinePlaceholder":102},[66,162,164],{"class":68,"line":163},17,[66,165,166],{},"  E --> E1[同时引入 jweixin 与 wecom-jssdk]\n",[66,168,170],{"class":68,"line":169},18,[66,171,172],{},"  E --> E2[wx.config 与 wx.agentConfig 各自初始化一次]\n",[25,174,175],{"id":175},"排查步骤",[177,178,179,186,192,198,215],"ol",{},[39,180,181,185],{},[182,183,184],"strong",{},"构建产物分析","：使用构建分析工具查看产物体积构成，确认是否存在超大依赖被打入主包；",[39,187,188,191],{},[182,189,190],{},"网络面板复查","：在企业微信内打开开发者工具（或用远程调试），观察关键资源加载时序，确认是否存在阻塞关键渲染路径的请求；",[39,193,194,197],{},[182,195,196],{},"登录态分区排查","：分别验证「未登录\u002F登录态失效」与「登录态有效」两种场景下的耗时差异，判断 OAuth 跳转是否是主要耗时来源；",[39,199,200,203,204,207,208,207,211,214],{},[182,201,202],{},"SDK 初始化埋点","：在 ",[43,205,206],{},"wx.config","、",[43,209,210],{},"wx.ready",[43,212,213],{},"wx.agentConfig"," 各阶段打点上报，统计各阶段平均耗时，定位真实瓶颈阶段；",[39,216,217,220],{},[182,218,219],{},"缓存命中对比","：对比首次进入与二次进入的耗时差异，确认缓存策略是否生效、生效后收益是否符合预期。",[29,222,223,224,226,227,229],{},"排查结论：主要耗时集中在 ",[43,225,213],{}," 初始化阶段；企业配置已做缓存后，命中缓存时不再重复请求配置，但 ",[43,228,213],{}," 本身仍需完整走一次企业微信侧校验。",[231,232,233],"h3",{"id":233},"关键链路说明",[36,235,236,247,258,267,272],{},[39,237,238,239,241,242,241,244,246],{},"页面依赖 JSAPI 权限，初始化链路为：拉取企业配置 → ",[43,240,206],{}," → ",[43,243,210],{},[43,245,213],{},"；",[39,248,249,250,252,253,255,256,246],{},"必须先执行 ",[43,251,206],{},"，并在 ",[43,254,210],{}," 回调之后再执行 ",[43,257,213],{},[39,259,260,261,263,264,266],{},"只有 ",[43,262,206],{}," 成功后，",[43,265,213],{}," 才可用；",[39,268,269,271],{},[43,270,206],{}," 主要用于基础 JS 能力（菜单、定位等）；",[39,273,274,276],{},[43,275,213],{}," 主要用于企业应用强相关能力（会话、消息等）。",[29,278,279,280,282,283,286,287,289],{},"登录态方面，若 ",[43,281,43],{}," 失效或未登录，需先跳转 ",[43,284,285],{},"https:\u002F\u002Fopen.weixin.qq.com\u002Fconnect\u002Foauth2\u002Fauthorize?appid=..."," 获取 ",[43,288,43],{}," 后完成登录，该跳转本身会带来一次额外的网络往返耗时。",[25,291,292],{"id":292},"优化建议",[294,295,296,313],"table",{},[297,298,299],"thead",{},[300,301,302,306,310],"tr",{},[303,304,305],"th",{},"方向",[303,307,309],{"align":308},"center","状态",[303,311,312],{},"具体措施",[314,315,316,332,342,353],"tbody",{},[300,317,318,322,325],{},[319,320,321],"td",{},"构建产物体积",[319,323,324],{"align":308},"✅",[319,326,327,328,331],{},"对依赖进行拆分，部分大型依赖改为 CDN 加载；构建产物启用 ",[43,329,330],{},"gzip"," 压缩；体积较大的模块按需拆分与单独加载",[300,333,334,337,339],{},[319,335,336],{},"静态资源阻塞",[319,338,324],{"align":308},[319,340,341],{},"对关键静态资源进行预加载；增加 DNS 预解析，减少首个请求的解析延迟",[300,343,344,347,350],{},[319,345,346],{},"路由与鉴权链路",[319,348,349],{"align":308},"✅（已做缓存优化）",[319,351,352],{},"对企业配置做缓存处理，命中缓存时不重复请求配置；仅在登录态失效时才走完整 OAuth 流程",[300,354,355,358,360],{},[319,356,357],{},"企业微信 SDK 升级",[319,359,324],{"align":308},[319,361,362,363,366,367,370,371,374,375,378,379],{},"用 ",[43,364,365],{},"ww.register"," 合并初始化，替代 ",[43,368,369],{},"jweixin"," + ",[43,372,373],{},"wecom-jssdk"," 双初始化；部分调用由 ",[43,376,377],{},"wx.invoke(xxx)"," 迁移为 ",[43,380,381],{},"ww.xxx()",[231,383,385],{"id":384},"企业微信-sdk-升级说明","企业微信 SDK 升级说明",[177,387,388,402,412],{},[39,389,390,391,393,394,396,397,207,399,401],{},"旧方案同时引入 ",[43,392,369],{}," 与 ",[43,395,373],{},"，初始化链路包含两次配置（",[43,398,206],{},[43,400,213],{},"）；",[39,403,404,405,407,408,378,410,246],{},"升级后采用合并方案，使用一次 ",[43,406,365],{}," 初始化；同时将部分调用由 ",[43,409,377],{},[43,411,381],{},[39,413,414],{},"升级后初始化耗时进一步下降，整体进入速度更稳定。",[25,416,417],{"id":417},"优化结果",[294,419,420,433],{},[297,421,422],{},[300,423,424,427,430],{},[303,425,426],{},"指标",[303,428,429],{},"优化前",[303,431,432],{},"优化后",[314,434,435,449,463,476],{},[300,436,437,440,443],{},[319,438,439],{},"生产环境构建产物体积",[319,441,442],{},"明显偏大",[319,444,445,446],{},"约 ",[43,447,448],{},"2.4M",[300,450,451,454,458],{},[319,452,453],{},"应用初始化耗时",[319,455,445,456],{},[43,457,45],{},[319,459,445,460],{},[43,461,462],{},"300ms",[300,464,465,468,471],{},[319,466,467],{},"缓存命中时页面进入耗时",[319,469,470],{},"较长且不稳定",[319,472,445,473],{},[43,474,475],{},"400ms",[300,477,478,481,484],{},[319,479,480],{},"首次登录\u002F登录态失效",[319,482,483],{},"耗时较长",[319,485,486,487],{},"需完整走流程，符合预期；二次进入可缩短至约 ",[43,488,489],{},"1s",[25,491,492],{"id":492},"总结",[177,494,495,498,506],{},[39,496,497],{},"通过依赖拆分 + CDN + 资源预加载，构建产物体积得到控制，整体请求时长缩短；",[39,499,500,501,503,504,246],{},"企业微信 SDK 升级后，应用初始化耗时由约 ",[43,502,45],{}," 降低至约 ",[43,505,462],{},[39,507,508,509,511],{},"缓存命中时页面进入耗时约 ",[43,510,475],{},"；若缓存或登录失效，加载时间会相应增加（符合预期），后续可考虑对 OAuth 跳转结果做更长时间的本地态缓存以进一步降低该场景耗时。",[25,513,514],{"id":514},"监控与报警建议",[29,516,517],{},"优化落地后，建议保留埋点长期观察，避免后续迭代中悄悄退化：",[294,519,520,533],{},[297,521,522],{},[300,523,524,527,530],{},[303,525,526],{},"监控点",[303,528,529],{},"采集方式",[303,531,532],{},"报警阈值参考",[314,534,535,550,566,584,595],{},[300,536,537,540,543],{},[319,538,539],{},"应用初始化总耗时",[319,541,542],{},"首屏埋点，从入口点击到可交互",[319,544,545,546,549],{},"均值超过 ",[43,547,548],{},"500ms"," 时排查",[300,551,552,560,563],{},[319,553,554,556,557,559],{},[43,555,206],{}," \u002F ",[43,558,213],{}," 各阶段耗时",[319,561,562],{},"分阶段埋点上报",[319,564,565],{},"单阶段耗时突增 2 倍以上时报警",[300,567,568,570,577],{},[319,569,321],{},[319,571,572,573,576],{},"CI 构建后统计 ",[43,574,575],{},"dist"," 体积，与上一次构建比较",[319,578,579,580,583],{},"单次构建体积增长超过 ",[43,581,582],{},"10%"," 时提示",[300,585,586,589,592],{},[319,587,588],{},"缓存命中率",[319,590,591],{},"统计企业配置缓存命中 \u002F 未命中比例",[319,593,594],{},"命中率明显下降时排查缓存失效逻辑",[300,596,597,600,603],{},[319,598,599],{},"OAuth 跳转触发率",[319,601,602],{},"统计需要完整走登录流程的会话占比",[319,604,605],{},"占比异常升高提示登录态维护存在问题",[25,607,608],{"id":608},"常见排查误区",[36,610,611,617,623],{},[39,612,613,616],{},[182,614,615],{},"只看平均耗时，忽略分布","：部分用户网络环境差、企业微信客户端版本旧，平均值容易掩盖长尾问题，建议同时观察 P75\u002FP90 分位数；",[39,618,619,622],{},[182,620,621],{},"把所有耗时都归因于 SDK","：实际排查中，构建产物体积、CDN 命中率、后端接口耗时都可能是影响因素，需要分阶段埋点定位，而不是直接归因于「企业微信慢」；",[39,624,625,628],{},[182,626,627],{},"忽略登录态失效场景","：若只在登录态有效的场景下测试优化效果，容易忽略 OAuth 跳转本身带来的耗时，上线前应覆盖「登录态失效」这一分支场景。",[25,630,631],{"id":631},"回归检查清单",[36,633,636,645,651,660,673,679],{"className":634},[635],"contains-task-list",[39,637,640,644],{"className":638},[639],"task-list-item",[641,642],"input",{"disabled":102,"type":643},"checkbox"," 登录态有效场景下，首次打开群工具耗时符合预期（对照优化后基线数据）；",[39,646,648,650],{"className":647},[639],[641,649],{"disabled":102,"type":643}," 登录态失效场景下，OAuth 跳转与回调链路正常，跳转前后参数不丢失；",[39,652,654,656,657,659],{"className":653},[639],[641,655],{"disabled":102,"type":643}," 缓存命中场景下，企业配置不重复请求，",[43,658,213],{}," 正常可用；",[39,661,663,665,666,668,669,672],{"className":662},[639],[641,664],{"disabled":102,"type":643}," ",[43,667,365],{}," 合并初始化后，原依赖 ",[43,670,671],{},"wx.invoke"," 的功能点（菜单、定位、会话等）逐一验证无回归；",[39,674,676,678],{"className":675},[639],[641,677],{"disabled":102,"type":643}," 构建产物体积、gzip\u002Fbrotli 压缩产物均正常生成，CDN 资源可正常加载；",[39,680,682,684],{"className":681},[639],[641,683],{"disabled":102,"type":643}," 弱网环境（模拟 3G\u002F4G）下手动验证一次完整打开链路，确认耗时增长在预期范围内。",[25,686,687],{"id":687},"相关链接",[36,689,690,697,703],{},[39,691,692],{},[693,694,696],"a",{"href":695},"\u002Fknowledge\u002Fteam-documents\u002F06","企业微信与小程序工单问题",[39,698,699],{},[693,700,702],{"href":701},"\u002Fknowledge\u002Fteam-documents\u002F13","新商家系统性能优化实践",[39,704,705],{},[693,706,708],{"href":707},"\u002Fknowledge\u002Fteam-documents\u002F20","H5 GPS 定位问题说明",[710,711,712],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":62,"searchDepth":75,"depth":75,"links":714},[715,716,717,718,721,724,725,726,727,728,729],{"id":27,"depth":75,"text":27},{"id":34,"depth":75,"text":34},{"id":55,"depth":75,"text":55},{"id":175,"depth":75,"text":175,"children":719},[720],{"id":233,"depth":81,"text":233},{"id":292,"depth":75,"text":292,"children":722},[723],{"id":384,"depth":81,"text":385},{"id":417,"depth":75,"text":417},{"id":492,"depth":75,"text":492},{"id":514,"depth":75,"text":514},{"id":608,"depth":75,"text":608},{"id":631,"depth":75,"text":631},{"id":687,"depth":75,"text":687},{"title":8,"description":9},"knowledge\u002Fteam-documents\u002F07","knowledge\u002Fknowledge\u002Fteam-documents\u002F07.md","md",{"items":735},[736,740,742,746,750,754],{"path":737,"title":738,"description":739,"category":10,"score":135},"\u002Fknowledge\u002Fteam-documents\u002F19","GridView 宫格加载渲染优化","系统首页 GridView 宫格模块接口耗时不高，但首次进入总耗时接近 22s。复盘耗时分层定位过程、代码层面的瓶颈（约 2000 行、100 个 tab 重复节点）、优化手段与最终指标对比。",{"path":695,"title":696,"description":741,"category":10,"score":135},"企微师傅端与商家小程序端长期共用一套代码，页面与组件嵌套边界不清晰、引入规范缺失、公共代码与端侧代码耦合度高，导致维护成本持续上升。本文给出拆分为两套独立项目的架构建议，并说明边界划分、迁移注意事项与性能优化方向。",{"path":743,"title":744,"description":745,"category":10,"score":135},"\u002Fknowledge\u002Fteam-documents\u002F04","老系统升级与兼容改造实践","公司原有业务系统采用 Node + jQuery 架构，长期运行后暴露出典型遗留系统问题：",{"path":747,"title":748,"description":749,"category":10,"score":135},"\u002Fknowledge\u002Fteam-documents\u002F02","防篡改水印","在各类管理后台、SaaS 平台或内部系统中，页面水印已经是非常常见的能力：一方面在截图时携带账号、姓名、时间等信息，降低截图外传的风险；另一方面在上传图片或文档预览时，通过水印标记上传者与时间，满足审计和合规需求。",{"path":751,"title":752,"description":753,"category":10,"score":135},"\u002Fknowledge\u002Fteam-documents\u002F22","企业微信 uni-app H5：OAuth 回退白屏与列表缓存","第三方 BI 报表项目，企业微信内嵌 H5，uni-app 编译，history 模式。主页面 BiLink 同时承担静默授权和列表展示，上线后碰到两个问题：授权完清掉 URL 参数，iOS 侧滑返回还是白屏；列表加了缓存以后，刷新行…",{"path":755,"title":756,"description":757,"category":10,"score":135},"\u002Fknowledge\u002Fteam-documents\u002F10","图片上传前的自定义水印实践","项目需要在图片上传前叠加动态水印。水印内容不是固定文案，而是由多个动态元素组成（如时间、地点、业务字段等）。",{"series":759,"title":760,"items":761,"index":99,"prev":831,"next":832},"team-documents","team documents",[762,766,768,772,774,778,780,781,785,789,791,795,799,801,805,809,813,817,821,823,825,829],{"path":763,"title":764,"date":765,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F01","执行价格弹窗：表头 \u002F 表体合并与可配置表格","2024-07-27",{"path":747,"title":748,"date":767,"pinned":17},"2024-01-09",{"path":769,"title":770,"date":771,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F03","键盘弹起导致底部被顶起问题（H5 适配）","2024-09-17",{"path":743,"title":744,"date":773,"pinned":17},"2024-12-12",{"path":775,"title":776,"date":777,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F05","内部插件 \u002F 工具库开发实践","2021-08-19",{"path":695,"title":696,"date":779,"pinned":17},"2025-10-01",{"path":7,"title":8,"date":16,"pinned":17},{"path":782,"title":783,"date":784,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F08","属性排序需求","2024-06-16",{"path":786,"title":787,"date":788,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F09","同业主重复单提醒规则","2020-06-07",{"path":755,"title":756,"date":790,"pinned":17},"2021-06-10",{"path":792,"title":793,"date":794,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F11","系统下单（重复单提示框）异常复盘","2023-11-21",{"path":796,"title":797,"date":798,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F12","系统自动更新说明","2025-05-26",{"path":701,"title":702,"date":800,"pinned":17},"2025-04-08",{"path":802,"title":803,"date":804,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F14","选项卡切换与 Loading 状态封装","2019-11-03",{"path":806,"title":807,"date":808,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F15","移动端返回事件触发两次问题复盘","2021-03-09",{"path":810,"title":811,"date":812,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F16","在线协作表格接入实践","2023-10-27",{"path":814,"title":815,"date":816,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F17","支付中转页面升级实践","2022-10-15",{"path":818,"title":819,"date":820,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F18","中英文输入法下搜索触发冲突复盘","2024-09-01",{"path":737,"title":738,"date":822,"pinned":17},"2026-03-17",{"path":707,"title":708,"date":824,"pinned":17},"2023-08-31",{"path":826,"title":827,"date":828,"pinned":17},"\u002Fknowledge\u002Fteam-documents\u002F21","vxe-table 行 Hover 联动高亮","2024-08-31",{"path":751,"title":752,"date":830,"pinned":17},"2023-08-17",{"path":695,"title":696,"date":779,"pinned":17},{"path":782,"title":783,"date":784,"pinned":17}]