Skip to content

perf: keep Slise banner mounted across navigation + gapless per-page …#687

Merged
liangping merged 1 commit into
ping-pub:masterfrom
devmildfire:fix/slise-ad-navigation-refresh
Jul 9, 2026
Merged

perf: keep Slise banner mounted across navigation + gapless per-page …#687
liangping merged 1 commit into
ping-pub:masterfrom
devmildfire:fix/slise-ad-navigation-refresh

Conversation

@devmildfire

Copy link
Copy Markdown
Contributor

Keep Slise banner mounted across navigation + gapless per-page refresh

Background

PR #686 fixed the cold-load delay (preconnect + preload of embed.js, and
syncing on the script load event instead of a one-shot typeof check). After
that merged you noted:

"it's better now, but there still a delayed refresh during page switching."

This PR fixes that remaining navigation delay.

What was wrong (measured on production ping.pub)

<AdBanner> lived inside <RouterView><Transition mode="out-in">, so it was
destroyed and recreated on every client-side navigation. On each remount
Slise blanks the <ins> and refetches a creative, so the banner went blank and
only repainted once the (often heavy) destination page finished mounting.

Timing click → banner visible across 37 real navigations:

scenario median max
chain routes (cosmos, 7 routes) ~500ms ~2665ms
wallet routes (warm) ~150ms ~193ms

The delay tracked page weight — the blank banner competed with the route
component for the main thread, so /cosmos/uptime was consistently ~2.5s blank.
It was not a queue leak (window.adsbyslise stays length 1) and not a
CSS transition.

The fix

  1. Persist the banner. <AdBanner> is now a sibling above <RouterView>
    in DefaultLayout.vue, so it mounts once and stays mounted across
    navigations — never destroyed, so it never blanks.

  2. Refresh gaplessly per navigation. AdBanner watches route.fullPath.
    On each navigation it removes data-ad-loaded from its <ins> without
    clearing the existing creative
    , then calls window.adsbyslisesync(). Slise
    refetches and swaps the new creative in only when ready, so the previous
    ad stays on screen the whole time — no blank gap.

    (Re-calling adsbyslisesync() on an <ins> that still has data-ad-loaded
    does nothing — Slise skips loaded slots — which is why the flag must be
    dropped first. Verified against the live embed.)

Result

  • No blank gap on navigation — old creative stays visible while the next
    loads in the background.
  • A fresh creative (impression) per page view is preserved.
  • Behaviour is now independent of destination-page weight.

Trade-off / rollback

Keeps a per-navigation ad refresh (every page view = fresh impression). If
that is not wanted, delete the route.fullPath watcher in AdBanner.vue and
the banner stays a single persistent ad — still gap-free, just no rotation.

…refresh

PR ping-pub#686 fixed cold-load, but the banner still went blank during client-side
page switches (measured on ping.pub: ~500ms median, up to ~2.5s on heavy
pages). Cause: <AdBanner> lived inside <RouterView><Transition>, so it was
destroyed/recreated on every navigation — Slise blanked the <ins> and only
repainted once the destination page had mounted, so the delay tracked page
weight.

Fix:
- Move <AdBanner> out of <RouterView> in DefaultLayout so it mounts once and
  persists across navigation (never unmounts -> never blanks).
- In AdBanner, watch route.fullPath and refresh gaplessly: drop data-ad-loaded
  (keeping the old creative on screen) then call adsbyslisesync(); Slise swaps
  the new creative in only when ready, so there is no blank gap.

Preserves a fresh creative/impression per page view.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@liangping liangping merged commit 20e65d6 into ping-pub:master Jul 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants