Высокопроизводительные визуализации данных в браузере (CodeFest)

Высокопроизводительные визуализации данных в браузере (CodeFest)

6d07e6d95a43357254698ce9723350e6?s=128

Vladimir Agafonkin

March 29, 2013
Tweet

Transcript

  1. Владимир Агафонкин высокопроизводительные визуализации данных в браузере март 2013

  2. agafonkin.com /mourner

  3. rain.in.ua

  4. визуализации данных

  5. None
  6. None
  7. None
  8. None
  9. None
  10. None
  11. интерактивность

  12. •реагирование на действия пользователя интерактивность

  13. •реагирование на действия пользователя •навигация по данным интерактивность

  14. •реагирование на действия пользователя •навигация по данным •фильтрация данных интерактивность

  15. None
  16. None
  17. None
  18. None
  19. None
  20. потребность в интерактивности увеличивается

  21. ответственность за обработку данных всё больше смещается от сервера к

    клиенту
  22. чистый JS — быстро рендеринг, DOM — медленно

  23. правило №1 чем меньше всего отображаем, тем быстрее

  24. обработка данных рендеринг

  25. обработка данных рендеринг

  26. •фильтрация объектов уменьшение данных

  27. •фильтрация объектов •геометрическое отсечение уменьшение данных

  28. •фильтрация объектов •геометрическое отсечение •геометрическое упрощение уменьшение данных

  29. •фильтрация объектов •геометрическое отсечение •геометрическое упрощение •кластеризация (группировка) уменьшение данных

  30. фильтрация

  31. поиск 2D-объектов •поиск объектов в текущей прямоугольной видимой области

  32. поиск 2D-объектов •поиск объектов в текущей прямоугольной видимой области •поиск

    объектов в точке (под курсором)
  33. загрузка данных — 1 раз поиск/фильтрация — много раз

  34. сетка

  35. None
  36. древовидные структуры данных •binary heap •binary search tree •range tree

    •k-d tree •quadtree •R-tree
  37. точки в quadtree

  38. прямоугольники в R-tree

  39. var tree = new RTree(); tree.insert( {x: 5, y: 10,

    w: 10, h: 15}, obj); ... tree.search( {x: 7, y: 7, w: 5, h: 5}); github.com/imbcmdth/RTree
  40. kothic.org/js

  41. определение коллизий

  42. Crossfilter (для многих измерений)

  43. отсечение ломаных линий алгоритм Коэна-Сазерленда

  44. отсечение полигонов алгоритм Сазерленда-Ходжмана

  45. упрощение ломаных линий

  46. упрощение по расстоянию

  47. алгоритм Дугласа-Пекера

  48. mourner.github.com/simplify-js

  49. кластеризация группировка похожих объектов

  50. None
  51. None
  52. иерархическая кластеризация 1 раз для всех масштабов

  53. загрузка и обработка данных

  54. UI JS UI

  55. UI JS браузер залипает на объемных вычислениях UI

  56. Web Workers

  57. <script src='data.js'></script> <script> ... worker.postMessage(HUGE_DATA_ARRAY); ... </script> загрузка и пересылка

    в Worker
  58. UI Worker JS загрузка данных UI

  59. UI Worker JS браузер залипает на загрузке и пересылке данных

    загрузка данных UI
  60. importScripts('data.js'); ... onmessage = function (e) { var result =

    searchData(e.data.query); postMessage(result); } загрузка в Worker
  61. UI Worker JS загрузка данных UI UI

  62. UI Worker JS браузер залипает на получении данных загрузка данных

    UI UI
  63. var array = new Float16Array(len); ... var buffer = array.buffer;

    postMessage(buffer, [buffer]); // с этого момента buffer недоступен transferable objects (Chrome, Firefox)
  64. UI Worker JS загрузка данных UI UI

  65. UI Worker JS браузер не залипает, данные пересылаются как ArrayBuffer

    загрузка данных UI UI
  66. function addNumbers(a, b) { 'use asm'; a = a |

    0; // int b = +b; // double return +(a + b); // double } светлое будущее — asm.js
  67. светлое будущее — asm.js •оптимизация узких мест вычислений

  68. светлое будущее — asm.js •оптимизация узких мест вычислений •пока только

    в FF Nightly
  69. светлое будущее — asm.js •оптимизация узких мест вычислений •пока только

    в FF Nightly •обратная совместимость!
  70. технологии рендеринга SVG, Canvas, HTML, WebGL

  71. SVG •быстрые нативные события для интерактивности

  72. SVG •быстрые нативные события для интерактивности •легко обновлять отдельные объекты

  73. SVG •быстрые нативные события для интерактивности •легко обновлять отдельные объекты

    •тормозит страницу (при большом кол-ве объектов)
  74. Canvas •после отрисовки не влияет на отзывчивость страницы

  75. Canvas •после отрисовки не влияет на отзывчивость страницы •повторяющиеся части

    можно отрисовать один раз и раскопировать
  76. Canvas •после отрисовки не влияет на отзывчивость страницы •повторяющиеся части

    можно отрисовать один раз и раскопировать •можно попиксельно рисовать/ обрабатывать в Worker
  77. Canvas •дорого перерисовывать при каждом обновлении

  78. Canvas •дорого перерисовывать при каждом обновлении •очень сложно с реализацией

    интерактивности
  79. WebGL •основной способ для 3D- визуализаций

  80. WebGL •основной способ для 3D- визуализаций •очень быстро в 2D,

    если нужно отрисовать много спрайтов
  81. WebGL •основной способ для 3D- визуализаций •очень быстро в 2D,

    если нужно отрисовать много спрайтов •в остальных случаях преимущество в скорости перед Canvas-2D спорно
  82. WebGL •основной способ для 3D- визуализаций •очень быстро в 2D,

    если нужно отрисовать много спрайтов •в остальных случаях преимущество в скорости перед Canvas-2D спорно •API намного сложнее и неудобнее
  83. WebGL •основной способ для 3D- визуализаций •очень быстро в 2D,

    если нужно отрисовать много спрайтов •в остальных случаях преимущество в скорости перед Canvas-2D спорно •API намного сложнее и неудобнее •поддержки в IE и iOS не ожидается
  84. HTML •удобно использовать для текста и элементов интерфейса

  85. HTML •удобно использовать для текста и элементов интерфейса •очень удобно

    анимировать с помощью CSS Transitions
  86. HTML •удобно использовать для текста и элементов интерфейса •очень удобно

    анимировать с помощью CSS Transitions •тормозит страницу при большом кол-ве объектов
  87. производительность Canvas

  88. частичная перерисовка

  89. частичная перерисовка

  90. частичная перерисовка

  91. function drawStar(x, y) { ... // нарисовать звезду в x,

    y } drawStar(10, 20); drawStar(50, 70); ...
  92. function drawStar() { var canvas = document.createElement('canvas'); ... // нарисовать

    звезду return canvas; } var star = drawStar(); ctx.drawImage(star, 10, 20); ctx.drawImage(star, 50, 70); ... копирование
  93. группируйте отрисовку по стилям, минимизируйте stroke/fill

  94. function drawLine(x1, x2, y1, y2) { ctx.strokeStyle = 'red'; ctx.beginPath();

    ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); } drawLine(10, 20, 30, 40); drawLine(200, 10, 0, 50); drawLine(30, 40, 70, 0);
  95. function drawLine(x1, x2, y1, y2) { ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2,

    y2); } ctx.strokeStyle = 'red'; drawLine(10, 20, 30, 40); drawLine(200, 10, 0, 50); drawLine(30, 40, 70, 0); ctx.stroke();
  96. var data = ctx.getImageData(0, 0, width, height).data; worker.postMessage(data, [data]); ...

    worker.onmessage = function (e) { var imageData = ctx.createImageData(width, height); imageData.data.set(e.data); ctx.putImageData(imageData, 0, 0); } Canvas + Worker
  97. var pixels = new Uint8ClampedArray( width * height); function drawPixel(x,

    y, r, g, b, a) { var i = 4 * (256 * y + x); pixels[i] = r; pixels[i + 1] = g; pixels[i + 2] = b; pixels[i + 3] = a; } ... postMessage(pixels.buffer, [pixels.buffer]); рисование пикселей в Worker
  98. var pixels = new Uint8ClampedArray(data); for (var x = 0;

    x < width; x++) { for (var y = 0; y < height; y++) { var i = 4 * (256 * y + x); pixels[i] = 2 * pixels[i]; pixels[i + 1] = 2 * pixels[i + 1]; pixels[i + 2] = 2 * pixels[i + 2]; } } ... postMessage(pixels.buffer, [pixels.buffer]); обработка пикселей в Worker
  99. UTFGrid

  100. UTFGrid •65535 разных символов

  101. UTFGrid •65535 разных символов •каждый символ — 4х4 пикселя

  102. UTFGrid •65535 разных символов •каждый символ — 4х4 пикселя •сетка

    + маппинг
  103. UTFGrid •65535 разных символов •каждый символ — 4х4 пикселя •сетка

    + маппинг •в среднем 1-3 КБ на тайл 256х256
  104. Спасибо! Вопросы? Владимир Агафонкин agafonkin@gmail.com