Migrating legacy site animations to GSAP without losing SEO means replacing jQuery slide carousels, inline style animations, and old CSS keyframe hacks with a single, performance-friendly animation layer while keeping URLs, DOM semantics, indexable content, and Core Web Vitals stable. The safe sequence is: inventory what animates → implement feature-parity with GSAP → verify performance (LCP, INP, CLS) → remove legacy dependencies, shipping behind flags with a rollback path at every step. SEO risk does not come from GSAP itself — it comes from migration mistakes: restructuring markup so text nodes move or vanish, hiding content with display:none or zero-height containers until JS runs, introducing layout-shifting animations that push CLS past 0.1, or breaking internal links and routes during a redesign that happens to ride along with the animation work. Do the migration as an animation-layer swap, not a page rebuild, and rankings have no reason to move.
This guide walks through auditing legacy animations, the specific SEO risks each type creates, a staged migration sequence, when you should not migrate, how to measure Core Web Vitals before and after, and a rollback plan that works under client pressure. Production patterns for the target state live in GSAP motion systems in production; for the broader craft context, see motion web development practices.
Step 0: Audit what you actually have
You cannot migrate what you have not inventoried. Build a spreadsheet (or ticket list) with one row per animated component:
| Component | Legacy tech | Trigger | Indexable content inside? | CLS risk | Keep / replace / remove |
|---|---|---|---|---|---|
| Homepage hero slider | jQuery plugin / slick | Autoplay + arrows | Yes (H1, CTAs in slides) | High (height changes) | Replace with single-hero or accessible carousel |
| Header mega menu | jQuery slideDown | Hover/click | Yes (nav links) | Medium | GSAP or CSS |
| Section scroll fades | CSS keyframes + old IO polyfill | Scroll | Yes | Medium if animating margin/top | GSAP ScrollTrigger or modern IO |
| Counter stats | setInterval + inline styles | In view | Yes (numbers) | High (width growth) | GSAP text/counter tween |
| Decorative marquee | JS position:absolute loop | Always | Optional | Medium | CSS animation or remove |
Flag every row that contains headings, links, prices, or product text. Those rows get extra SEO scrutiny in every subsequent step.
SEO risks in legacy-to-GSAP migrations
DOM changes and content visibility
Search engines need the same content your users see. Common violations during migration:
- Moving slide content out of the initial HTML into JS-generated markup.
- Setting
opacity: 0ordisplay: noneon large content blocks until scroll — fine as progressive enhancement, dangerous as the only state if JS fails or is slow. - Replacing semantic headings with styled
divs because the animation library prefers them. - Duplicating content for “mobile vs desktop” carousels with inconsistent canonical signals.
Rule: content is visible and semantic in the raw HTML; JS only enhances from that baseline. Apply the pre-animation hidden state only after the browser confirms motion will run (e.g., after setting a js-motion flag and checking reduced-motion).
CLS from animated layout
Legacy sliders that animate height, top, or swap images without dimensions are CLS factories. GSAP should animate transform and opacity for in-flow content, and images need explicit width/height or aspect-ratio. If the old slider resizes to the tallest slide, reserve that space with CSS before GSAP ever runs. Keep CLS < 0.1 per web.dev guidance on CLS.
URLs, routes, and link equity
Migrations go wrong when animation work is bundled with a redesign: new URL structures, removed topic pages, anchor links replaced by JS scroll that fails without handlers, or client-side routing that hides previously crawlable paths. Keep redirects 1:1, preserve anchor targets, and never ship a route change in the same deploy as an animation swap unless both are independently tested.
Interaction and long tasks (INP)
Porting a heavy jQuery slider to a “GSAP timeline that also re-renders DOM” can make INP worse, not better. Prefer transform-based movement of existing nodes, pause timelines off-screen, and avoid layout reads inside onUpdate. INP good = under 200ms (MDN on interaction responsiveness).
The safe migration sequence
1. Inventory
Complete the audit table above. Classify each component: keep (modernize), replace, or remove. Removal is often the highest-ROI move — unused sliders and parallax layers cost bytes and risk without business value.
2. Baseline measurement
Before writing GSAP code, capture lab metrics (Lighthouse/WebPageTest) and field metrics (CrUX, Search Console Core Web Vitals) for templates: home, landing, product/service, blog. Record LCP, INP, CLS, plus HTTP weight and blocking JS. This baseline is your proof of “no regression” later.
3. Parity implementation
Rebuild each component with GSAP to match observable behavior first — same triggers, same content order, same accessibility affordances (focus states, pause controls on carousels, keyboard nav). Do not “improve” UX and swap tech in the same step; parity isolates bugs. Ship behind a feature flag or in a staging environment that mirrors production markup.
- Keep heading hierarchy and link
hrefs untouched. - Animate only
transform/opacityunless layout animation is unavoidable — then reserve space. - Load GSAP with defer/module strategy; avoid render-blocking.
- Honor
prefers-reduced-motionfrom day one, not as a later patch.
4. Performance & QA pass
Run the full checklist: visual regression on key breakpoints, cross-browser and device QA (a documented cross-browser QA process for WordPress maps cleanly onto this phase), crawl templates to confirm indexable text still present in raw HTML, and compare CWV against baseline. Test with JS disabled: content must remain readable and navigable.
5. Remove legacy dependencies
Only after parity and metrics hold: drop jQuery plugins, old carousel CSS, unused keyframes, and dead markup. Removing jQuery entirely (when nothing else needs it) often saves more than the GSAP code costs. Update bundle analysis so the win is visible.
6. Production monitoring
Watch field CWV for 2–4 weeks post-deploy, plus crawl stats and indexing for the affected templates. Animation regressions show up as CLS/INP spikes before they show up as ranking volatility — catch them early.
When NOT to migrate to GSAP
- The animation is already CSS-cheap and working. Hover states and simple fades often need no JS at all. Choose technique by need, not habit — see GSAP vs CSS: when to use which.
- The component is dead weight. An ignored hero slider is a removal candidate, not a rewrite.
- You cannot baseline or roll back. No metrics, no flag, no staging parity → do not migrate in production yet.
- The page has other in-flight SEO changes. Separate deploys: content/IA changes and animation swaps should not share a release train.
- A static poster image would convert better than any motion. Sometimes the right move is deleting motion entirely.
Measuring CWV before and after
Use a three-layer view:
- Lab (every PR): Lighthouse on staging for LCP/CLS sanity and total blocking time.
- Field (pre/post): 28-day CrUX or Search Console CWV for the affected URL groups; compare p75 LCP, INP, CLS to your baseline.
- Content & indexation: spot-check “site:URL” or URL Inspection for hero headlines and slide copy; confirm they remain in the rendered and raw HTML.
Acceptance gate: no template regresses p75 CWV beyond thresholds; CLS stays < 0.1; INP stays < 200ms; LCP stays < 2.5s on representative mobile lab runs. If a replacement slider worsens INP, fix before enabling the flag for all traffic.
Rollback plan (write it before you ship)
- Flag-based rollback: one config value restores legacy component code paths (keep them one release).
- Content rollback: CMS content untouched by the animation swap, so editorial can revert independently.
- Dependency pinning: lockfile changes isolated in their own commit for clean
git revert. - Decision triggers: predefined — e.g., p75 CLS > 0.1 for 7 days, or critical visual bug on a money page → flag off same day.
- Who flips the switch: a named owner, not a committee, because animation regressions compound daily.
Putting it together
Treat GSAP migration as infrastructure work: inventory, baseline, parity, verify, remove, monitor — with SEO invariants (URLs, semantic DOM, visible content, stable layout) locked at every stage. Most “migration tanked our traffic” stories are actually “migration rebuilt the page and changed everything else too.” Keep the blast radius to the animation layer, measure honestly, and the result is a faster, more maintainable site with rankings intact — the same standard applied when agencies ship full builds through a disciplined white-label web development process.
Frequently asked questions
Does replacing jQuery animations with GSAP affect SEO?
Not by itself. SEO impact comes from accompanying changes: altered DOM/semantics, hidden indexable content, layout shifts, or URL changes. If you preserve markup, content visibility, and routes while swapping only the animation implementation, rankings should remain stable.
Should animated carousel content stay in the initial HTML?
Yes, when the content is valuable for users or crawlers (headlines, offers, product info). Keep it semantic in the raw HTML; enhance with GSAP progressively. Avoid JS-only rendering of slide copy and avoid duplicate mobile/desktop copies that confuse canonicalization.
How do I prevent CLS when replacing a height-animating slider?
Reserve space with explicit image dimensions/aspect-ratio and min-height on the slider container; animate transform/opacity instead of height/top; avoid injecting content above existing elements after load. Target CLS < 0.1.
When should we keep CSS animations instead of moving to GSAP?
For simple state changes — hovers, fades, short one-shots — CSS is often enough and cheaper on the main thread. Reserve GSAP for sequences, scroll-linked work, orchestration, and anything you need fine-grained control or cross-browser consistency on. See GSAP vs CSS: when to use which.
What is the quickest safe path for a legacy site with many old sliders?
Audit → baseline CWV → remove unused sliders first → rebuild the two or three that matter with parity + flags → QA and field-check → drop jQuery plugins. Removing dead animation code often improves metrics immediately and shrinks the migration to a manageable set.
Read next: white-label web development for agencies · pixel-perfect Figma to WordPress development · GSAP motion and page transitions
