在网站上显示图片的最快最稳定的方式是什么?

时间:2015-09-14 13:17:17

标签: javascript css image performance coffeescript

我正在申请心理学研究。在某些特定情况下,Web应用程序需要在很短的时间内显示图像(例如20-50ms)。

从互联网上加载图像不是问题,因为程序会在使用以下脚本进入网站时缓存所有图像。

  for stimulus in stimuli
    if stimulus
      extension = stimulus.split(".").pop()
      if extension.match(/png|jpg|jpeg|gif|bmp/i)
        # Pre-cache every image to the browser by creating dummy image DOMs
        image = $("<img src='#{stimulus}' style='display:none;'></img>")
        $(document.body).append(image)

然而,问题如下:当我将图像DOM附加到容器时,将立即创建一个计时器功能,在指定的时间(如10ms)后,该功能将删除图像DOM并显示下一个图像。当超时足够长(> 100ms)时,这可以很好地工作,但是如果超时非常短(例如10-50ms),有时图像将不会显示在屏幕上。我目前的解决方法是在移除图像之前应用不透明度动画几毫秒。不仅这不是一个好方法,有时(主观观察)图像将显示更长时间,有时它显示更短。

  # Call render function to get the image DOM
  $("#stimulus-container").append(stimulus.render(_i + 1, stimuli.length))
  if maxTimeout > 0
    nextTimer = setTimeout(->
      clearTimeout(nextTimer)
      # Current (bad) workaround defer the removal of the image DOM
      $("#stimulus-container *").animate({
        opacity: 0,
      }, 50, () ->
        # Remove current image and display next
        playStimulus(nextSequence)
      )
    # The designated time to display the image
    , maxTimeout
    )

我认为问题可能与DOM操作的延迟有关。我的代码有没有什么好的解决方法,或者我应该使用CSS动画/ Canvas等其他方法来重新实现?我是这些(CSS动画/画布)的新手,所以建议实施的任何细节都将受到高度赞赏。关键是在屏幕上显示图像的时间非常短(且稳定)。非常感谢你的关注。

1 个答案:

答案 0 :(得分:2)

你是对的,DOM延迟有时可能太高,特别是对于那样的短时间内的操作。但是,您可以使用一个DOM图像元素,预加载所有需要的图像,并每20ms更改一次图像的src属性。

我为您编制了一个简短的演示:http://codepen.io/cgav/pen/MaKbJg?editors=101

HTML:

<img id="image" />

JS:

allImages = []
urls = [
  # the images' URLs go in here
]

DURATION = 10

startTimer = ->
  domImage = document.getElementById("image")
  counter = 0
  setInterval ->
    domImage.src = allImages[counter].dataurl
    counter++
    counter = 0 if counter is allImages.length
  , DURATION

storeNextDataURLFromImage = () ->
  url = urls.pop()
  if not url?
    return startTimer()

  img = new Image()
  img.crossOrigin = "Anonymous"  # this is needed to avoid http://stackoverflow.com/questions/22710627/tainted-canvases-may-not-be-exported 
  img.onload = (e) ->
    canvas = document.createElement("canvas")
    canvas.width = img.width
    canvas.height = img.height

    ctx = canvas.getContext("2d")
    ctx.drawImage(img, 0, 0)
    allImages.push {
      dataurl: canvas.toDataURL()
      width: img.width
      height: img.height
    }
    storeNextDataURLFromImage()

  img.src = url

storeNextDataURLFromImage()  
相关问题