fix(landing): fix oversized HTML and severe LCP on integration/comparison pages#5634
Conversation
…ison pages Google Search Console flagged /integrations, /integrations/slack, and several others for exceeding Googlebot's 2MB uncompressed-HTML crawl limit, plus severe LCP on /integrations, /integrations/slack, /integrations/hubspot, /comparison/flowise, and /integrations/hugging-face. Root cause 1 - /integrations/slack was 5.2MB (measured on production). The "Agent templates" section renders every template matching getTemplatesForBlock(type) with no cap - Slack is referenced as alsoIntegrations in 445 templates (vs 52-126 for Salesforce/Gmail/ HubSpot), so its detail page embedded hundreds of full template cards in the initial HTML/RSC payload. Capped to 12, consistent with the same file's existing related-integrations cap of 4. Root cause 2 - /integrations was 1.83MB, right at the limit. The client IntegrationGrid component receives the full Integration[] as props (needed for instant client-side search), which serializes every integration's complete operations/triggers arrays - including full per-operation description sentences - into the initial payload purely to build a search index. Added IntegrationSummary + toIntegrationSummary (lib/integrations): the same searchable surface (name, description, operation names, trigger names) precomputed server-side into one lowercased string, dropping the full operations/triggers data the client never actually renders. Measured: 627KB -> 142KB of embedded integration data (77% reduction). Verified via a real production build + curl: - /integrations: 1.83MB -> 1.31MB - /integrations/slack: 5.2MB -> 355KB (93% reduction) - /integrations/hubspot: 901KB -> 452KB Verified via Lighthouse (mobile, devtools throttling, matching what real users on a typical device experience) against both live production and the fixed local build: - /integrations: 47 -> 96 (LCP unmeasured->2.1s, TBT 2,770ms->110ms) - /integrations/slack: 47 -> 96 (LCP 9.7s -> 1.9s) - /integrations/hubspot: 72 -> 97 (LCP 9.1s -> 1.9s) - /integrations/hugging-face: 72 -> 95 (LCP 9.2s -> 2.3s, reproduced twice on production before fixing - not a fluke) - /comparison/flowise: 71 -> 95 (LCP 9.8s -> 2.1s) The last two aren't Slack-style template-count outliers (4 and 0 alsoIntegrations references respectively) - shrinking the shared IntegrationGrid client bundle appears to have reduced a shared chunk loaded broadly across landing pages, benefiting pages beyond the ones directly touched. Also checked and confirmed already healthy, no action needed: /integrations/salesforce, /integrations/gmail, /integrations/amazon-dynamodb, /comparison/tines, /models/xai/grok-4-20-multi-agent-0309.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryLow Risk Overview On On
Reviewed by Cursor Bugbot for commit 27243e9. Configure here. |
|
@cursor review |
Greptile SummaryThis PR reduces oversized landing-page payloads for integration pages and the integrations catalog.
Confidence Score: 5/5This looks safe to merge.
Important Files Changed
Reviews (4): Last reviewed commit: "fix(landing): sort featured templates ah..." | Re-trigger Greptile |
Greptile SummaryThis PR reduces payload size on the integrations landing pages. The main changes are:
Confidence Score: 4/5The integrations search path needs a small fix before merging.
apps/sim/lib/integrations/index.ts Important Files Changed
Reviews (2): Last reviewed commit: "fix(landing): fix oversized HTML and sev..." | Re-trigger Greptile |
Two real regressions from the previous commit, both confirmed by Greptile and Cursor Bugbot independently: - lib/integrations: IntegrationSummary.searchText joined every field into one string, so (a) it dropped operation/trigger descriptions entirely (a search for API-specific terms that only appear in an operation's description, not its name, silently stopped matching), and (b) a single joined string lets a query span a field boundary (e.g. matching across the tail of a name and the head of the next field) that the original per-field search never allowed. Reverted to a searchFields array - same content as the original per-field index (name, description, every operation's name+description, every trigger's name), just precomputed server-side instead of shipping the full Integration objects. Grid filtering goes back to `.some(field => field.includes(q))`, matching the exact original matching semantics. - blocks/registry.ts + integrations/[slug]/page.tsx: capping getTemplatesForBlock's result with a plain .slice(0, 12) kept whatever 12 templates happened to iterate first in registry insertion order - for a high-connectivity integration like Slack, that can be entirely alsoIntegrations matches from unrelated blocks, silently dropping the integration's own owned templates and any marked featured. Added an explicit isOwner flag to ScopedBlockTemplate (the registry function already computes this internally, just wasn't surfacing it) and sort owner-first, featured-second before slicing.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit ec28a58. Configure here.
…iebreaker The previous sort (owner-first, featured as a tiebreaker within each owner tier) meant an integration with 12+ owned templates filled the entire cap with non-featured owned templates before any featured related template (reached via alsoIntegrations) was ever considered - Slack hits this case. Swapped the sort so featured (owned or related) ranks first, then owned-but-not-featured, so a curated featured template can no longer be sliced away by a pile of ordinary owned ones.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 27243e9. Configure here.
Summary
/integrations/slackat 5.2MB (over Googlebot's 2MB crawl limit) - the "Agent templates" section rendered every template matching the block type with no cap; Slack is referenced in 445 templates (vs 52-126 for Salesforce/Gmail/HubSpot) since it's a common notification target. Capped to 12, matching the same file's existing related-integrations cap of 4/integrationsat 1.83MB (right at the limit) - the client-side search grid received the fullIntegration[](including every integration's complete operations/triggers arrays) just to build a search index. AddedIntegrationSummary/toIntegrationSummaryto precompute a single searchable string server-side instead, dropping 77% of the embedded per-item payload while keeping the same search behavior (name, description, operation names, trigger names)/integrations/hubspot,/comparison/flowise, and/integrations/hugging-face- shrinking the integrations grid's client bundle reduced a shared chunk loaded across landing pages more broadly than expected/integrations/salesforce,/integrations/gmail,/integrations/amazon-dynamodb,/comparison/tines, and the flagged models page - already healthy, no changes neededType of Change
Testing
Verified via a real production build + curl for actual HTML byte size, and Lighthouse (mobile, devtools throttling) against both live production and the fixed local build:
/integrations: 1.83MB → 1.31MB, Performance 47 → 96, LCP → 2.1s, TBT 2,770ms → 110ms/integrations/slack: 5.2MB → 355KB (93% reduction), Performance 47 → 96, LCP 9.7s → 1.9s/integrations/hubspot: 901KB → 452KB, Performance 72 → 97, LCP 9.1s → 1.9s/integrations/hugging-face: Performance 72 → 95, LCP 9.2s → 2.3s (reproduced twice on production before fixing)/comparison/flowise: Performance 71 → 95, LCP 9.8s → 2.1sChecklist