阿里云主机折上折
  • 微信号
Current Site:Index > Methods to reduce the number of HTTP requests

Methods to reduce the number of HTTP requests

Author:Chuan Chen 阅读数:14307人阅读 分类: 性能优化

The number of HTTP requests is one of the key factors affecting webpage performance. Excessive requests can lead to longer page load times and degrade the user experience. Techniques such as merging resources, using CSS sprites, and inlining critical CSS can effectively reduce the number of requests and improve page performance.

Merging CSS and JavaScript Files

Combining multiple CSS or JavaScript files into a single file is the most straightforward optimization method. Each file requires a separate HTTP request, and merging them can significantly reduce the number of requests.

// Before merging
<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="base.css">
<link rel="stylesheet" href="components.css">

// After merging
<link rel="stylesheet" href="all.css">

Build tools like Webpack and Gulp can automate this process:

// webpack.config.js
module.exports = {
  entry: {
    app: ['./src/js/main.js', './src/js/utils.js']
  },
  output: {
    filename: 'bundle.js'
  }
}

Using CSS Sprites

CSS sprites combine multiple small icons into a single large image, displaying specific parts via CSS background positioning. This is particularly useful for navigation icons, social buttons, and similar elements.

.icon {
  background-image: url('sprite.png');
  background-repeat: no-repeat;
}

.icon-home {
  width: 32px;
  height: 32px;
  background-position: 0 0;
}

.icon-user {
  width: 32px;
  height: 32px;
  background-position: -32px 0;
}

Modern build tools can automatically generate sprites and their corresponding CSS:

// Using gulp.spritesmith
const gulp = require('gulp');
const spritesmith = require('gulp.spritesmith');

gulp.task('sprite', function() {
  return gulp.src('images/icons/*.png')
    .pipe(spritesmith({
      imgName: 'sprite.png',
      cssName: 'sprite.css'
    }))
    .pipe(gulp.dest('dist'));
});

Inlining Critical CSS

Inlining the critical CSS required for above-the-fold rendering directly into the HTML avoids additional requests that block rendering. Non-critical CSS can be loaded asynchronously.

<head>
  <style>
    /* Critical CSS */
    body { font-family: sans-serif; }
    .header { background: #333; }
    .hero { padding: 2em; }
  </style>
  <!-- Load remaining CSS asynchronously -->
  <link rel="preload" href="non-critical.css" as="style" onload="this.rel='stylesheet'">
</head>

Inlining Small Images with Base64 Encoding

For images smaller than 2KB, consider converting them to Base64 encoding and embedding them directly in CSS or HTML to eliminate additional HTTP requests.

.logo {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AkEEjUXKw0bJQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAJklEQVQ4y2NgGAWjYBSMglEwCkbBKBgFowAAATMAZ/8Pq/kAAAAASUVORK5CYII=');
}

Using Icon Fonts Instead of Image Icons

Icon fonts treat icons as characters, allowing hundreds of icons to be included in a single font file with just one HTTP request.

<link rel="stylesheet" href="font-awesome.css">

<i class="fa fa-user"></i>
<i class="fa fa-home"></i>
<i class="fa fa-cog"></i>

Lazy Loading Non-Critical Resources

Use lazy loading techniques to defer the loading of images, iframes, and other resources that are not needed for the initial view, reducing the number of initial requests.

<img data-src="image.jpg" class="lazyload" alt="Example image">

<script>
document.addEventListener("DOMContentLoaded", function() {
  const lazyImages = [].slice.call(document.querySelectorAll("img.lazyload"));
  
  if ("IntersectionObserver" in window) {
    let lazyImageObserver = new IntersectionObserver(function(entries) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          let lazyImage = entry.target;
          lazyImage.src = lazyImage.dataset.src;
          lazyImageObserver.unobserve(lazyImage);
        }
      });
    });

    lazyImages.forEach(function(lazyImage) {
      lazyImageObserver.observe(lazyImage);
    });
  }
});
</script>

Using HTTP/2 Server Push

HTTP/2's server push feature allows the server to proactively send resources, reducing round-trip requests.

# Nginx configuration example
http2_push /style.css;
http2_push /main.js;

Setting Appropriate Caching Policies

Configure proper cache headers to allow browsers to reuse downloaded resources and avoid repeated requests.

# Nginx caching configuration
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
  expires 365d;
  add_header Cache-Control "public, no-transform";
}

Using WebP Format Images

WebP format typically results in smaller file sizes than PNG or JPEG, reducing the transfer time for image requests.

<picture>
  <source srcset="image.webp" type="image/webp">
  <img src="image.jpg" alt="Example image">
</picture>

Reducing Third-Party Script Usage

Evaluate the necessity of third-party scripts and merge or remove unnecessary tracking codes, social plugins, etc.

<!-- Avoid this -->
<script src="analytics.js"></script>
<script src="social-share.js"></script>
<script src="chat-widget.js"></script>

<!-- Opt for on-demand loading -->
<button id="load-chat">Need help? Click to load chat</button>
<script>
document.getElementById('load-chat').addEventListener('click', function() {
  const script = document.createElement('script');
  script.src = 'chat-widget.js';
  document.body.appendChild(script);
});
</script>

Using Service Workers to Cache Resources

Service workers can intercept network requests for more granular cache control.

// service-worker.js
const CACHE_NAME = 'v1';
const urlsToCache = [
  '/',
  '/styles/main.css',
  '/scripts/main.js',
  '/images/logo.png'
];

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => cache.addAll(urlsToCache))
  );
});

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)
      .then(response => response || fetch(event.request))
  );
});

Optimizing API Requests

Merge API endpoints or use query languages like GraphQL to reduce the number of data requests.

// Traditional REST API
fetch('/api/user/123');
fetch('/api/user/123/posts');

// GraphQL query
fetch('/graphql', {
  method: 'POST',
  body: JSON.stringify({
    query: `
      {
        user(id: 123) {
          name
          email
          posts {
            title
            date
          }
        }
      }
    `
  })
});

Using CDNs to Accelerate Resource Loading

Content Delivery Networks (CDNs) reduce the physical distance for resource requests, improving load times.

<!-- Load common libraries from a CDN -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">

Preloading Critical Resources

Use <link rel="preload"> to load critical resources in advance and avoid request blocking.

<head>
  <link rel="preload" href="critical.css" as="style">
  <link rel="preload" href="main.js" as="script">
  <link rel="preload" href="hero-image.jpg" as="image">
</head>

Reducing Redirects

Avoid unnecessary redirects, as each redirect generates an additional HTTP request.

# Avoid this
location /old-page {
  return 301 /new-page;
}

# Link directly to the final destination
<a href="/new-page">Go to new page</a>

Using SVG Instead of Some Images

SVG is a vector format that typically results in smaller files and can be inlined in HTML.

<!-- Inline SVG example -->
<svg width="100" height="100" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40" fill="#f00"/>
</svg>

Optimizing Web Font Usage

Use fonts judiciously to avoid excessive font variants that lead to additional requests.

/* Avoid this */
@font-face {
  font-family: 'MyFont';
  src: url('myfont-regular.woff2') format('woff2');
  font-weight: 400;
}
@font-face {
  font-family: 'MyFont';
  src: url('myfont-bold.woff2') format('woff2');
  font-weight: 700;
}

/* Use unicode-range to split font files */
@font-face {
  font-family: 'MyFont';
  src: url('myfont-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF;
}

Reducing Cookie Size

Large cookies are automatically sent with every request, increasing the request payload.

// Set cookies with specific paths to avoid global cookies
document.cookie = "preferences=dark; path=/settings; max-age=31536000";

Using Modular JavaScript

Modern JavaScript module systems allow better control over code splitting and on-demand loading.

// Dynamic module import
button.addEventListener('click', async () => {
  const module = await import('./module.js');
  module.doSomething();
});

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.