Javascript 在浏览器中缩放文本的更快方法?(帮助解释测试)

Javascript 在浏览器中缩放文本的更快方法?(帮助解释测试),javascript,html,html5-canvas,performance-testing,css-transforms,Javascript,Html,Html5 Canvas,Performance Testing,Css Transforms,我需要在浏览器中缩放大量文本节点(支持所有现代桌面和移动浏览器) 如果我是对的,有两个选项可以提供良好的性能:缩放画布中的文本对象或使用transform:matrix缩放DOM中的文本节点 我已经创建了一个场景来测试这两个版本,但结果并不确定。取消注释testDOM()或testCanvas()函数以启动测试。(我使用JQuery和CreateJS框架是因为它很方便。可以使用vanilla JS,但我不认为这是这里的瓶颈)。(这与您实际看到的屏幕部分有关,因此请切换到codepen中的全屏视图

我需要在浏览器中缩放大量文本节点(支持所有现代桌面和移动浏览器)

如果我是对的,有两个选项可以提供良好的性能:缩放画布中的文本对象或使用
transform:matrix
缩放DOM中的文本节点

我已经创建了一个场景来测试这两个版本,但结果并不确定。取消注释
testDOM()
testCanvas()
函数以启动测试。(我使用JQuery和CreateJS框架是因为它很方便。可以使用vanilla JS,但我不认为这是这里的瓶颈)。(这与您实际看到的屏幕部分有关,因此请切换到codepen中的全屏视图)

var宽度=500;
var高度=500;
var计数=200;
var阶跃=1.02;
var MIN=0.1;
var MAX=10;
var期;
var帆布;
var-bg;
var canvasTexts=[];
var-domTexts=[];
var-domMatrix=[];
var-dom;
函数testDOM(){
对于(变量i=0;i最大值)
刻度=最小值;
矩阵[0]=矩阵[3]=标度;
css(“transform”、“matrix”(+matrix.join(“,”)+”));
}
requestAnimationFrame(tickDOM);
}
函数testCanvas(){
$('#dom').hide();
stage=newcreatejs.stage('canvas');
createjs.Touch.enable(stage);
createjs.Ticker.timingMode=createjs.Ticker.RAF;
canvas=stage.canvas;
devicePixelRatio=window.devicePixelRatio | | 1;
stage.scaleX=设备比例;
stage.scaleY=设备比例;
log('devicePixelRatio='+devicePixelRatio);
stage.mouseMoveOutside=true;
阶段选择=错误;
stage.ticketabled=false;
stage.addChild(bg=newcreatejs.Shape());
graphics.clear();
bg.graphics.f('#f2f2').drawRect(0,0,2*宽度,高度);
canvas.width=2*width*devicePixelRatio;
canvas.height=高度*设备像素比率;
canvas.style.width=2*width+'px';
canvas.style.height=高度+px;
stage.update();
对于(变量i=0;iMAX)
text.scaleX=text.scaleY=MIN;
}
stage.update();
requestAnimationFrame(画布);
}
testDOM();
//testCanvas();
我的问题是:

  • 有可能提高我的测试性能吗?我做错什么了吗
  • 前5-10秒的速度要慢得多,但我不明白为什么。浏览器是否会在一段时间后以某种方式兑现文本对象?如果是,测试是否不适用于对象在较长时间内不放大循环的真实场景测试
  • 根据Chrome评测工具,DOM版本的空闲时间比Canvas版本多40%(快40%),但是Canvas动画看起来更平滑(在最初5-10秒的延迟之后),我应该如何解释评测工具的结果
  • 在DOM版本中,我试图在应用转换之前隐藏文本节点的父节点,然后将其取消隐藏,但这可能并不重要,因为绝对定位元素上的transform:matrix不会导致回流,对吗
  • 与画布节点相比,DOM文本节点具有一些优势,例如使用
    光标:指针进行本机鼠标悬停检测或支持装饰(画布中不能有带下划线的文本)。还有什么我应该知道的吗
  • 设置
    transform:matrix
    时,我必须创建一个编译器必须解析回数字的字符串,是否有更有效的方法使用
    transform:matrix
  • Q.1

    有可能提高我的测试性能吗?我在做什么 出什么事了

    是和否(是和否,没有本质上的错误(忽略jQuery))

    性能取决于浏览器和设备,例如Firefox比数组更好地处理对象,而Chrome更喜欢数组。对于javascript,有一长串的差异

    然后,渲染取决于硬件、内存大小、功能以及特定的驱动程序。一些硬件讨厌状态变化,而另一些硬件则全速处理状态变化。限制状态更改可以提高一台机器的速度,而额外的代码复杂性将影响不需要优化的设备

    操作系统也发挥了作用


    Q.2

    前5-10秒的速度要慢得多,但我不明白 为什么?浏览器是否会在一段时间后以某种方式兑现文本对象? 如果是,测试是否不可用于实际场景测试 对象在较长时间内不会在循环中缩放

    Javascript中的性能测试非常复杂,并且作为一个整体应用程序(如您的测试)根本不实用

    为什么慢? 很多原因,移动记忆
    var WIDTH = 500;
    var HEIGHT = 500;
    var COUNT = 200;
    var STEP = 1.02;
    var MIN = 0.1;
    var MAX = 10;
    var stage;
    var canvas;
    var bg;
    var canvasTexts = [];
    var domTexts = [];
    var domMatrix = [];
    var dom;
    
    function testDOM() {
        for (var i = 0; i < COUNT; i++) {
            var text = $("<div>Hello World</div>");
            var scale = MIN + Math.random() * 10;
            var matrix = [scale, 0, 0, scale, Math.random() * WIDTH, Math.random() * HEIGHT];
            text.css("transform", "matrix(" + matrix.join(',') + ")");
            domTexts.push(text);
            domMatrix.push(matrix);
        }
        dom = $('#dom');
        dom.append(domTexts);
        setTimeout(tickDOM, 1000);
    }
    
    function tickDOM() {
        for (var i = 0; i < domTexts.length; i++) {
            var text = domTexts[i];
            var matrix = domMatrix[i];
            var scale = matrix[0];
            scale *= STEP;
            if (scale > MAX)
                scale = MIN;
            matrix[0] = matrix[3] = scale;
            text.css("transform", "matrix(" + matrix.join(',') + ")");
        }
        requestAnimationFrame(tickDOM);
    }
    
    function testCanvas() {
        $('#dom').hide();
        stage = new createjs.Stage('canvas');
        createjs.Touch.enable(stage);
        createjs.Ticker.timingMode = createjs.Ticker.RAF;
        canvas = stage.canvas;
        devicePixelRatio = window.devicePixelRatio || 1;
        stage.scaleX = devicePixelRatio;
        stage.scaleY = devicePixelRatio;
        console.log('devicePixelRatio = ' + devicePixelRatio);
        stage.mouseMoveOutside = true;
        stage.preventSelection = false;
        stage.tickEnabled = false;
        stage.addChild(bg = new createjs.Shape());
        bg.graphics.clear();
        bg.graphics.f('#F2F2F2').drawRect(0, 0, 2 * WIDTH, HEIGHT);
        canvas.width = 2 * WIDTH * devicePixelRatio;
        canvas.height = HEIGHT * devicePixelRatio;
        canvas.style.width = 2 * WIDTH + 'px';
        canvas.style.height = HEIGHT + 'px';
        stage.update();
        for (var i = 0; i < COUNT; i++) {
            var text = new createjs.Text("Hello World", "10px", "#333333");
            text.scaleX = text.scaleY = MIN + Math.random() * 10;
            text.x = Math.random() * WIDTH;
            text.y = Math.random() * HEIGHT;
            stage.addChild(text);
            canvasTexts.push(text);
        }
        stage.update();
        setTimeout(tickCanvas, 1000);
    }
    
    function tickCanvas() {
        for (var i = 0; i < canvasTexts.length; i++) {
            var text = canvasTexts[i];
            text.scaleX = text.scaleY *= STEP;
            if (text.scaleX > MAX)
                text.scaleX = text.scaleY = MIN;
        }
        stage.update();
        requestAnimationFrame(tickCanvas);
    }
    
    testDOM();
    //testCanvas();