Thanks Steven, I appreciate the time looking into it. Just to give you an update on what I'm doing currently, I'm just loading the first image (if it exists) where the gallery would be, with the loading icon. That's displayed until the page communicates back to the site with AJAX to have the plugin check for the correct number of images. It then loads the JB gallery, replacing the image/loading icon.

Here's what that looks like: http://prntscr.com/n00ws7 (initial page load) -> http://prntscr.com/n00y33 (few seconds later). At least with this way, the user won't have possibly switched images when the gallery re/loads.

Thanks Steven, I didn't see that there was a reply earlier (no email that I saw).

I appreciate the thinking out loud.

Typically, here's how the loading time looks:

  • WordPress generates the page content, typically about 0.3s

  • Our API gets listing data, if not server (API) cached, ~4-5s, if server cached, ~0.9s - ~2s, if locally cached, ~0.1s

  • Any other API requests run, but for the sake of this, let's say there's none (0s, though usually there's some other cached things, or if you're registered, some calls to record visit/ get notes/favorite status of listing)

I have timed my image checker on something with ~36 images (probably above avg image count, and inbetween my blocks of 10 checking), and it was ~1.3s - ~2.7s (and I added caching for it, so if we HAVE checked for the image count before, it gets cached in WordPress, ~0.1s. It seems like that getting responses from the server about images can also be server cached, so running the same query again without local caching takes as low as ~0.4s). Not bad, but because this is WordPress/PHP, there's no page output until everything is done.

So adding it all up, we get anywhere from ~0.5s (everything cached) - ~8.1s (nothing cached). So, quite a range, but my focus is going to be on reducing the top end. In this case, 8.1s for a page to START loading content is just too high. This is why I wanted to see about dynamically adjusting the photo count later. Most listings (if they have photos) are going to probably have more than 6 (our max thumbnail count), and by the time a user got to photo 7+ would have been more than enough time to get the correct photo count.

I'll have to play around with just refreshing the gallery, and see how (maybe) jarring it is, but I should be able to get what image they're on, and return them to that.

What you've suggested with CSS, is almost how it was originally before my initial edits, where the page would load, and JS on the page would send back to the site, which would send to the API to build the XML, and then back to the site and back to JS before the gallery loaded. This was also sent with several other AJAX requests, and usually was stalled until those finished first. When this was the behavior, we just used the JuiceBox loading icon (.gif) until that request completed.

On a quick note about the loading icon, when I was initially looking at reducing the amount of requests on our pages, I replaced the .gif file with a CSS animated loading icon, modeled after the .gif (saves some KB, and a request, just to share):

<style>
div#jb-custom-loading div.ds-spin-container{width:100px;height:100px;background:#000;position:absolute;transform:translate(-50%,-50%);top:230px;left:50%;border-radius:10px;border:1px solid #000;z-index:0}
div#jb-custom-loading div.ds-spin-teardrop{position:absolute;top:50%;left:50%;background-color:#000;display:block;width:12px;padding:3px 2px 5px!important;height:8px;border-top-left-radius:9px;border-bottom-left-radius:9px;border-bottom-right-radius:9px;box-shadow:0 0 8px gray;transform:translate(-50%,-50%) rotate(-45deg);margin:0;box-sizing:content-box!important;z-index:0}
div#jb-custom-loading div.ds-spin-hexagon{position:absolute;width:60px;height:34.642px;background-color:#fff;margin:0!important;padding:0!important;top:33px;left:20px;z-index:0}
div#jb-custom-loading div.ds-spin-hexagon:before,div#jb-custom-loading div.ds-spin-hexagon:after{content:"";position:absolute;width:0;height:0;transform:translate(-50%,-50%);border-left:30px solid transparent;border-right:30px solid transparent}
div#jb-custom-loading div.ds-spin-hexagon:before{top:-24%;left:50%;border-bottom:17.32px solid #fff}
div#jb-custom-loading div.ds-spin-hexagon:after{bottom:-74%;left:50%;border-top:17.32px solid #fff}
div#jb-custom-loading div.ds-spin-spin{-webkit-animation:ds-spin 4s linear infinite;-moz-animation:ds-spin 4s linear infinite;animation:ds-spin 4s linear infinite}
@-moz-keyframes ds-spin { 100%{-moz-transform:rotate(360deg)} }
@-webkit-keyframes ds-spin { 100%{-webkit-transform:rotate(360deg)} }
@keyframes ds-spin { 100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)} }
</style>
<div id="jb-custom-loading">
    <div class="ds-spin-container">
        <div class="ds-spin-hexagon ds-spin-spin"> </div>
        <div class="ds-spin-teardrop"> </div>
    </div>
</div>

As for performing a string manipulation on the configuration data, that's not specifically possible because all images that you request from the server are .jpg, whether they exist or not. You have to look at the image/ response headers to know if it's an SVG or not.

But as I mentioned, I'll likely just have to go back to either delaying the gallery from loading for a couple seconds after the page loads, or experiment with just refreshing the gallery when I know the correct photo count.

Thanks,
Tony.

Hello Steven,

It sounds like that I probably can't do what I'm looking for specifically, however here's generally how the 'XML' is generated. Also note that I have slightly modified the JuiceBox code so that the configUrl can directly take the normal 'XML' files contents inline and load it with the page (to avoid an AJAX request, and because the content is dynamic):

  • WordPress page is loaded for a Real Estate listing

  • Our plugin makes a call to our API server to load listing data

  • Listing data includes the photo count for the listing, and the photo base URL

  • Plugin takes photo count and photo base to build 'XML', like this: http://prntscr.com/mwxtfu

  • Without including the XML inline, it's normally a AJAX request to the site that builds the file dynamically with PHP, checking with the API server to get details

The issue however is that occasionally (because of caching) the API server reports 0 photos available, even if we do have photos available. When it reports 0, I have a quick check if the base image (for example: https://images.marketleader.com/HouseIm … 04168.jpg) exists. If it does, I have it switch from 0 photos available to 50, and build the XML with that.

I can then have the page check back in to validate how many images actually exist, but I don't do that when generating the 'XML' config to reduce loading time.

The only way that I can think of to really validate if an image exists is to get the response headers from the image, and look at the 'content type'. If it's not valid, a SVG image is returned. Otherwise, it should be JPG (for SVG example: https://images.marketleader.com/HouseIm … hoto.jpg).

Currently my solution to this is to check every 10 images, and if we encounter a SVG, count down until we find the correct image. So it'll check f_photo_10.jpg, if it's a jpg, check f_photo_20.jpg, etc. When it encounters a SVG, say at _40.jpg, it checks the headers counting back down: _39.jpg > SVG > _38.jpg > SVG > etc, until it finds the last valid image, say _33.jpg. I now know that there's 34 images (starts at 0), and I could either build a new configUrl, or simply send the real photo count back to the site.

Ideally I would want to just send the real photo count back to the site (though AJAX to avoid affecting initial page load), and have the site/ JuiceBox simply remove image indexes 35 - 50, as they're not valid. Sounds like that I would have to send a new configUrl however and reload the Juicebox gallery.

I can also detect on the page if the image is invalid as the SVG image is naturally 300x131, which most real images are not (not a great solution, but best I could come up with myself in JS).

Overall obviously the best option is to simply make sure that the server is sending the correct photo count, but unfortunately the database team that I'm working with isn't willing to make changes to the caching/ data. So I'm trying to workaround it with what I have access to.

If something here doesn't make sense or you'd like more information, just let me know.

Thanks,
Tony.

Hello,

I currently am using the gallery on a page for Real Estate listings, and occasionally I do not know how many images are in the gallery, so the XML file that's generated is simply generated out to 50 images. This causes a problem if there's less than 50 images for the listing. For example: http://prntscr.com/mwhb8p

I was looking at the API here: https://www.juicebox.net/support/api/, and I can use .onImageChange to detect if the image is valid or not, however I don't see a way to remove an image index from the gallery.

I could use some JS to remove the image containers/ thumbnails when an invalid photo is viewed, but it will come back when switching thumbnail pages, for example. Is there any API or functionality for removing an image from the gallery after the page has loaded?

Thanks,
Tony.

Hello Steven,

I think that I found what I was looking for, around line 14612:

var bL = function (a) {
//return;
if (a == "false") return;

With this, I don't see any 404's or anything, and I don't see any stylesheets trying to be loaded on the page, so I believe that this is what I was looking for. Using a == "false" means that I can change themeUrl to "false", and be able to load the juicebox.css file bundled with another combined stylesheet.

I'm using a string "false" as I'm generating this in PHP which doesn't translate booleans too well.

Thanks,
Tony

Thanks for the reply Steven, off the top of your head, there's nothing in the JS that I could change so that if themeUrl == "false" for example, it doesn't try to load it?

I tried to follow the code, but it was a bit too much for me regarding how the themeUrl is processed/ loaded.

I was able to previously make a change that allowed me to inline the XML file that 'configUrl' looks for, and if it's the start of the XML file, simple read it from there, reducing a request to get the XML file (http://prntscr.com/lrt64k).

I tried looking at the

D.theme = J(D.themeurl, D.theme);

line, figured it was somewhere around there, but I don't really see where the stylesheet is being loaded.

Using http://0.0.0.0 from what I've seen would (to me, probably) be better than trying to load an empty file, as that's still an extra get request, which takes time and can stall other things.

Hello,

I am using Juicebox embedded on a page, and would like to combine the theme.css file into another CSS file that's loaded on the page, reducing requests. However, there doesn't appear to be a way to disable the 'themeUrl' parameter, to have it NOT try to load a CSS file.

Is there a way to disable Juicebox from trying to load the theme.css file completely, and letting it simply continue without loading a file?

I could use http://0.0.0.0 for the themeUrl, as this sort of does avoid a request (takes ~2μs in the network tab, vs ~300ms for a invalid path, ~1s for 127.0.0.1), but would rather not have a 404 show up in the network/ console tabs.

Thanks,
Tony

I have tried with the current 1.5.1 Lite version, and it does appear to work there. So it looks like that this is a bug that existed in 1.2.0. We will have to see about updating, since what we're using is ~6 years old at this point.

After some basic testing, the jb.onInitComplete function does not appear to trigger on smaller screen devices that trigger the mobile gallery view.

For an example, check out: https://www.dstestblog.com/tony-clean/idx/mls-1381735- from both a desktop view and mobile device (browser emulated mobile device would be best, to be able to see the console).

Here's the function:

<script type="text/javascript">
    jQuery(document).ready( function() {
        jb = new juicebox({
            containerid: 'dsidx-media',
            galleryWidth: '100%',
            galleryHeight: '100%',
            configUrl: dsidx.details.GetConfigUrl(),
            themeUrl: 'https://api-idx.diversesolutions.com/Styles/Libraries/juicebox/theme.css',

            enableAutoplay: 'true',
            showautoplaybutton: false,
            autoPlayOnLoad: true,
            galleryTitlePosition: 'NONE',
            showImageOverlay: 'auto',
            thumbHeight: '60',
            thumbWidth: '60',
            thumbSelectedFrameWidth: '5',
            captionPosition: 'NONE',
            expandInNewPage: 'false',
            backgroundColor: 'transparent',
            imageScaleMode: 'SCALE_DOWN'
        });
        jb.onInitComplete = function(){
        console.log('woof');
            if(jb.getImageCount() <= 1){
                jb.toggleThumbs();
            }
        }
        jb.onExpand = function(){
            dsidx.details.trackGalleryExpand();
        }
    });
</script>

As you can see, we have a console.log('woof'); in there, which on desktop, works: http://prntscr.com/ll9fhx

However, when emulating a mobile view, the jb.onInitComplete and the console.log (along with everything else) aren't triggered: http://prntscr.com/ll9g6m

Is there a reason for this? Currently the JuiceBox version that's in use is Juicebox-Pro 1.2.0, I have not tried with the current 1.5.1 Lite.

Am I missing something here, or is this an existing JuiceBox bug? Everything else appears to be functioning correctly.