Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Высокопроизводительные визуализации данных в бр...
Search
Vladimir Agafonkin
March 29, 2013
Programming
490
2
Share
Высокопроизводительные визуализации данных в браузере (CodeFest)
Vladimir Agafonkin
March 29, 2013
More Decks by Vladimir Agafonkin
See All by Vladimir Agafonkin
Fast by Default: Algorithmic Optimization in Practice (dotJS 2019)
mourner
0
2.2k
Fast by Default: Algorithmic Optimization in Practice (JSCamp 2019)
mourner
0
660
How Vector Maps Work (2019)
mourner
1
500
Fast by default: everyday algorithmic thinking for developers [RU]
mourner
1
550
Fast by default: everyday algorithmic thinking for developers
mourner
1
510
Mapbox GL: How vector maps work
mourner
0
460
Random cool stuff I've been hacking on (mostly spatial indices)
mourner
0
610
Как работают современные интерактивные карты на WebGL
mourner
1
550
Leaflet, WebGL & the Future of Web Mapping
mourner
5
3.5k
Other Decks in Programming
See All in Programming
How We Practice Exploratory Testing in Iterative Development( #scrumniigata ) / 反復開発の中で、探索的テストをどう実施しているか
teyamagu
PRO
3
860
20年以上続くプロダクトでも使い続けられる静的解析ツールを求めて
matsuo_atsushi
0
150
Agent Skills を社内で育てる仕組み作り
jackchuka
1
2.1k
「なんか〇〇ライブラリで脆弱性あるみたいなんだけど。。。」から始める脆弱性対応 / First Steps in Vulnerability Response
mackey0225
2
130
ソースコード→AST→オペコード、の旅を覗いてみる
o0h
PRO
1
140
色即是空、空即是色、データサイエンス
kamoneggi
1
120
開発体験を左右するライブラリの API 設計 - GraphQL スキーマ構築ライブラリから考える #tskaigi
izumin5210
1
190
サーバーレスで作る、動画データ管理基盤
oyasumipants
0
220
RailsTokyo 2026#4: AI様があれば、 Hotwireの弱点は消えるか?
naofumi
3
420
Agentic UI in the Frontend: Architectures with Open Standards @JAX 2026 in Mainz
manfredsteyer
PRO
0
120
横断組織出身のQAEがインプロセスQAEでつまずいたこと・活かせたこと
ty89
0
150
決定論 vs 確率論:Gemini 3 FlashとTF-IDFを組み合わせた「法規判定エンジン」の構築
shukob
0
170
Featured
See All Featured
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.2k
The Spectacular Lies of Maps
axbom
PRO
1
750
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
740
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.2k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
230
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
200
sira's awesome portfolio website redesign presentation
elsirapls
0
250
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
30 Presentation Tips
portentint
PRO
1
290
Done Done
chrislema
186
16k
Transcript
Владимир Агафонкин высокопроизводительные визуализации данных в браузере март 2013
agafonkin.com /mourner
rain.in.ua
визуализации данных
None
None
None
None
None
None
интерактивность
•реагирование на действия пользователя интерактивность
•реагирование на действия пользователя •навигация по данным интерактивность
•реагирование на действия пользователя •навигация по данным •фильтрация данных интерактивность
None
None
None
None
None
потребность в интерактивности увеличивается
ответственность за обработку данных всё больше смещается от сервера к
клиенту
чистый JS — быстро рендеринг, DOM — медленно
правило №1 чем меньше всего отображаем, тем быстрее
обработка данных рендеринг
обработка данных рендеринг
•фильтрация объектов уменьшение данных
•фильтрация объектов •геометрическое отсечение уменьшение данных
•фильтрация объектов •геометрическое отсечение •геометрическое упрощение уменьшение данных
•фильтрация объектов •геометрическое отсечение •геометрическое упрощение •кластеризация (группировка) уменьшение данных
фильтрация
поиск 2D-объектов •поиск объектов в текущей прямоугольной видимой области
поиск 2D-объектов •поиск объектов в текущей прямоугольной видимой области •поиск
объектов в точке (под курсором)
загрузка данных — 1 раз поиск/фильтрация — много раз
сетка
None
древовидные структуры данных •binary heap •binary search tree •range tree
•k-d tree •quadtree •R-tree
точки в quadtree
прямоугольники в R-tree
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
kothic.org/js
определение коллизий
Crossfilter (для многих измерений)
отсечение ломаных линий алгоритм Коэна-Сазерленда
отсечение полигонов алгоритм Сазерленда-Ходжмана
упрощение ломаных линий
упрощение по расстоянию
алгоритм Дугласа-Пекера
mourner.github.com/simplify-js
кластеризация группировка похожих объектов
None
None
иерархическая кластеризация 1 раз для всех масштабов
загрузка и обработка данных
UI JS UI
UI JS браузер залипает на объемных вычислениях UI
Web Workers
<script src='data.js'></script> <script> ... worker.postMessage(HUGE_DATA_ARRAY); ... </script> загрузка и пересылка
в Worker
UI Worker JS загрузка данных UI
UI Worker JS браузер залипает на загрузке и пересылке данных
загрузка данных UI
importScripts('data.js'); ... onmessage = function (e) { var result =
searchData(e.data.query); postMessage(result); } загрузка в Worker
UI Worker JS загрузка данных UI UI
UI Worker JS браузер залипает на получении данных загрузка данных
UI UI
var array = new Float16Array(len); ... var buffer = array.buffer;
postMessage(buffer, [buffer]); // с этого момента buffer недоступен transferable objects (Chrome, Firefox)
UI Worker JS загрузка данных UI UI
UI Worker JS браузер не залипает, данные пересылаются как ArrayBuffer
загрузка данных UI UI
function addNumbers(a, b) { 'use asm'; a = a |
0; // int b = +b; // double return +(a + b); // double } светлое будущее — asm.js
светлое будущее — asm.js •оптимизация узких мест вычислений
светлое будущее — asm.js •оптимизация узких мест вычислений •пока только
в FF Nightly
светлое будущее — asm.js •оптимизация узких мест вычислений •пока только
в FF Nightly •обратная совместимость!
технологии рендеринга SVG, Canvas, HTML, WebGL
SVG •быстрые нативные события для интерактивности
SVG •быстрые нативные события для интерактивности •легко обновлять отдельные объекты
SVG •быстрые нативные события для интерактивности •легко обновлять отдельные объекты
•тормозит страницу (при большом кол-ве объектов)
Canvas •после отрисовки не влияет на отзывчивость страницы
Canvas •после отрисовки не влияет на отзывчивость страницы •повторяющиеся части
можно отрисовать один раз и раскопировать
Canvas •после отрисовки не влияет на отзывчивость страницы •повторяющиеся части
можно отрисовать один раз и раскопировать •можно попиксельно рисовать/ обрабатывать в Worker
Canvas •дорого перерисовывать при каждом обновлении
Canvas •дорого перерисовывать при каждом обновлении •очень сложно с реализацией
интерактивности
WebGL •основной способ для 3D- визуализаций
WebGL •основной способ для 3D- визуализаций •очень быстро в 2D,
если нужно отрисовать много спрайтов
WebGL •основной способ для 3D- визуализаций •очень быстро в 2D,
если нужно отрисовать много спрайтов •в остальных случаях преимущество в скорости перед Canvas-2D спорно
WebGL •основной способ для 3D- визуализаций •очень быстро в 2D,
если нужно отрисовать много спрайтов •в остальных случаях преимущество в скорости перед Canvas-2D спорно •API намного сложнее и неудобнее
WebGL •основной способ для 3D- визуализаций •очень быстро в 2D,
если нужно отрисовать много спрайтов •в остальных случаях преимущество в скорости перед Canvas-2D спорно •API намного сложнее и неудобнее •поддержки в IE и iOS не ожидается
HTML •удобно использовать для текста и элементов интерфейса
HTML •удобно использовать для текста и элементов интерфейса •очень удобно
анимировать с помощью CSS Transitions
HTML •удобно использовать для текста и элементов интерфейса •очень удобно
анимировать с помощью CSS Transitions •тормозит страницу при большом кол-ве объектов
производительность Canvas
частичная перерисовка
частичная перерисовка
частичная перерисовка
function drawStar(x, y) { ... // нарисовать звезду в x,
y } drawStar(10, 20); drawStar(50, 70); ...
function drawStar() { var canvas = document.createElement('canvas'); ... // нарисовать
звезду return canvas; } var star = drawStar(); ctx.drawImage(star, 10, 20); ctx.drawImage(star, 50, 70); ... копирование
группируйте отрисовку по стилям, минимизируйте stroke/fill
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);
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();
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
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
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
UTFGrid
UTFGrid •65535 разных символов
UTFGrid •65535 разных символов •каждый символ — 4х4 пикселя
UTFGrid •65535 разных символов •каждый символ — 4х4 пикселя •сетка
+ маппинг
UTFGrid •65535 разных символов •каждый символ — 4х4 пикселя •сетка
+ маппинг •в среднем 1-3 КБ на тайл 256х256
Спасибо! Вопросы? Владимир Агафонкин
[email protected]