首先在body外插入一個absolute的容器避免重繪:javascript
const svgWidthTestContainer = document.createElement('svg'); svgWidthTestContainer.setAttribute('id', 'svgWidthTest'); svgWidthTestContainer.style.cssText = ` position: absolute; width: 500px; height: 500px; left: -1000px; top: -1000px; visibility: 'hidden'; `; document.body.appendChild(svgWidthTestContainer);
總結出了兩種方法,這裏因爲我使用的是svg,其餘元素同理。下面先說性能最好的一個方法,先建立全部的text元素,而後統一append到準備好的容器裏。
代碼以下:css
export function getSvgsWidth(texts) { // 這裏使用div不用fragment主要是不方便刪除 const textsFragment = document.createElement('g'); const textElements = texts.map((text) => { const textElement = document.createElement('text'); textElement.textContent = text; textsFragment.appendChild(textElement); return textElement; }); svgWidthTestContainer.appendChild(textsFragment); const textElementsWidth = textElements.map(element => element.getBoundingClientRect().width); svgWidthTestContainer.removeChild(textsFragment); return textElementsWidth; } // 獲得1-1000000數字在屏幕上的寬度 console.log(getSvgsWidth([...Array(100000).keys()]));
還有一個方法(不推薦)就是事先準備好一個text,而後每次替換裏面的textContent返回寬度,代碼以下:java
// 準備好text const textElementTest = document.createElement('text'); svgWidthTestContainer.appendChild(textElementTest); export function getSvgsWidthWithOneText(texts) { const textElementsWidth = texts.map((text) => { textElementTest.textContent = text; return textElementTest.getBoundingClientRect().width; }); return textElementsWidth; }
// 能夠作一個性能測試,我這邊算出來他倆一直保持着5倍左右的差距 const dateStart = new Date().getTime(); console.log(getSvgsWidth([...Array(100000).keys()])); console.log(getSvgsWidthWithOneText([...Array(100000).keys()])); console.log(new Date().getTime() - dateStart);