How to load hospital favorites instantly instead of paginating through 5000+ items? Answered

Post author
Jordan Winn

I have built a hospital directory at https://www.nursingusa.com – creating an account allows users to save hospitals to their favorites, which displays in their profiles.

Currently, this is SLOWLY loading the favorites list, 100 at a time. So if you save a hospital that starts with the letter "z", it has to slowly load/hide 5000+ hospitals, before your favorite shows up.

I need help figuring out how to speed this up. It's layered in via Memberstack + Finsweet

Comments

3 comments

  • Comment author
    A J

    Hey Jordan Winn,

    I am assuming you are using #106 memberscript for the saving favorites functionality.

    Can you try cloning your profile page where you show saved hospitals and try implementing the following code instead of the memberscript that you have currently in the custom code section?

    <style>
      [ms-code-save], [ms-code-unsave] {
        display: none;
      }
      [ms-code-save-item] {
        display: none;
      }
    </style>
    <script>
    document.addEventListener("DOMContentLoaded", function() {
      const memberstack = window.$memberstackDom;
      let isLoggedIn = false;
      let savedItems = new Set(); 
    
      async function checkMemberLogin() {
        try {
          const member = await memberstack.getCurrentMember();
          return !!member;
        } catch (error) {
          return false;
        }
      }
    
      function getSavedItems(memberData) {
        return new Set(memberData.savedItems || []); 
      }
    
      function updateButtonVisibility() {
        const saveButtons = document.querySelectorAll('[ms-code-save]');
        const unsaveButtons = document.querySelectorAll('[ms-code-unsave]');
    
        saveButtons.forEach(button => {
          const itemId = button.getAttribute('ms-code-save');
          button.style.display = !savedItems.has(itemId) ? 'block' : 'none';
        });
    
        unsaveButtons.forEach(button => {
          const itemId = button.getAttribute('ms-code-unsave');
          button.style.display = savedItems.has(itemId) ? 'block' : 'none';
        });
      }
    
      function updateItemVisibility() {
        const saveLists = document.querySelectorAll('[ms-code-save-list]');
        saveLists.forEach(list => {
          const filter = list.getAttribute('ms-code-save-list');
          const items = list.querySelectorAll('[ms-code-save-item]');
          items.forEach(item => {
            const saveButton = item.querySelector('[ms-code-save]');
            if (!saveButton) {
              item.style.display = 'block';
              return;
            }
            const itemId = saveButton.getAttribute('ms-code-save');
    
            if (!isLoggedIn || filter === 'all') {
              item.style.display = 'block';
            } else if (filter === 'saved' && savedItems.has(itemId)) {
              item.style.display = 'block';
            } else if (filter === 'unsaved' && !savedItems.has(itemId)) {
              item.style.display = 'block';
            } else {
              item.style.display = 'none';
            }
          });
        });
      }
    
      async function handleButtonClick(event) {
        if (!isLoggedIn) return;
    
        const button = event.currentTarget;
        const action = button.getAttribute('ms-code-save') ? 'save' : 'unsave';
        const itemId = button.getAttribute(action === 'save' ? 'ms-code-save' : 'ms-code-unsave');
    
        if (action === 'save' && !savedItems.has(itemId)) {
          savedItems.add(itemId);
        } else if (action === 'unsave') {
          savedItems.delete(itemId);
        }
    
        try {
          await memberstack.updateMemberJSON({ json: { savedItems: Array.from(savedItems) } }); 
        } catch (error) {
          // Silently handle the error
        }
    
        updateButtonVisibility();
        updateItemVisibility();
      }
    
      function addClickListeners() {
        const saveButtons = document.querySelectorAll('[ms-code-save]');
        const unsaveButtons = document.querySelectorAll('[ms-code-unsave]');
        saveButtons.forEach(button => button.addEventListener('click', handleButtonClick));
        unsaveButtons.forEach(button => button.addEventListener('click', handleButtonClick));
      }
    
      async function initializeScript() {
        isLoggedIn = await checkMemberLogin();
    
        if (isLoggedIn) {
          try {
            const result = await memberstack.getMemberJSON();
            const memberData = result.data || {};
            savedItems = getSavedItems(memberData);
          } catch (error) {
            // Silently handle the error
          }
        }
    
        updateButtonVisibility();
        updateItemVisibility();
        addClickListeners();
    
        // Set up a MutationObserver to watch for changes in the DOM
        const observer = new MutationObserver((mutations) => {
          let shouldUpdate = false;
          mutations.forEach((mutation) => {
            if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
              shouldUpdate = true;
            }
          });
          if (shouldUpdate) {
            updateButtonVisibility();
            updateItemVisibility();
            addClickListeners();
          }
        });
    
        // Start observing the document with the configured parameters
        observer.observe(document.body, { childList: true, subtree: true });
      }
    
      initializeScript();
    });
    </script>
    

    This is a modification of the #106 memberscript, test this out in the cloned page and see if it helps in loading time of the saved items.

    0
  • Comment author
    Jordan Winn

    Thank you so much for hopping in to help, A J! This isn't loading Favorites any faster.  I have two other scripts loading here, I'm wondering if these slow this down?

    <!-- Finsweet Attributes -->
    <script async type="module"
    src="https://cdn.jsdelivr.net/npm/@finsweet/attributes@2/attributes.js"
    fs-list
    ></script><!-- [Attributes by Finsweet] CMS Load -->
    <script async src="https://cdn.jsdelivr.net/npm/@finsweet/attributes-cmsload@1/cmsload.js"></script><!-- [Attributes by Finsweet] CMS Filter -->
    <script async src="https://cdn.jsdelivr.net/npm/@finsweet/attributes-cmsfilter@1/cmsfilter.js"></script>

    0
  • Comment author
    A J

    Jordan Winn, welcome.It might take time to load all the items via Webflow and Finsweet (especially if there are large number of items). That being said, it looks like you are using the latest version of Finsweet (i.e v2) via

    <!-- Finsweet Attributes -->
    <script async type="module"
    src="https://cdn.jsdelivr.net/npm/@finsweet/attributes@2/attributes.js"
    fs-list
    ></script>
    

    Just to keep things clean and consistent, you might consider adapting the CMS with relevant updated attributes wherever you are using CMS Load and Filter of v1 and then update / remove the next two scripts as it might seem fit as per Finsweet's docs.

    It is said that v2 has improved performance as well, so not sure if it will help in loading the items in a better pace, but could be worth a try.

    Alternatively, you could split the CMS based on some groups (that is if CMS items can be clubbed based on their category as such), so that you don't have all 5000+ items load at once but have a visual interface where the items are segmented and loaded separately via CMS to see if that helps.

    Hope this gives you some idea.

    0

Please sign in to leave a comment.