measureText.html 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/astrobench@0.1.2/src/style.css">
  8. <script src="../test/lib/rollup.browser.js"></script>
  9. <script src="../test/lib/requireES.js"></script>
  10. <script src="../test/lib/config.js"></script>
  11. <script src="../test/data/text.js"></script>
  12. <title>measureText</title>
  13. </head>
  14. <body>
  15. <div id="astrobench"></div>
  16. <script src="https://cdn.jsdelivr.net/npm/astrobench@0.1.2/dist/astrobench.js"></script>
  17. <script type="text/javascript">
  18. requireES([
  19. 'zrender/esm/core/LRU'
  20. ], function (LRU) {
  21. function createMeasure() {
  22. let ctx = document.createElement('canvas').getContext('2d');
  23. let lastFont;
  24. return function getWidth(text, font) {
  25. if (lastFont !== font) {
  26. ctx.font = font;
  27. lastFont = font;
  28. }
  29. return ctx.measureText(text).width;
  30. }
  31. }
  32. function createMeasureSimpleCache() {
  33. let textWidthCache = {};
  34. let textWidthCacheCounter = 0;
  35. const getWidth = createMeasure();
  36. const TEXT_CACHE_MAX = 5000;
  37. return function getWidthSimpleCache(text, font) {
  38. const key = text + ':' + font;
  39. if (textWidthCache[key]) {
  40. return textWidthCache[key];
  41. }
  42. const width = getWidth(text, font);
  43. if (textWidthCacheCounter > TEXT_CACHE_MAX) {
  44. textWidthCacheCounter = 0;
  45. textWidthCache = {};
  46. }
  47. textWidthCacheCounter++;
  48. textWidthCache[key] = width;
  49. return width;
  50. }
  51. }
  52. function createMeasureLRUCache() {
  53. let textWidthCache = {};
  54. const getWidth = createMeasure();
  55. return function getWidthLRUCache(text, font) {
  56. let cacheOfFont = textWidthCache[font];
  57. if (!cacheOfFont) {
  58. cacheOfFont = textWidthCache[font] = new LRU.default(500);
  59. }
  60. let width = cacheOfFont.get(text);
  61. if (width == null) {
  62. width = getWidth(text, font);
  63. cacheOfFont.put(text, width);
  64. }
  65. return width;
  66. }
  67. }
  68. function createSuite(name, textFrags) {
  69. suite(name, function () {
  70. let font = '12px sans-serif';
  71. let basicMeasure;
  72. let measureWithSimpleCache;
  73. let measureWithLRUCache;
  74. setup(function () {
  75. basicMeasure = createMeasure();
  76. measureWithSimpleCache = createMeasureSimpleCache();
  77. measureWithLRUCache = createMeasureLRUCache();
  78. let testRes1 = basicMeasure('测试', font);
  79. let testRes2 = measureWithSimpleCache('测试', font);
  80. let testRes3 = measureWithLRUCache('测试', font);
  81. if (testRes1 !== testRes2 || testRes1 !== testRes3) {
  82. throw new Error(`Result wrong, ${testRes1}, ${testRes2}, ${testRes3}`);
  83. }
  84. });
  85. bench('Basic', function () {
  86. for (let i = 0; i < textFrags.length; i++) {
  87. let width = basicMeasure(textFrags[i], font);
  88. }
  89. });
  90. bench('Simple Cache', function () {
  91. // TODO 如果 measureWithSimpleCache 调用报错,会报 textFrags is not defined 的错误
  92. for (let i = 0; i < textFrags.length; i++) {
  93. let width = measureWithSimpleCache(textFrags[i], font);
  94. }
  95. });
  96. bench('LRU Cache', function () {
  97. for (let i = 0; i < textFrags.length; i++) {
  98. let width = measureWithLRUCache(textFrags[i], font);
  99. }
  100. });
  101. });
  102. }
  103. createSuite('English Measure Text(By Words)', LARGE_TEXT_EN.split(' '));
  104. createSuite('English Measure Text(By Character)', LARGE_TEXT_EN.split(''));
  105. createSuite('Chinese Measure Text', LARGE_TEXT_ZH.split(''));
  106. });
  107. </script>
  108. </body>
  109. </html>