Eliminate frontend POI waterfall for faster initial load
Listing stream fires immediately on auth without waiting for POI fetch. POI distances are not needed for initial rendering and are only computed when user selects POI metric or sets travel filters. This saves ~200-500ms on initial load and keeps the stream on the cached Redis path.
This commit is contained in:
parent
3885fd52fe
commit
8ef6868881
2 changed files with 36 additions and 7 deletions
|
|
@ -17,7 +17,7 @@ import { Sheet, SheetContent, SheetTrigger } from './components/ui/sheet';
|
|||
import { Button } from './components/ui/button';
|
||||
import { Filter, Heart } from 'lucide-react';
|
||||
import type { GeoJSONFeatureCollection, PropertyProperties, PropertyFeature, POI, POITravelFilter } from '@/types';
|
||||
import { refreshListings, streamListingGeoJSON, fetchUserPOIs, type StreamingProgress } from '@/services';
|
||||
import { refreshListings, streamListingGeoJSON, fetchUserPOIs, fetchBulkPOIDistances, type StreamingProgress } from '@/services';
|
||||
import { setOnUnauthorized } from '@/services/apiClient';
|
||||
import { clearPasskeyUser } from './auth/passkeyService';
|
||||
import { poiMetricPropertyName, injectPoiMetricProperty } from '@/utils/poiUtils';
|
||||
|
|
@ -167,7 +167,7 @@ function App() {
|
|||
try {
|
||||
for await (const batch of streamListingGeoJSON(user, parameters, (progress) => {
|
||||
setStreamingProgress(progress);
|
||||
}, { includePoiDistances: userPOIs.length > 0, signal: controller.signal })) {
|
||||
}, { signal: controller.signal })) {
|
||||
// Deduplicate features by URL
|
||||
const uniqueBatch = batch.filter((feature) => {
|
||||
const url = feature.properties?.url;
|
||||
|
|
@ -200,7 +200,39 @@ function App() {
|
|||
setStreamingProgress(null);
|
||||
}
|
||||
}
|
||||
}, [user, userPOIs]);
|
||||
}, [user]);
|
||||
|
||||
// Merge POI distances into listing data after both are available
|
||||
useEffect(() => {
|
||||
if (!user || !listingData || userPOIs.length === 0 || !queryParameters) return;
|
||||
|
||||
let cancelled = false;
|
||||
fetchBulkPOIDistances(user, (queryParameters.listing_type as 'RENT' | 'BUY') ?? 'RENT')
|
||||
.then((distanceLookup) => {
|
||||
if (cancelled) return;
|
||||
const updatedFeatures = accumulatedFeaturesRef.current.map(feature => {
|
||||
const id = feature.properties?.id;
|
||||
if (id && distanceLookup[id]) {
|
||||
return {
|
||||
...feature,
|
||||
properties: {
|
||||
...feature.properties,
|
||||
poi_distances: distanceLookup[id],
|
||||
},
|
||||
};
|
||||
}
|
||||
return feature;
|
||||
});
|
||||
accumulatedFeaturesRef.current = updatedFeatures;
|
||||
setListingData({
|
||||
type: 'FeatureCollection',
|
||||
features: [...updatedFeatures],
|
||||
});
|
||||
})
|
||||
.catch(() => {}); // POI distances are best-effort
|
||||
|
||||
return () => { cancelled = true; };
|
||||
}, [user, listingData?.features.length, userPOIs.length, queryParameters]);
|
||||
|
||||
// Compute processed listing data: inject synthetic POI metric property & apply max travel filter
|
||||
const processedListingData = useMemo(() => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue