Image fails to load in rare cases. Preload issue?

On a webpage, I have 2 images on top of each other. When clicking a button, it hides one and shows the other.

var VAL = true
var INFUNCTION = false

async function onClick() {
   // to avoid double clicks
   if (INFUNCTION) { return; }
   INFUNCTION = true
   VAL = ! VAL
   await setVal(VAL)
   INFUNCTION = false
}
async function setVal() {
   if ( VAL) {
    	$w("#image0".hide()
	await $w("#image1").show("turn", {"duration" : 500})
   }
   else {
    	$w("#image1".hide()
	await $w("#image0").show("turn", {"duration" : 500})
   }
}

However, on some very rare cases, the new image fails to appear on the screen. I get the following error when this happens, in the web developer console.

Any insight much appreciated. Thanks!

The resource at “https://siteassets.parastorage.com/pages/pages/thunderbolt?beckyExperiments=specs.thunderbolt.videobox_united%3Atrue%2Cspecs.thunderbolt.image_placeholder%3Atrue%2Ctb_UploadButtonFixValidationNotRequired%3Atrue%2Cspecs.thunderbolt.dontMergeAdvancedSeoDataForML%3Atrue%2Cspecs.thunderbolt.editor_elements_site_assets%3Atrue%2Cspecs.thunderbolt.tb_media_layout_by_effect%3Atrue&contentType=application%2Fjson&dfCk=6&dfVersion=1.1187.0&experiments=bv_migrateResponsiveLayoutToSingleLayoutData%2Cbv_migrateResponsiveToVariantsModels%2Cbv_remove_add_chat_viewer_fixer%2Cdm_removeMissingResponsiveRefs%2Csv_unquoteUsedFontsInDataFixer%2Csv_usedFontsDataFixer&fileId=3440cac3.bundle.min&isHttps=true&isPremiumDomain=true&isUrlMigrated=true&isWixCodeOnPage=false&isWixCodeOnSite=true&language=en&metaSiteId=242698c4-2c1f-4024-83ff-5f94ec28b733&module=thunderbolt-platform&originalLanguage=fr&pageId=73eea8_4eda0af9ef83c1aabc67f3b220957ba7_373.json&quickActionsMenuEnabled=false&registryLibrariesTopology=%5B%7B%22artifactId%22%3A%22editor-elements%22%2C%22url%22%3A%22https%3A%2F%2Fstatic.parastorage.com%2Fservices%2Feditor-elements%2F1.4095.0%22%2C%22manifestName%22%3A%22library-manifest%22%7D%2C%7B%22artifactId%22%3A%22editor-elements-design-systems%22%2C%22url%22%3A%22https%3A%2F%2Fstatic.parastorage.com%2Fservices%2Feditor-elements%2F1.4095.0%22%2C%22manifestName%22%3A%22design-systems-manifest%22%7D%5D&remoteWidgetStructureBuilderVersion=1.226.0&siteId=8a2c90ca-3ce7-4ae4-8aa3-fcefe66c3a35&siteRevision=373&tbElementsSiteAssets=siteAssets.9ef97c5f.bundle.min.js&viewMode=desktop” preloaded with link preload was not used within a few seconds. Make sure all attributes of the preload tag are set correctly. morpion

The resource at “https://siteassets.parastorage.com/pages/pages/thunderbolt?beckyExperiments=specs.thunderbolt.videobox_united%3Atrue%2Cspecs.thunderbolt.image_placeholder%3Atrue%2Ctb_UploadButtonFixValidationNotRequired%3Atrue%2Cspecs.thunderbolt.dontMergeAdvancedSeoDataForML%3Atrue%2Cspecs.thunderbolt.editor_elements_site_assets%3Atrue%2Cspecs.thunderbolt.tb_media_layout_by_effect%3Atrue&contentType=application%2Fjson&dfCk=6&dfVersion=1.1187.0&experiments=bv_migrateResponsiveLayoutToSingleLayoutData%2Cbv_migrateResponsiveToVariantsModels%2Cbv_remove_add_chat_viewer_fixer%2Cdm_removeMissingResponsiveRefs%2Csv_unquoteUsedFontsInDataFixer%2Csv_usedFontsDataFixer&fileId=3440cac3.bundle.min&isHttps=true&isPremiumDomain=true&isUrlMigrated=true&isWixCodeOnPage=true&isWixCodeOnSite=true&language=en&metaSiteId=242698c4-2c1f-4024-83ff-5f94ec28b733&module=thunderbolt-platform&originalLanguage=fr&pageId=73eea8_fcab92076aeae13003bc689e7e6de3c3_373.json&quickActionsMenuEnabled=false&registryLibrariesTopology=%5B%7B%22artifactId%22%3A%22editor-elements%22%2C%22url%22%3A%22https%3A%2F%2Fstatic.parastorage.com%2Fservices%2Feditor-elements%2F1.4095.0%22%2C%22manifestName%22%3A%22library-manifest%22%7D%2C%7B%22artifactId%22%3A%22editor-elements-design-systems%22%2C%22url%22%3A%22https%3A%2F%2Fstatic.parastorage.com%2Fservices%2Feditor-elements%2F1.4095.0%22%2C%22manifestName%22%3A%22design-systems-manifest%22%7D%5D&remoteWidgetStructureBuilderVersion=1.226.0&siteId=8a2c90ca-3ce7-4ae4-8aa3-fcefe66c3a35&siteRevision=373&tbElementsSiteAssets=siteAssets.9ef97c5f.bundle.min.js&viewMode=desktop” preloaded with link preload was not used within a few seconds. Make sure all attributes of the preload tag are set correctly. morpion

The resource at “https://static.parastorage.com/services/wix-code-viewer-app/1.753.0/app.js” preloaded with link preload was not used within a few seconds. Make sure all attributes of the preload tag are set correctly. morpion

The resource at “https://static.parastorage.com/services/editor-elements/dist/componentSdks.8efda8fe.bundle.min.js” preloaded with link preload was not used within a few seconds. Make sure all attributes of the preload tag are set correctly. morpion

The resource at “https://static.parastorage.com/services/wix-code-platform/1.739.0/wixCodeNamespacesAndElementorySupport.min.js” preloaded with link preload was not used within a few seconds. Make sure all attributes of the preload tag are set correctly. morpion

The resource at “https://53e1429b-4e8a-41c4-b9eb-84bfb2194154.static.pub.wix-code.com/static/v2/09ed56cc-9211-41fa-ba7c-a335abd8eab2/53e1429b-4e8a-41c4-b9eb-84bfb2194154/pages/zpi11.js?use_core_ng=true” preloaded with link preload was not used within a few seconds. Make sure all attributes of the preload tag are set correctly.

One thing I see is that you have a function with 3 parameters:

async function setVal(val, row, col)

You only call it with one parameter:

await setVal(VAL)

And in the function itself you don’t use any of the parameters. Instead you use the global variable VAL instead of the val variable being passed to the function as a parameter.

I also cobbled together a quickie test. I start with #imgIn shown and #imgOut hidden. I added the following code to toggle the images being shown:

export async function btnSwitch_click(event) {
  let stateIn = $w('#imgIn').hidden;
  let stateOut = $w('#imgOut').hidden;
  if(stateIn === false && stateOut === true) {
     await $w('#imgIn').hide();
     $w('#imgOut').show("turn", {"duration" : 500});
  }
  else {
     $w('#imgOut').hide();       
     await $w('#imgIn').show("turn", {"duration" : 500});
  }
}

Works just fine.

See the Toggle Images example.

Hey, thanks for your test. It works fine 90% of the time for me, but sometimes I have this rare error about preload issue. Do you know why that could be?

@sebastienmoutondev From what I understand, when you get the “error” (I think it’s really a warning), the image isn’t displayed?

There might be an issue with the Promises returned from the hide() and show(). Did you try my code in your site?

If you’re still encountering issue, please post the URL and explain what I need to do to see the problem.

@yisrael-wix Correct, when I get this warning, the image is not displayed on the website.

Let me try your code. I have a hunch that your code will solve the problem thanks to you marking hide as await, which I didn’t do.

In any case thanks a lot for your help, I will revert back later if I still see the problem with your code.

@yisrael-wix Unfortunately, that did not fix it. I added an “await” in front of all my “hide” statements, but that did not solve the problem

Here’s the link:

www DOT harint DOT com/morpion?lang=en

If you click many times on the “start over” button, at some random point the cross in the middle will not be shown. If you press one more time, the cross will show. Here’s the code for how I show it (I tried to remove the superfluous code in there to make it easier to read for you).

For clarity : " $w( “#image” + r + c)" is an empty image (showing an empty slot)
and “$w( “#image” + r + c + 0)” is the image of a cross, while “$w( “#image” + r + c + 1)” is the image of naught. These 3 images are stacked up, and I show and hide as appropriate to reflect the state of the game.

var ALLOW_USER_ACTION = true

$w.onReady(async function () {
    console.log("here")
    $w("#buttonStartOver").onClick(startOver)
}

async function startOver() {
 if (!ALLOW_USER_ACTION) {console.log("startOver bypass " + ALLOW_USER_ACTION); return;}
    console.log("startOver 1 " + CURRENT_STATUS + " " +  ALLOW_USER_ACTION)
    ALLOW_USER_ACTION = false
    console.log("startOver 2 " + CURRENT_STATUS + " " +  ALLOW_USER_ACTION)
    await wipeBoard()
    await setVal1(1, 1)
    ALLOW_USER_ACTION = true
}

async function wipeBoard() {
 // we first hide all_cases
 // and then we'll show all_cases
 // (to avoid the race condition where the hide, started before the show, resolves after)
 let all_promises = []
 for (let r = 0 ; r < num_rows; ++r) {
        for (let c = 0 ; c < num_cols; ++c) {
            board[r * num_cols + c] = 0
            all_promises.push($w("#image" + r + c).hide()) // empty
            all_promises.push($w("#image" + r + c + "0").hide()) // cross
            all_promises.push($w("#image" + r + c + "1").hide()) // naught
        }
    }

 // wait for all promises to be resolved
 await Promise.all(all_promises)

    all_promises = []

 for (let r = 0 ; r < num_rows; ++r) {
 for (let c = 0 ; c < num_cols; ++c) {
            board[r * num_cols + c] = 0
            all_promises.push($w("#image" + r + c).show()) // show empty spot
        }
    }
 await Promise.all(all_promises)
}

async function setVal1(row, col) {
    console.log("set val " + val + " " + row + " " + col)

    await $w("#image" + row + col).hide() // empty
    await $w("#image" + row + col + "0").hide() // cross
    await $w("#image" + row + col + "1").hide() // naught
    console.log("before COMPVAL")
    console.log("setVal AA " + $w("#image" + row + col + "0").hidden)
    let res = await $w("#image" + row + col + "0").show("turn", {"duration" : 500})
    console.log("setVal AB " + $w("#image" + row + col + "0").hidden)
    console.log("after COMPVAL " + $w("#image" + row + col + "0").hidden + " " + $w("#image" + row + col).hidden)
   
}


@sebastienmoutondev It’s like this…

I suspect - only suspect at this point - that this might be related to a recent performance release. I am still evaluating.

I do see that every once in a while the X doesn’t display after clicking on the Start Over button. However, I don’t see any error messages being displayed. I suspect that although the algorithm knows that there is an X in the middle, the image itself isn’t displayed.

I will send this to QA for evaluation regarding the performance release, but as it is, the code is quite complex.

If you can, please set up a simple test page with the simplest scenario possible that shows this problem. This will make it much easier for QA to identify the problem.

@yisrael-wix Ok, thanks for that. Yes, I agree it feels like a bug.

I’ll try to set up a page with a simple example. Thank you.

@yisrael-wix ok I managed to set up a much simpler example.

see page www DOT harint DOT com / problematic

here is the code :

var SHOW_CROSS = true

$w.onReady(function () {
    $w("#button1").onClick(onClick)
});

async function onClick() {
  if (SHOW_CROSS) {
    await $w("#image1").hide()
    await $w("#image2").show("turn")
  }
  else {
    await $w("#image2").hide()
    await $w("#image1").show("turn")
  }
  SHOW_CROSS = !SHOW_CROSS
}

If you press many times on the button, at a random point, you will see no images at all. Given this simple code, I believe it should never happen. With multiple clicks, it is expected that sometimes both images will appear, but it should not be the case that none appear (because the last onClick call necessarily ends with a “show”).

I think that’s probably a good minimal case for QA to review.

Please keep me updated as I am keen to get this working on my website. Thanks!

@sebastienmoutondev This page doesn’t work at all. I get multiple images displayed at once, or none at all. If you check the logic, I’m sure you’ll see that it in itself is problematic and not what you intend.

For now, I hope that QA can deal with the original page even though it’s quite complex.

@yisrael-wix Hey Yisrael. That is actually what I intended. I agree this page does not make sense as something for users to see, but it is a good example to show the problem.
Given the code, it is expected than sometimes both images will show together : when 2 onClicks have been fired : let’s call them onClick1 and onClick2. Because they are on 2 different “threads”, both images will show when this line of onClick1 :

await $w("#image2").show("turn")

happens to be ran between these 2 lines of onClick2 :

await $w("#image2").hide()
await $w("#image1").show("turn")

However, there is NO scenario when we should see no image at all, because even in a storm of “onClick”, the last thread always finishes with a call to “show”.

So I believe it should be a good example for QA, because the code is simpler that the previous example, and it is quicker to reproduce the problem (i.e. see no image at all).

By the way, I think you are likely correct that this issue might not be related to the warning I pasted at the beginning. In any case, I’ve seen it happening in cases where the warning was not printed.

@sebastienmoutondev The logic in your sample code causes the problem. I believe that the original page is in fact a Velo bug related to the performance release.

@yisrael-wix Hi Yisrael,

I think I have isolated further the problem. Or it might be a new problem.

I have a very simple code that creates an issue.

Here’s the page : www DOT harint DOT com / problematic2
Here’s the code :

$w.onReady(async function () {
    await $w("#image1").hide()
    await $w("#image2").hide()
    await $w("#image1").show("turn")
});

As you load the page the first time, the image will NOT show.

However, if you instead use this code (I just remove the argument “turn” ):

$w.onReady(async function () {
    await $w("#image1").hide()
    await $w("#image2").hide()
    await $w("#image1").show()
});

Then the image will show. So there might be a bug in the show function.

@sebastienmoutondev This looks interesting. There are a number of issues involved here which I’m evaluating. I will turn over to QA when I figure out what’s going on.

Thanks! This is great. :beers:

@yisrael-wix Thank you! I noticed that the issue in the second case is that the statement " await $w( “#image1” ).show( “turn” ) "never returns. It does not raise an error, it just hangs there and never finishes.

About your code:
$w . onReady ( async function () {
await $w ( “#image1” ). hide ()
await $w ( “#image2” ). hide ()
await $w ( “#image1” ). show ()
});

Try it without an await when showing the image like this.

$w . onReady ( async function () {
await $w ( “#image1” ). hide ()
await $w ( “#image2” ). hide ()
$w ( “#image1” ). show ()
});
I think when you await more then 1 element it gets on an pile, the last added to the pile is used first (if i’m correct.
But if u don’t use an await when showing then the first to pile, do what they have to do and then the last element u used wil fire since it doesn’t have await it waits on the others and then when the pile is gone it fires

So in a smal example of how i think it goes.
Await Image1.hide
Await Image2.hide
Await Image1.show

Wil actualy pile up wich makes image1.show on top and first completes.
Then image2.hide
Then image1.hide

Just a gues

@volkaertskristof It should not work that way. It should work serially. The await keyword pauses execution of the container async function until a Promise is resolved.