diff --git a/basicswap/static/js/offerstable.js b/basicswap/static/js/offerstable.js
index 9cd30f6..7f3b30e 100644
--- a/basicswap/static/js/offerstable.js
+++ b/basicswap/static/js/offerstable.js
@@ -75,6 +75,7 @@ let filterTimeout = null;
 // CONFIGURATION CONSTANTS
 // TIME CONSTANTS
 const CACHE_DURATION = 10 * 60 * 1000;
+const wsPort = config.port || window.ws_port || '11700';
 
 //  APP CONSTANTS
 const itemsPerPage = 50;
@@ -206,7 +207,7 @@ const WebSocketManager = {
                 this.connect();
             }
             this.startHealthCheck();
-        }, 1000);
+        }, 0);
     },
 
     startHealthCheck() {
@@ -1158,26 +1159,50 @@ async function fetchOffers() {
     const refreshText = document.getElementById('refreshText');
 
     try {
-        refreshButton.disabled = true;
-        refreshIcon.classList.add('animate-spin');
-        refreshText.textContent = 'Refreshing...';
-        refreshButton.classList.add('opacity-75', 'cursor-wait');
+        if (refreshButton) {
+            refreshButton.disabled = true;
+            refreshIcon.classList.add('animate-spin');
+            refreshText.textContent = 'Refreshing...';
+            refreshButton.classList.add('opacity-75', 'cursor-wait');
+        }
 
-        const endpoint = isSentOffers ? '/json/sentoffers' : '/json/offers';
-        const response = await fetch(endpoint);
-        const data = await response.json();
+        const [offersResponse, pricesData] = await Promise.all([
+            fetch(isSentOffers ? '/json/sentoffers' : '/json/offers'),
+            fetchLatestPrices()
+        ]);
 
-        jsonData = formatInitialData(data);
+        if (!offersResponse.ok) {
+            throw new Error(`HTTP error! status: ${offersResponse.status}`);
+        }
+
+        const data = await offersResponse.json();
+        const processedData = Array.isArray(data) ? data : Object.values(data);
+        
+        jsonData = formatInitialData(processedData);
         originalJsonData = [...jsonData];
 
+        latestPrices = pricesData || getEmptyPriceData();
+
         await updateOffersTable();
         updatePaginationInfo();
 
     } catch (error) {
         console.error('[Debug] Error fetching offers:', error);
+
+        const cachedOffers = CacheManager.get('offers_cached');
+        if (cachedOffers?.value) {
+            jsonData = cachedOffers.value;
+            originalJsonData = [...jsonData];
+            await updateOffersTable();
+        }
         ui.displayErrorMessage('Failed to fetch offers. Please try again later.');
     } finally {
-        stopRefreshAnimation();
+        if (refreshButton) {
+            refreshButton.disabled = false;
+            refreshIcon.classList.remove('animate-spin');
+            refreshText.textContent = 'Refresh';
+            refreshButton.classList.remove('opacity-75', 'cursor-wait');
+        }
     }
 }
 
@@ -1467,78 +1492,50 @@ async function updateOffersTable() {
             window.TooltipManager.cleanup();
         }
 
-        const PRICES_CACHE_KEY = 'prices_coingecko';
-        const cachedPrices = CacheManager.get(PRICES_CACHE_KEY);
-        latestPrices = cachedPrices?.value || getEmptyPriceData();
-
         const validOffers = getValidOffers();
-        const startIndex = (currentPage - 1) * itemsPerPage;
-        const endIndex = Math.min(startIndex + itemsPerPage, validOffers.length);
-        const itemsToDisplay = validOffers.slice(startIndex, endIndex);
-
-        fetchLatestPrices().then(freshPrices => {
-            if (freshPrices) {
-                latestPrices = freshPrices;
-                updateProfitLossDisplays();
-            }
-        }).catch(error => {
-            console.warn('Price fetch failed:', error);
-        });
-
-        const BATCH_SIZE = 5;
-        const identities = [];
-        for (let i = 0; i < itemsToDisplay.length; i += BATCH_SIZE) {
-            const batch = itemsToDisplay.slice(i, i + BATCH_SIZE);
-            const batchPromises = batch.map(offer =>
-                offer.addr_from ? IdentityManager.getIdentityData(offer.addr_from) : Promise.resolve(null)
-            );
-            const batchResults = await Promise.all(batchPromises);
-            identities.push(...batchResults);
-            if (i + BATCH_SIZE < itemsToDisplay.length) {
-                await new Promise(resolve => setTimeout(resolve, 100));
-            }
-        }
-
         if (validOffers.length === 0) {
             handleNoOffersScenario();
             return;
         }
 
-        const totalPages = Math.max(1, Math.ceil(validOffers.length / itemsPerPage));
-        currentPage = Math.min(currentPage, totalPages);
-
-        const existingRows = offersBody.querySelectorAll('tr');
-        existingRows.forEach(row => {
-            cleanupRow(row);
-        });
+        const startIndex = (currentPage - 1) * itemsPerPage;
+        const endIndex = Math.min(startIndex + itemsPerPage, validOffers.length);
+        const itemsToDisplay = validOffers.slice(startIndex, endIndex);
 
         const fragment = document.createDocumentFragment();
-        itemsToDisplay.forEach((offer, index) => {
-            const identity = identities[index];
-            const row = createTableRow(offer, identity);
-            if (row) {
-                fragment.appendChild(row);
-            }
-        });
 
-        offersBody.textContent = '';
-        offersBody.appendChild(fragment);
+        const BATCH_SIZE = 10;
+        for (let i = 0; i < itemsToDisplay.length; i += BATCH_SIZE) {
+            const batch = itemsToDisplay.slice(i, i + BATCH_SIZE);
 
-        const tooltipTriggers = offersBody.querySelectorAll('[data-tooltip-target]');
-        tooltipTriggers.forEach(trigger => {
-            const targetId = trigger.getAttribute('data-tooltip-target');
-            const tooltipContent = document.getElementById(targetId);
-            
-            if (tooltipContent) {
-                window.TooltipManager.create(trigger, tooltipContent.innerHTML, {
-                    placement: trigger.getAttribute('data-tooltip-placement') || 'top'
-                });
+            const batchPromises = batch.map(offer =>
+                offer.addr_from ? IdentityManager.getIdentityData(offer.addr_from) : Promise.resolve(null)
+            );
+
+            const batchIdentities = await Promise.all(batchPromises);
+
+            batch.forEach((offer, index) => {
+                const row = createTableRow(offer, batchIdentities[index]);
+                if (row) fragment.appendChild(row);
+            });
+
+            if (i + BATCH_SIZE < itemsToDisplay.length) {
+                await new Promise(resolve => setTimeout(resolve, 16));
             }
-        });
+        }
+
+        if (offersBody) {
+            const existingRows = offersBody.querySelectorAll('tr');
+            existingRows.forEach(row => cleanupRow(row));
+            offersBody.textContent = '';
+            offersBody.appendChild(fragment);
+        }
+
+        initializeTooltips();
 
         requestAnimationFrame(() => {
             updateRowTimes();
-            updatePaginationControls(totalPages);
+            updatePaginationControls(Math.ceil(validOffers.length / itemsPerPage));
             if (tableRateModule?.initializeTable) {
                 tableRateModule.initializeTable();
             }
@@ -1550,16 +1547,6 @@ async function updateOffersTable() {
     } catch (error) {
         console.error('[Debug] Error in updateOffersTable:', error);
         handleTableError();
-
-        try {
-            const cachedOffers = CacheManager.get('offers_cached');
-            if (cachedOffers?.value) {
-                jsonData = cachedOffers.value;
-                updateOffersTable();
-            }
-        } catch (recoveryError) {
-            console.error('Recovery attempt failed:', recoveryError);
-        }
     }
 }
 
@@ -1837,12 +1824,11 @@ function createOrderbookColumn(offer, coinFrom) {
 }
 
 function createRateColumn(offer, coinFrom, coinTo) {
-    const rate = parseFloat(offer.rate);
-    const inverseRate = 1 / rate;
-    const fromSymbol = getCoinSymbol(coinFrom);
-    const toSymbol = getCoinSymbol(coinTo);
+    const rate = parseFloat(offer.rate) || 0;
+    const inverseRate = rate ? (1 / rate) : 0;
 
     const getPriceKey = (coin) => {
+        if (!coin) return null;
         const lowerCoin = coin.toLowerCase();
         if (lowerCoin === 'firo' || lowerCoin === 'zcoin') {
             return 'zcoin';
@@ -1857,13 +1843,15 @@ function createRateColumn(offer, coinFrom, coinTo) {
     };
 
     const toSymbolKey = getPriceKey(coinTo);
-    let toPriceUSD = latestPrices[toSymbolKey]?.usd;
+    let toPriceUSD = latestPrices && toSymbolKey ? latestPrices[toSymbolKey]?.usd : null;
 
     if (!toPriceUSD || isNaN(toPriceUSD)) {
         toPriceUSD = tableRateModule.getFallbackValue(toSymbolKey);
     }
 
     const rateInUSD = toPriceUSD && !isNaN(toPriceUSD) && !isNaN(rate) ? rate * toPriceUSD : null;
+    const fromSymbol = getCoinSymbol(coinFrom);
+    const toSymbol = getCoinSymbol(coinTo);
 
     return `
         <td class="py-3 semibold monospace text-xs text-right items-center rate-table-info">
@@ -1884,6 +1872,7 @@ function createRateColumn(offer, coinFrom, coinTo) {
     `;
 }
 
+
 function createPercentageColumn(offer) {
     return `
         <td class="py-3 px-2 bold text-sm text-center monospace items-center rate-table-info">
@@ -2710,95 +2699,83 @@ const timerManager = {
     }
 };
 
-// INITIALIZATION AND EVENT BINDING
-document.addEventListener('DOMContentLoaded', () => {
-   const saved = localStorage.getItem('offersTableSettings');
-   if (saved) {
-       const settings = JSON.parse(saved);
+async function initializeTableAndData() {
+    loadSavedSettings();
+    updateClearFiltersButton();
+    initializeTableEvents();
+    initializeTooltips();
+    updateCoinFilterImages();
 
-       ['coin_to', 'coin_from', 'status', 'sent_from'].forEach(id => {
-           const element = document.getElementById(id);
-           if (element && settings[id]) element.value = settings[id];
-       });
+    try {
+        await fetchOffers();
+        applyFilters();
+    } catch (error) {
+        console.error('Error loading initial data:', error);
+        ui.displayErrorMessage('Error loading data. Retrying in background...');
+    }
+}
 
+function loadSavedSettings() {
+    const saved = localStorage.getItem('offersTableSettings');
+    if (saved) {
+        const settings = JSON.parse(saved);
+        
+        ['coin_to', 'coin_from', 'status', 'sent_from'].forEach(id => {
+            const element = document.getElementById(id);
+            if (element && settings[id]) element.value = settings[id];
+        });
 
-       if (settings.sortColumn !== undefined) {
-           currentSortColumn = settings.sortColumn;
-           currentSortDirection = settings.sortDirection;
+        if (settings.sortColumn !== undefined) {
+            currentSortColumn = settings.sortColumn;
+            currentSortDirection = settings.sortDirection;
+            updateSortIndicators();
+        }
+    }
+}
 
+function updateSortIndicators() {
+    document.querySelectorAll('.sort-icon').forEach(icon => {
+        icon.classList.remove('text-blue-500');
+        icon.textContent = '↓';
+    });
 
-           document.querySelectorAll('.sort-icon').forEach(icon => {
-               icon.classList.remove('text-blue-500');
-               icon.textContent = '↓';
-           });
+    const sortIcon = document.getElementById(`sort-icon-${currentSortColumn}`);
+    if (sortIcon) {
+        sortIcon.textContent = currentSortDirection === 'asc' ? '↑' : '↓';
+        sortIcon.classList.add('text-blue-500');
+    }
+}
 
-           const sortIcon = document.getElementById(`sort-icon-${currentSortColumn}`);
-           if (sortIcon) {
-               sortIcon.textContent = currentSortDirection === 'asc' ? '↑' : '↓';
-               sortIcon.classList.add('text-blue-500');
-           }
-       }
-   }
+document.addEventListener('DOMContentLoaded', async () => {
+    const tableLoadPromise = initializeTableAndData();
 
-   updateClearFiltersButton();
-   initializeTableEvents();
-   initializeTooltips();
-   updateCoinFilterImages();
+    WebSocketManager.initialize();
 
-   setTimeout(() => {
-       WebSocketManager.initialize();
-   }, 1000);
+    await tableLoadPromise;
 
-   if (initializeTableRateModule()) {
-       continueInitialization();
-   } else {
-       let retryCount = 0;
-       const maxRetries = 5;
-       const retryInterval = setInterval(() => {
-           retryCount++;
-           if (initializeTableRateModule()) {
-               clearInterval(retryInterval);
-               continueInitialization();
-           } else if (retryCount >= maxRetries) {
-               clearInterval(retryInterval);
-               continueInitialization();
-           }
-       }, 1000);
-   }
+    timerManager.addInterval(() => {
+        if (WebSocketManager.isConnected()) {
+            console.log('🟢 WebSocket connection established');
+        }
+    }, 30000);
 
-   timerManager.addInterval(() => {
-       if (WebSocketManager.isConnected()) {
-           console.log('🟢 WebSocket connection one established');
-       }
-   }, 30000);
+    timerManager.addInterval(() => {
+        CacheManager.cleanup();
+    }, 300000);
 
-   timerManager.addInterval(() => {
-       CacheManager.cleanup();
-   }, 300000);
+    timerManager.addInterval(updateRowTimes, 900000);
 
-   timerManager.addInterval(updateRowTimes, 900000);
+    EventManager.add(document, 'visibilitychange', () => {
+        if (!document.hidden) {
+            if (!WebSocketManager.isConnected()) {
+                WebSocketManager.connect();
+            }
+        }
+    });
 
-   EventManager.add(document, 'visibilitychange', () => {
-       if (!document.hidden) {
-           if (!WebSocketManager.isConnected()) {
-               WebSocketManager.connect();
-           }
-       }
-   });
-
-   EventManager.add(window, 'beforeunload', () => {
-       cleanup();
-   });
-
-   updateCoinFilterImages();
-   fetchOffers().then(() => {
-       applyFilters();
-       if (!isSentOffers) {
-           return;
-       }
-   }).catch(error => {
-       console.error('Error fetching initial offers:', error);
-   });
+    EventManager.add(window, 'beforeunload', () => {
+        cleanup();
+    });
 });
 
 async function cleanup() {