我怎样才能真正快速地在 webkit 中显示图像?
How can I display an image in webkit really fast?
我正在使用电子构建一个照片应用程序,从文件系统加载用户照片。这些照片的大小很容易达到 7MB 或更大。该应用程序允许用户使用键盘箭头在照片之间切换,此时我希望新照片显示得非常快。
对于 7MB 的图像,仅更改 DOM 中现有图像标签的 src
可能需要约 200-300 毫秒,webkit 必须加载文件、解码文件并渲染页面上的文件。加载和解码各需要 100-150 毫秒。 (实际上分析器只是说 2 x 解码,但下一步删除其中一个解码,所以我认为它与读取的文件有关)。
正在预加载 img
标签...
var img = new Image();
img.src = "/path/to/photo.jpg"
...意味着webkit 预加载文件,这去掉了文件加载时间,但是像这样追加仍然有100-150ms 的延迟...
domElement.appendChild(img);
...因为读取的数据仍然必须解码才能附加到 DOM。
有没有办法对图像进行预解码,让附加到DOM上不存在100-150ms的延迟,只需要快速渲染?
不,你不能"pre-decode"。但是,您可以通过应用样式 width: 1px; height: 1px; opacity: 0.01
以一种有效的不可见方式预先附加 img
,如果您再次附加,webkit 将不会重做该工作。
您甚至可以同时删除图像,前提是它有时间完全解码,并且 webkit 会保留解码后的数据(尽管我不确定 for how long)。
如果您想绝对确定它会快速加载,您可以执行以下两项操作之一。通过删除上面的样式或通过在 DOM 的不同部分加载相同的 img
标签,同时保留 'pre-appended' 标签来显示 img
标签。根据我的经验,这将花费 3 毫秒到 20 毫秒。
如果您使用大量用户定义的照片内容,请注意清理。
根据我的经验,简单地从 DOM 中删除许多 img
元素将 导致内存泄漏(和电子 windows 崩溃) .我建议您在 从 DOM 中删除图像后将 img.src
设置为空 ,或者如果不再需要则设置 the entire img
to null图像实例。
您可以使用 chrome devtools 时间轴使用以下代码(使用您自己的图像)来测量不同场景下照片的渲染速度。
<style>
/*#preload img {
width: 1px;
height: 1px;
opacity: 0.01;
}*/
</style>
<button>Toggle Image</button>
<div id="container"></div>
<div id="preload"></div>
<script>
"use strict"
const button = document.getElementsByTagName('button')[0]
, container = document.getElementById('container')
, preload = document.getElementById('preload')
, img1 = new Image()
, img2 = new Image()
var current = img2
img1.src = './img1.JPG'
img2.src = './img2.JPG'
preload.appendChild(img2)
setTimeout(function(){
preload.removeChild(preload.childNodes[0])
}, 200)
button.addEventListener('click', function(e){
toggleImg()
})
function toggleImg(){
if (current === img1) {
setImg(img2);
} else {
setImg(img1)
}
}
function setImg(img){
if (container.hasChildNodes()) container.removeChild(container.childNodes[0])
container.appendChild(img)
current = img
}
</script>
我建议尝试使用 HTML5 Canvas 来渲染您的图像,这样您就可以提前加载下一张图像并更直接地控制缓存策略。
我正在使用电子构建一个照片应用程序,从文件系统加载用户照片。这些照片的大小很容易达到 7MB 或更大。该应用程序允许用户使用键盘箭头在照片之间切换,此时我希望新照片显示得非常快。
对于 7MB 的图像,仅更改 DOM 中现有图像标签的 src
可能需要约 200-300 毫秒,webkit 必须加载文件、解码文件并渲染页面上的文件。加载和解码各需要 100-150 毫秒。 (实际上分析器只是说 2 x 解码,但下一步删除其中一个解码,所以我认为它与读取的文件有关)。
正在预加载 img
标签...
var img = new Image();
img.src = "/path/to/photo.jpg"
...意味着webkit 预加载文件,这去掉了文件加载时间,但是像这样追加仍然有100-150ms 的延迟...
domElement.appendChild(img);
...因为读取的数据仍然必须解码才能附加到 DOM。
有没有办法对图像进行预解码,让附加到DOM上不存在100-150ms的延迟,只需要快速渲染?
不,你不能"pre-decode"。但是,您可以通过应用样式 width: 1px; height: 1px; opacity: 0.01
以一种有效的不可见方式预先附加 img
,如果您再次附加,webkit 将不会重做该工作。
您甚至可以同时删除图像,前提是它有时间完全解码,并且 webkit 会保留解码后的数据(尽管我不确定 for how long)。
如果您想绝对确定它会快速加载,您可以执行以下两项操作之一。通过删除上面的样式或通过在 DOM 的不同部分加载相同的 img
标签,同时保留 'pre-appended' 标签来显示 img
标签。根据我的经验,这将花费 3 毫秒到 20 毫秒。
如果您使用大量用户定义的照片内容,请注意清理。
根据我的经验,简单地从 DOM 中删除许多 img
元素将 导致内存泄漏(和电子 windows 崩溃) .我建议您在 从 DOM 中删除图像后将 img.src
设置为空 ,或者如果不再需要则设置 the entire img
to null图像实例。
您可以使用 chrome devtools 时间轴使用以下代码(使用您自己的图像)来测量不同场景下照片的渲染速度。
<style>
/*#preload img {
width: 1px;
height: 1px;
opacity: 0.01;
}*/
</style>
<button>Toggle Image</button>
<div id="container"></div>
<div id="preload"></div>
<script>
"use strict"
const button = document.getElementsByTagName('button')[0]
, container = document.getElementById('container')
, preload = document.getElementById('preload')
, img1 = new Image()
, img2 = new Image()
var current = img2
img1.src = './img1.JPG'
img2.src = './img2.JPG'
preload.appendChild(img2)
setTimeout(function(){
preload.removeChild(preload.childNodes[0])
}, 200)
button.addEventListener('click', function(e){
toggleImg()
})
function toggleImg(){
if (current === img1) {
setImg(img2);
} else {
setImg(img1)
}
}
function setImg(img){
if (container.hasChildNodes()) container.removeChild(container.childNodes[0])
container.appendChild(img)
current = img
}
</script>
我建议尝试使用 HTML5 Canvas 来渲染您的图像,这样您就可以提前加载下一张图像并更直接地控制缓存策略。