AB testing with Adobe Target
The demo showcases multiple ways in which Adobe Target can be used in Next.js pages, using different data fetching and rendering strategies:
- /static-rewrites: Static Pages + Middleware Rewrites, events are sent using API Routes
- /ssg: SSG + Middleware Rewrites, events are sent using API Routes
- /csr/at: CSR Page with at.js
- /csr/at-blocking: CSR Page with at.js blocking rendering until experiment is ready
- /ssr/at: SSR Page with at.js
- /ssr: SSR Page where events are sent using API Routes
The differences between the pages are:
- Pages under Next.js Middleware take advantage of the Vercel Edge Network, rewrites should be very fast if the request hits the Target Edge Network
- The difference between
/static-rewrites
and/ssg
is only that the latter is using dynamic routes over predefined pages - Pages that have
at.js
will have a larger JS footprint as it takes 33.7kb to load it. - If the page is blocking until the experiment is ready, like in
/csr/at-blocking
or/ssr
, TTFB and FCP are worse than in non-blocking pages - Pages that call an API route instead of using
at.js
are less likely to get adblocked because the API routes live in the same domain. The API route takes more time to send an event as it's an intermediary, but analytics reporting shouldn't be affecting performance
There are also measurable differences in performance between CSR, SSR, and Static + Middleware rewrites, the links below are using Lighthouse Metrics:
- Static + Middleware rewrites (/static-rewrites)
- CSR + at.js (/csr/at)
- CSR + at.js blocking (/csr/at-blocking)
- SSR + at.js (/ssr/at)
Based on the lighthouse results above, we can conclude the following:
- Static + Middleware rewrites scores better CWV (Core Web Vitals - LCP, TTI, TBT) results than other pages, this is due to it being completely static and not using
at.js
, while still being able to handle per request experimentation - The blocking behavior of
/csr/at-blocking
gives it worse performance over/csr/at
/ssr/at
has better performance than/csr/at-blocking
even though it has to wait for the page to be generated by a serverless function. This has to do with the performance hit introduced by waiting onat.js
and blocking the paint of the page until the experiment is ready- The difference between
/ssr/at
and/csr/at
is less noticeable, in this case case it's more of a tradeoff, CSR paints faster but it has a layout shift while the experiment loads, SSR loads with the experiment ready but it's a serverless function and can't be cached globally if it depends on request data