仅使用Chrome进行慢速图像绘制
Slow image draw with Chrome only
这是一个基本的文本输入,它将化身图像和文本添加到类似聊天的框div
中,化身可以是数百的任何数字,所以我不能只将其作为一个类。
问题:通过html插入使用标准<img>
会导致Chrome中的图像重绘速度缓慢。IE和Firefox会立即显示图像(缓存第一个条目后)。
我已经对主函数本身进行了计时,它在6毫秒左右完成(很棒),但在那个阶段,Chrome已经渲染了文本,甚至还没有开始渲染图像。在另一台速度更快的计算机上测试-没有变化。
http://jsfiddle.net/chrisadmin/yw24h2aj/
html:
<div id="newMsg" style="border:1px solid black"></div>
<br/>Type some stuff and hit enter<br/>
<input class="ui-widget-content ui-corner-bl ui-corner-br" maxlength="400" type="text" id="outgoing" onkeydown="if (event.keyCode == 13) displayMsg()" />
js:
ngcClientTag = 0;
opt_avatar = '1';
function displayMsg() {
var message = $('#outgoing').val();
$('#outgoing').val('');
ngcClientTag++;
var innerHtml =
'<div id="c_m_' + (ngcClientTag - 1) + '" class="msg1">' +
'<div style="float:left">' +
'<img class="msg2" src="http://parkbenchgames.com/images/ava/' + opt_avatar + '.png"/>' +
'</div>' +
'<div>' +
'<div class="msg3" id="s_m_' + (ngcClientTag - 1) + '">' +
'</div>' +
'</div>' +
'<div style="clear:both">' + '</div>' +
'</div>';
$("#newMsg").append(innerHtml);
$("#s_m_" + (ngcClientTag - 1)).text(message);
}
css:
.msg1 {
position:relative;
margin-bottom:1px;
}
.msg2 {
position:relative;
margin-right:5px;
border:none;
height:25px;
width:46px;
}
.msg2a {
position:relative;
margin-right:5px;
border:none;
height:25px;
width:3px;
}
.msg3 {
position:relative;
top:4px;
margin-bottom:4px;
overflow:hidden;
}
这太烦人了!我也遇到过同样的问题:动态创建的图像在FF中不会闪烁,但在Chrome中会闪烁。
我没有任何关于Chrome内部的参考工作来说明为什么会发生这种情况,但以下是当它发生在我身上时我是如何解决的。2件事:
1.不要使用img src
将图像作为背景图像加载到div。Chrome必须以不同的方式加载/缓存这些图像。。。?
2.预加载图像
这就说明了一切。在FF中,您可以通过创建一个包含图像的DOM元素来实现预加载,ala
var $img=$('<img>');
$img.attr('src','image.ext');
然而,如果你想预加载图像,Chrome要求你把图像附加到DOM(屏幕外的某个地方),比如
var $img=$('<img>');
$img.attr('src','image.ext');
$img.css({position:'absolute',top:'-10000px',left:'-10000px'});
$('body').append($img);
由于您已经准备好了displayMsg()
函数,因此可以通过用空message
调用图像来预加载图像,然后立即删除它创建的元素,这样就不会使屏幕变得混乱。
html/css没有改变。
JS
ngcClientTag = 0;
opt_avatar = '1';
/* PRELOAD *///===========================
//you know the avatar number, grab the image
var img='http://parkbenchgames.com/images/ava/' + opt_avatar + '.png';
//make it a background style instead of an img tag
var bgStyle="background-image:url("+img+")";
$(document).ready(function () {
//preload the image!
displayMsg();
//use setTimeout to make sure we are on the next iteration of event loop
setTimeout(function() {$('.msg1').remove()},0);
});
function displayMsg() {
var message = $('#outgoing').val();
$('#outgoing').val('');
ngcClientTag++;
var innerHtml =
'<div id="c_m_' + ngcClientTag + '" class="msg1">';
//display img in div instead of img tag
//borrow class msg2 to give it the same dimensions as the img
innerHtml +='<div style="float:left;'+bgStyle+'" class="msg2">' +
'</div>' +
'<div>' +
'<div class="msg3" id="s_m_' + ngcClientTag + '">' +
'</div>' +
'</div>' +
'<div style="clear:both">' + '</div>' +
'</div>';
$("#newMsg").append(innerHtml);
$("#s_m_" + ngcClientTag).text(message); // for text safe insert
}
小提琴http://jsfiddle.net/yo307pt7/4/
这最终成为了一个完整的FUBAR:我(在一些史前阶段)使用PHP强制浏览器通过无缓存选项获取新图像。一个非常糟糕的主意。
Chrome遵循了比其他浏览器更残酷的政策。
我的答案是,用一个"?作为一种广泛的js策略,图像url末尾的number_here将在不影响速度的情况下提供完美的更新。
当您希望在浏览器刷新时进行完美更新时,请更改"number_here"。使用变量可以变得聪明。
pv = '?24';
...
output = '<img src="'images'icon20.png"'+pv+'>';
...
- 用图像而不是颜色填充对象(将图像绘制到画布上)
- 仅使用Chrome进行慢速图像绘制
- 将 SVG 图像绘制到 CanvasRenderingContext2D 中
- 为什么我不能将图像绘制到画布中
- 将许多新图像绘制到画布时内存泄漏
- Javascript - 加载GIF冻结,同时将图像绘制到画布(Phonegap/Cordova)
- 画布:绘制图像而不是将图像绘制到画布
- 将图像绘制到<画布>
- 在浏览器中识别完整的图像绘制
- 画布图像绘制失败
- 将图像绘制到画布上
- 如何在画布上为运动图像绘制多条路径
- 将图像绘制到画布有时不显示任何东西
- 修剪透明背景的图像绘制在画布与PHP或javascript
- Javascript将图像绘制在彼此之上
- 我可以将数组值插入到画布的图像绘制函数中吗?
- 画布上的图像绘制比原始尺寸大
- 画布图像绘制不工作
- 将预先加载的图像绘制到画布中
- javascript从缓冲区(nodejs/socket.io)将图像绘制到html中