如何用JavaScript高效显示大量二维码?现有API渲染性能不足
优化批量二维码生成与渲染的方案
问题描述
我尝试在表格中显示二维码,二维码的URL以文本节点形式存储在div中。现有代码可正常运行,但二维码显示速度较慢,且需要渲染更多二维码,请问是否有更优或更轻量的替代方案?
用户原有实现代码:
function myfunction() { // PAGE 1 STARTS // ROW 1 var TextInsideA2 = document.getElementById('A2').innerHTML; document.getElementById('barcodeA2').src = "https://api.qrserver.com/v1/create-qr-code/?data='" + TextInsideA2 +"'&size=85x85"; var TextInsideA3 = document.getElementById('A3').innerHTML; document.getElementById('barcodeA3').src = "https://api.qrserver.com/v1/create-qr-code/?data='" + TextInsideA3 +"'&size=85x85"; var TextInsideA4 = document.getElementById('A4').innerHTML; document.getElementById('barcodeA4').src = "https://api.qrserver.com/v1/create-qr-code/?data='" + TextInsideA4 +"'&size=85x85"; // ROW 2 var TextInsideA5 = document.getElementById('A5').innerHTML; document.getElementById('barcodeA5').src = "https://api.qrserver.com/v1/create-qr-code/?data='" + TextInsideA5 +"'&size=85x85"; var TextInsideA6 = document.getElementById('A6').innerHTML; document.getElementById('barcodeA6').src = "https://api.qrserver.com/v1/create-qr-code/?data='" + TextInsideA6 +"'&size=85x85"; var TextInsideA7 = document.getElementById('A7').innerHTML; document.getElementById('barcodeA7').src = "https://api.qrserver.com/v1/create-qr-code/?data='" + TextInsideA7 +"'&size=85x85"; // ROW 3 var TextInsideA8 = document.getElementById('A8').innerHTML; document.getElementById('barcodeA8').src = "https://api.qrserver.com/v1/create-qr-code/?data='" + TextInsideA8 +"'&size=85x85"; var TextInsideA9 = document.getElementById('A9').innerHTML; document.getElementById('barcodeA9').src = "https://api.qrserver.com/v1/create-qr-code/?data='" + TextInsideA9 +"'&size=85x85"; var TextInsideA10 = document.getElementById('A10').innerHTML; document.getElementById('barcodeA10').src = "https://api.qrserver.com/v1/create-qr-code/?data='" + TextInsideA10 +"'&size=85x85"; // ROW 4 var TextInsideA11 = document.getElementById('A11').innerHTML; document.getElementById('barcodeA11').src = "https://api.qrserver.com/v1/create-qr-code/?data='" + TextInsideA11 +"'&size=85x85"; var TextInsideA12 = document.getElementById('A12').innerHTML; document.getElementById('barcodeA12').src = "https://api.qrserver.com/v1/create-qr-code/?data='" + TextInsideA12 +"'&size=85x85"; var TextInsideA13 = document.getElementById('A13').innerHTML; document.getElementById('barcodeA13').src = "https://api.qrserver.com/v1/create-qr-code/?data='" + TextInsideA13 +"'&size=85x85"; // PAGE 1 ENDS } window.onload = myfunction;
优化方案
1. 重构重复代码,提升维护性与基础效率
你的代码存在大量重复的DOM操作和URL拼接逻辑,先把通用逻辑抽成独立函数,减少冗余的同时还能避免潜在的错误(比如之前的单引号包裹可能导致URL解析异常):
function generateQRCode(textElementId, barcodeImageId) { // 用textContent代替innerHTML,避免获取到HTML标签内容 const qrData = document.getElementById(textElementId).textContent.trim(); if (!qrData) return; // 跳过空内容,减少无效请求 // 用encodeURIComponent正确编码数据,避免特殊字符破坏URL const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?data=${encodeURIComponent(qrData)}&size=85x85`; document.getElementById(barcodeImageId).src = qrUrl; } function initQRCodes() { // 用数组批量管理需要生成二维码的元素配对 const qrElementPairs = [ ['A2', 'barcodeA2'], ['A3', 'barcodeA3'], ['A4', 'barcodeA4'], ['A5', 'barcodeA5'], ['A6', 'barcodeA6'], ['A7', 'barcodeA7'], ['A8', 'barcodeA8'], ['A9', 'barcodeA9'], ['A10', 'barcodeA10'], ['A11', 'barcodeA11'], ['A12', 'barcodeA12'], ['A13', 'barcodeA13'] ]; // 批量执行生成逻辑 qrElementPairs.forEach(pair => generateQRCode(pair[0], pair[1])); } window.onload = initQRCodes;
2. 本地生成二维码,彻底消除网络延迟
如果要渲染大量二维码,第三方API的网络请求是最大的性能瓶颈。推荐使用纯前端二维码生成库(比如轻量无依赖的QRCode.js),直接在浏览器本地生成二维码,速度会有质的提升:
<!-- 建议把库文件下载到本地引入,避免CDN依赖 --> <script src="qrcode.min.js"></script> <script> function generateLocalQRCode(textElementId, containerId) { const qrData = document.getElementById(textElementId).textContent.trim(); if (!qrData) return; // 本地生成二维码到指定容器 new QRCode(document.getElementById(containerId), { text: qrData, width: 85, height: 85, // 还可以自定义样式,比如二维码颜色、背景色 colorDark: '#000000', colorLight: '#ffffff' }); } function initQRCodes() { const qrElementPairs = [ ['A2', 'barcodeA2'], ['A3', 'barcodeA3'], // ... 其他元素配对 ]; qrElementPairs.forEach(pair => generateLocalQRCode(pair[0], pair[1])); } window.onload = initQRCodes; </script>
这种方案的优势:
- 完全本地渲染,没有网络请求延迟,生成速度极快
- 不依赖第三方API的可用性,稳定性更高
- 支持自定义二维码样式,灵活性更强
3. 懒加载非可视区域的二维码
如果表格内容很长,很多二维码初始时不在用户可视范围内,可以用懒加载策略,只有当元素滚动到视口内时再生成,减少页面初始化时的计算和请求压力:
// 判断元素是否在视口内的工具函数 function isElementInViewport(element) { const rect = element.getBoundingClientRect(); return ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth) ); } function lazyLoadQRCodes() { const qrElementPairs = [/* 元素配对数组 */]; qrElementPairs.forEach(pair => { const barcodeContainer = document.getElementById(pair[1]); // 只加载未处理且进入视口的二维码 if (isElementInViewport(barcodeContainer) && !barcodeContainer.dataset.loaded) { generateLocalQRCode(pair[0], pair[1]); // 用本地生成函数或API请求函数 barcodeContainer.dataset.loaded = 'true'; // 标记已加载,避免重复处理 } }); } // 初始化时加载可视区域的二维码,然后监听滚动事件 window.onload = () => { lazyLoadQRCodes(); window.addEventListener('scroll', lazyLoadQRCodes); };
4. 缓存DOM元素,减少重复查询
如果需要处理的元素数量很多,多次调用getElementById虽然效率不低,但可以一次性缓存所有需要的元素,减少DOM查询次数:
function initQRCodes() { // 一次性缓存所有需要用到的DOM元素 const elements = { A2: document.getElementById('A2'), barcodeA2: document.getElementById('barcodeA2'), A3: document.getElementById('A3'), barcodeA3: document.getElementById('barcodeA3'), // ... 其他元素 }; const qrElementPairs = [['A2', 'barcodeA2'], ['A3', 'barcodeA3'], ...]; qrElementPairs.forEach(pair => { const qrData = elements[pair[0]].textContent.trim(); if (qrData) { elements[pair[1]].src = `https://api.qrserver.com/v1/create-qr-code/?data=${encodeURIComponent(qrData)}&size=85x85`; } }); }
内容的提问来源于stack exchange,提问作者Marko
相关产品推荐
相关产品推荐

