Back to Home

Website Optimization for Safari iOS

Optimizations checklist eliminates typical Safari issues on iOS: HTTP/1.1 queues, thrashing JS, OOM canvas. Includes HTTP/2, lazy loading, defer scripts, PurgeCSS. Suitable for middle/senior developers.

Fast website in Safari: full checklist
Advertisement 728x90

Safari Website Optimization: A Developer's Checklist

Sites that load smoothly in Chrome or Firefox often lag in Safari on iOS. HTTP/1.1 limitations, a single-threaded JavaScript engine, and strict memory limits lead to request queues, thrashing, and OOM-kills. This optimization checklist addresses typical Safari issues without compromising functionality.

Critical Fixes for Safari Stability

Safari limits connections to 6 per domain in HTTP/1.1, causing queues when loading multiple resources. The single-threaded JS engine struggles with frequent scroll/resize events, and canvases over 4000×10000 pixels can crash tabs.

Essential Steps

  • Switch to HTTP/2

Nginx configuration:

Google AdInline article slot

```nginx

server {

listen 443 ssl http2;

Google AdInline article slot

server_name mysite.com;

ssl_certificate /path/to/cert.pem;

ssl_certificate_key /path/to/key.pem;

Google AdInline article slot

root /var/www/html;

index index.html;

}

```

Reload: sudo nginx -s reload. Check in DevTools: Protocol = h2.

  • Lazy loading for below-the-fold images

```html

<img src="hero.jpg" alt="Main banner" class="hero-image">

<img src="gallery/photo1.jpg" alt="Photo" loading="lazy">

```

For Swiper:

```html

<img data-src="slide1.jpg" class="swiper-lazy" alt="Slide">

<div class="swiper-lazy-preloader"></div>

```

  • Defer for all scripts except jQuery

```html

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>

<script src="js/slider.js" defer></script>

<script src="js/main.js" defer></script>

```

  • Remove unused libraries

Check: console.log(window.THREE). Search project: THREE. or three.js.

  • Throttle scroll/resize/wheel

```javascript

let ticking = false;

window.addEventListener('scroll', () => {

if (!ticking) {

requestAnimationFrame(() => {

onScrollHeavyTask();

ticking = false;

});

ticking = true;

}

});

```

  • Optimize canvas on mobile

Recalculate based on screen width, reduce particles on small resolutions.

High-Priority Loading Improvements

Gzip/Brotli compression in nginx:

gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;

Preconnect for CDN in <head>:

<link rel="preconnect" href="https://code.jquery.com">
<link rel="preconnect" href="https://cdn.jsdelivr.net">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

PurgeCSS for CSS (Gulp):

const gulp = require('gulp');
const purgecss = require('gulp-purgecss');

gulp.task('purge', () => {
  return gulp.src('dist/css/style.css')
    .pipe(purgecss({
      content: ['**/*.html', '**/*.js'],
      safelist: [/swiper/, /modal/, /active/, /open/]
    }))
    .pipe(gulp.dest('dist/css'));
});

PostCSS version is similar.

Remove jQuery Migrate: ensure no JQMIGRATE in console.

font-display: swap:

@font-face {
  font-family: 'Open Sans';
  src: url('/fonts/OpenSans.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}

Optimizations for Lighthouse

Critical CSS inline + async loading:

<style>
  .header { background: #fff; }
  .hero { font-size: 2rem; }
</style>
<link rel="preload" href="css/main.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="css/main.css"></noscript>

WebP with fallback:

<picture>
  <source srcset="images/photo.webp" type="image/webp">
  <source srcset="images/photo.jpg" type="image/jpeg">
  <img src="images/photo.jpg" alt="Description" loading="lazy" width="800" height="600">
</picture>

Gulp for WebP:

const imagemin = require('gulp-imagemin');
const webp = require('gulp-webp');

gulp.task('webp', () => {
  return gulp.src('src/images/**/*.{jpg,png}')
    .pipe(webp())
    .pipe(gulp.dest('dist/images'));
});

Key Takeaways

  • HTTP/2 eliminates connection queues in Safari.
  • Throttling scroll/resize prevents thrashing in the single-threaded JS.
  • Lazy loading + defer reduce render-blocking.
  • PurgeCSS and library removal cut JS/CSS volume.
  • Canvas optimization is critical for animated backgrounds.

Regular audits with this checklist minimize traffic loss from iOS audiences.

— Editorial Team

Advertisement 728x90

Read Next