Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lcp-issues #502

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/components/navigation/sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ export const Sidebar: FC<Props> = ({ children, data }) => {
Entertainment, Inc.
<br />© BLIZZARD ENTERTAINMENT, INC. All Rights Reserved.
</p>
<div id="ezoic-pub-ad-placeholder-118" />
{/*<div id="ezoic-pub-ad-placeholder-118" />*/}
</nav>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ function App() {
<Meta />
<Links />
<EnsureThemeApplied />
<script async src="//www.ezojs.com/ezoic/sa.min.js"></script>
{/*<script async src="//www.ezojs.com/ezoic/sa.min.js"></script>
<script
dangerouslySetInnerHTML={{
__html: `window.ezstandalone = window.ezstandalone || {};
Expand All @@ -272,7 +272,7 @@ function App() {
ezstandalone.display();
});`
}}
/>
/>*/}
</head>
<body className={`h-full bg-gray-100 dark:bg-slate-800`}>
<noscript>
Expand Down
2 changes: 2 additions & 0 deletions app/routes/queries.item-data.$itemId.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// trigger cr
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai help me fix

LCP issue: longer than 4s (mobile)

Improve page performance
Grade Suggestion
F34 Add Expires headers
Web pages are becoming increasingly complex with more scripts, style sheets, images, and Flash on them. A first-time visit to a page may require several HTTP requests to load all the components. By using Expires headers these components become cacheable, which avoids unnecessary HTTP requests on subsequent page views. Expires headers are most often associated with images, but they can and should be used on all page components including scripts, style sheets, and Flash.
F45 Compress components with gzip
Compression reduces response times by reducing the size of the HTTP response. Gzip is the most popular and effective compression method currently available and generally reduces the response size by about 70%. Approximately 90% of today's Internet traffic travels through browsers that claim to support gzip.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cohenaj194

To address the LCP issue on mobile devices, you can implement the following fixes:

  1. Add Expires headers (F34):

    Setting proper caching headers will allow browsers to cache static assets, reducing load times on subsequent visits.

    In your Remix app, you can set Cache-Control headers in the loader functions of your routes or in a shared headers function. Here's how you can do it:

    // In app/entry.server.tsx or a root route
    export const headers = () => {
      return {
        'Cache-Control': 'public, max-age=31536000, immutable', // Cache for 1 year
      };
    };

    For static assets like images, CSS, and JavaScript files served from the public directory, ensure that your hosting provider or CDN is configured to add appropriate Cache-Control headers. Since you're using Cloudflare, you can set up a Page Rule to add these headers:

    • Go to Cloudflare Dashboard > Page Rules.
    • Create a new rule for your static assets URL pattern.
    • Set Edge Cache TTL to a desired value.
  2. Compress components with gzip (F45):

    Compression can significantly reduce the size of your assets.

    If you're deploying to Cloudflare Workers, gzip or Brotli compression is automatically applied to your responses when the client supports it.

    For further assurance, you can double-check your Cloudflare settings:

    • Go to Cloudflare Dashboard > Speed > Optimization.
    • Ensure that Auto Minify is enabled for JavaScript, CSS, and HTML.
    • Ensure that Brotli is enabled under the Speed settings.

    If you're using a custom server (like Express) with Remix, you can enable gzip compression using middleware:

    // server.js
    const express = require('express');
    const compression = require('compression');
    const app = express();
    
    app.use(compression());
    // ... rest of your server setup

    For Remix Apps deployed on other platforms, refer to their documentation on enabling compression.

  3. Additional Tips to Improve LCP:

    • Optimize Images: Ensure images are properly sized and compressed. Use modern image formats like WebP when possible.
    • Code Splitting: Utilize code splitting to reduce the initial load time by lazy-loading non-critical JavaScript.
    • Critical CSS: Inline critical CSS to reduce render-blocking resources.
    • Remove Unused Scripts: Audit and remove any unnecessary scripts or dependencies.
    • Prefetching/Preloading: Use <link rel="preload"> or <link rel="prefetch"> for critical assets.

Implementing these changes should help reduce your LCP times on mobile devices. Let me know if you need further assistance!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai use your learnings and grep through this repo to give more precise suggestions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cohenaj194

After analyzing your codebase, I noticed that none of your loader functions are currently setting Cache-Control headers. This means that browsers may not be efficiently caching your server-rendered responses, contributing to the LCP issues on mobile devices.

To improve caching and reduce load times, you can add Cache-Control headers to your loader functions. Here's how you can modify them:

// For example, in app/routes/queries.item-data.$itemId.tsx

export const loader: LoaderFunction = async ({ params, request }) => {
  // ... your existing code ...

  return json(data, {
    headers: {
      'Cache-Control': 'public, max-age=31536000, immutable', // Adjust max-age as needed
    },
  });
};

Apply this change to all your loader functions where appropriate. This tells the browser to cache the response, reducing the need to fetch the data again on subsequent visits.

Additionally, it appears that there's no usage of compression middleware like compression() in your codebase. If you're using a custom server with Express or a similar framework, you can enable gzip compression:

// server.js or server.ts (if applicable)
const express = require('express');
const compression = require('compression');
const app = express();

app.use(compression());
// ... rest of your server setup

However, since I didn't find a server.js or server.ts file, it's possible that you're deploying your Remix app directly to Cloudflare Workers or another platform that handles compression for you. In this case, ensure that Brotli compression is enabled in your Cloudflare settings:

  • Go to Cloudflare Dashboard > Speed > Optimization.
  • Make sure Auto Minify is enabled for JavaScript, CSS, and HTML.
  • Ensure Brotli is turned on.

Additional Recommendations:

  • Optimize Images: Review your image assets to ensure they're properly sized and compressed. Use modern formats like WebP where possible.
  • Code Splitting: Implement code splitting to load only the necessary JavaScript for each page.
  • Critical CSS: Inline critical CSS to reduce render-blocking resources.
  • Remove Unused Scripts: Audit your dependencies and remove any that are unnecessary.
  • Prefetching/Preloading: Utilize <link rel="preload"> or <link rel="prefetch"> for critical assets.

Implementing these changes should help improve your LCP metrics on mobile devices. Let me know if you have any questions or need further assistance!

Analysis chain
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find all TypeScript files with loader functions
fd --extension ts --exec rg --files-with-matches 'export\s+(const|function)\s+loader' {} \; > loader_files.txt

# Check each loader file for 'Cache-Control' headers
while read file; do
  echo "Checking $file"
  rg 'Cache-Control' "$file" || echo "No Cache-Control headers set in $file"
done < loader_files.txt

# Search for usage of compression middleware in the codebase
rg 'compression\(\)'

# Find server setup files (e.g., server.ts, server.js)
fd --extension ts --glob 'server.*'

Length of output: 169


Script:

#!/bin/bash
# Find all TypeScript files with loader functions
rg --files-with-matches 'export\s+(const|function)\s+loader' --glob '*.ts' --glob '*.tsx' > loader_files.txt

# Check each loader file for 'Cache-Control' headers
while read file; do
  echo "Checking $file"
  if ! rg 'Cache-Control' "$file"; then
    echo "No Cache-Control headers set in $file"
  fi
done < loader_files.txt

# Search for usage of compression middleware in the codebase
rg 'compression\(\)' --type file

# Find server setup files (e.g., server.ts, server.js)
rg --files 'server\.(js|ts)$'

Length of output: 7811

import type { LoaderFunction } from '@remix-run/cloudflare'
import { json } from '@remix-run/cloudflare'
import { useLoaderData } from '@remix-run/react'
Expand Down Expand Up @@ -97,6 +98,7 @@ export const loader: LoaderFunction = async ({ params, request }) => {
}

return json({
'Cache-Control': 'public, max-age=31536000, immutable',
history: await historyResponse.json(),
listing: await listingResponse.json(),
itemDescription: (await blogResponse.json()).itemDescription,
Expand Down
Loading