Web Caching

Andres Alvarez

Front-End Developer

Cache

  • High-speed data storage
  • Subset of data
  • Hit and miss
  • Retrieve computed data

Cache Miss

Cache Hit

Web Cache

Why do we want it ?

Improve performance ⚡️

Performance

Service Worker

  • Proxy servers 🛰
  • Sits between app, browser and network 🚀

Service Worker

HTTP Cache

  • Avoid unnecessary requests
  • Doesn't require much work
  • Cache stored in the browser
  • Request and response headers

Cache Response Headers

Cache-Control

  • How
  • How long
  • Intermediate caches
  • Stale while Revalidate

Cache-Control: public, max-age=31536000

Etag

  • Expired cache
  • Token
  • Hash of the file content

304 Not Modified

Etag

Last-Modified

  • Same as ETag
  • Time based

Cache-Control

Cache-Control

CDN

  • Content Delivery Network
  • Edge Servers around the world 🌎
  • CloudFront

CDN

CDN

Server Caching

  • In memory
  • Redis or Mencached
  • @cache

@s-ui/decorator

Server Caching

import {UseCase} from '@s-ui/domain'
import {inlineError, cache} from '@s-ui/decorators'

// uses params as keys
export class GetSeoTagsSearchUseCase extends UseCase {
  @cache({
    server: true,
    ttl: '1 minute'
  })
  async execute({params}) {
    const [seoTagsError, seoTagsResponse] = await this._service.execute({
      params
    })

    if (seoTagsError) {
      return Promise.reject(seoTagsError)
    }

    return seoTagsResponse?.toJSON()
  }
}

Redis Caching

import {UseCase} from '@s-ui/domain'
import {inlineError, cache} from '@s-ui/decorators'

export class GetSeoTagsSearchUseCase extends UseCase {
  @cache({
    server: true,
    ttl: '1 minute',
    redis: {host: 'localhost', port: 6379}
  })
  async execute({adSearchParamsAggregate}) {
    const [seoTagsError, seoTagsResponse] = await this._service.execute({
      adSearchParamsAggregate
    })

    if (seoTagsError) {
      return Promise.reject(seoTagsError)
    }

    return seoTagsResponse?.toJSON()
  }
}

Browser Caching

const cache = {}

const execute = (id) => {
  // hit
  // more conditions could be added e.g. ttl
  if (cache[id] !== undefined) {
    return cache[id]
  }
  
  // miss
  const value = compute(id)  
  cache[id] = value
}


execute('1')

Browser Caching

  • @cache
  • react-query
  • swr

Be careful when using cache

Fotocasa Server Memory

Key takeaways

  • Cache improves performance
  • Use cache when is truly needed
  • Cache invalidation is hard
  • Do not over optimize

Questions ?

Made with Slides.com