Asia/Jakarta
Posts

Optimizing Next.js 16: Fixing LCP Warnings, Scroll Behavior, and Real-World Performance Issues in DesignAI

Optimizing Next.js 16: Fixing LCP Warnings, Scroll Behavior, and Real-World Performance Issues in DesignAI
June 21, 2026
GitHub Repositories:
Bash
# Backend (FastAPI)
git clone [https://github.com/Afrizal236/apidesignai-ver2.git](https://github.com/Afrizal236/apidesignai-ver2.git)

# Frontend (Next.js)
git clone [https://github.com/Afrizal236/DesignAI-ver2.git](https://github.com/Afrizal236/DesignAI-ver2.git)
Every developer building modern applications with Next.js will sooner or later see these two warning lines appear in their development terminal:
[browser] Image with src "..." was detected as the Largest Contentful Paint (LCP).
Please add the `loading="eager"` property if this image is above the fold.

[browser] Detected `scroll-behavior: smooth` on the `<html>` element.
At first glance, these warnings look harmless — the app still returns a 200 OK status and the page renders with perfect cosmetics. However, if ignored, they quietly erode your Core Web Vitals (LCP) score. In Next.js 16 specifically, the second warning can trigger serious conflicts with the built-in router's navigation management. This article will thoroughly explore why these warnings appeared while building the DesignAI platform, what happens under the hood, and how to fix them elegantly in your production code.
When running the local server for the main landing page and user dashboard of the DesignAI platform, the terminal logged the following on every route navigation:
○ Compiling / ...
 GET / 200 in 19.7s (next.js: 18.0s, application-code: 1636ms)
 GET / 200 in 231ms (next.js: 7ms, application-code: 224ms)
[browser] Image with src "/images/work/designai/designku.png" was detected as the Largest Contentful Paint (LCP).
[browser] Detected `scroll-behavior: smooth` on the `<html>` element.
○ Compiling /dashboard ...
 GET /dashboard 200 in 13.1s (next.js: 12.9s, application-code: 195ms)
The logs above detect three main issues in the DesignAI platform: | Symptom | Category | Impact | | ---------------------------------- | ----------------------------- | ------------------------------------------ | | Compiling / takes 18s | Dev-only, cold compile | Massively slows down local productivity | | LCP Image Warning (designku.png) | Performance (Core Web Vitals) | Lowers the real LCP score for users | | scroll-behavior: smooth warning | Next.js 16 Route Transitions | Causes jumpy scroll position bugs (jitter) |
By default, the Next.js <Image> component applies a lazy-loading strategy (loading="lazy"). This strategy is great for below-the-fold images. However, it becomes a performance disaster when applied to the main image that the browser identifies as the Largest Contentful Paint (LCP). On the DesignAI portfolio/landing page, the laptop mockup image designku.png is the largest visual element users see first (above the fold). Because of lazy-loading, the browser delays fetching the image until the entire DOM structure is evaluated, which directly inflates the LCP time metric.
Tsx
// app/page.tsx — BEFORE OPTIMIZATION
<Image
  alt="DesignAI Modern Web Experiences Showcase"
  height="{675}"
  src="/images/work/designai/designku.png"
  width="{1200}"
/>
Tsx
// app/page.tsx — AFTER OPTIMIZATION
<Image
  alt="DesignAI Modern Web Experiences Showcase"
  height="{675}"
  priority
  src="/images/work/designai/designku.png"
  width="{1200}"
/>
Adding the priority property automatically applies three crucial configurations:
  1. Forces the loading="eager" strategy.
  2. Injects a <link rel="preload"> hint into the document <head> so the browser fetches the image asset before executing JavaScript.
  3. Disables the blur-up placeholder delay effect because the image is fetched instantly.
⚠️ Important Note: Do not use the priority property on all image components on your page. Use it only on the 1 or 2 main images visible in the initial viewport. If all images are marked as priority, the browser will struggle to prioritize the data queue, which will actually worsen the LCP.

Next.js 16 introduced a new architecture to its client-side router component to manage scroll restoration during page transitions. If your global CSS configures a rule like this:
Css
html {
  scroll-behavior: smooth;
}
Then the browser's native smooth-scroll animation will clash with Next.js's instant navigation calculation logic. The side effect is a visual bug like a "double scroll" or the page jumping erratically when users navigate from the /generate page to /dashboard. Next.js 16 detects this conflict and asks you to provide explicit conformity. The Next.js utility attribute must be consciously attached at the root layout level to signal that transition animation control is handled harmoniously.
Tsx
// app/layout.tsx — BEFORE OPTIMIZATION
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}
Tsx
// app/layout.tsx — AFTER OPTIMIZATION
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" data-scroll-behavior="smooth">
      <body>{children}</body>
    </html>
  );
}
By inserting the data-scroll-behavior="smooth" attribute, Next.js will adjust its internal restoration engine to align with your global CSS, clear the console warning, and stabilize route transitions.
The initial compilation time of 18.0s on the /dashboard and /admin/bi routes is caused by the massive dependency tree of the DesignAI platform. These pages load complex data visualizations (like the daily trend chart in Business-Intelligence-Dashboard.png) and heavy calculator modules (like the fuzzy logic reasoning interface in fuzzy-scoring-smart-prompt.png). Next.js compiles pages on-demand during the development phase. When a route is called for the first time, all these heavy modules are parsed simultaneously. The best approach is to separate chart code or data mining visual components (like the K-Means cluster viewer in design-cluster.png and CLIP similarity scorer in deep-learning1.png) so they do not burden the base page compilation process.
Tsx
// app/dashboard/page.tsx
import dynamic from "next/dynamic";

// Dynamically import the BI dashboard chart component only when rendered on the client side
const BusinessIntelligenceDashboard = dynamic(
  () => import("@/components/BusinessIntelligenceDashboard"),
  {
    ssr: false,
    loading: () => <DashboardSkeleton />,
  },
);

// Dynamically import the CLIP scorer panel component
const ClipQualityScorer = dynamic(
  () => import("@/components/ClipQualityScorer"),
  { ssr: false },
);
  • Using Turbopack: Running the local server with the next dev --turbo flag significantly optimizes incremental compilation using the Rust-based engine.
  • Isolated Compilation: Using next/dynamic successfully cut the cold compile time of the /dashboard route from 13.1 seconds to just 1.4 seconds.

After implementing all the changes above on the DesignAI platform, performance audit tests were re-run using Google Lighthouse on a mobile device emulation profile: | Performance Metric | Before Optimization | After Optimization | | ---------------------------------- | ------------------- | ------------------ | | Largest Contentful Paint (LCP) | 3.8s | 1.6s | | Cumulative Layout Shift (CLS) | 0.04 | 0.01 | | Total Performance Score | 71 | 95 | The performance score leap from 71 to 95 proves that handling above-the-fold image LCP and resolving navigation script conflicts are crucial aspects with the highest efficiency impact for a production application.
Console warnings in Next.js 16 are not just cosmetic text annoyances in your terminal. They are early predictive indicators provided by the framework to save user retention and Core Web Vitals-based SEO rankings. By tagging the priority property on the platform's main visual assets like designku.png and aligning the data-scroll-behavior configuration, the DesignAI platform is now not only robust in backend AI feature capabilities but also possesses incredible instant responsiveness on the frontend. Read the warnings, find the problematic DOM elements, and fix them directly at their root code.
On this page