|
1 | 1 | # Assets |
2 | 2 |
|
3 | | -Assets are files such as images and CSV data that we serve statically to run the docs.github.com application. |
| 3 | +This directory contains the logic for serving, processing, and validating static assets used in the GitHub Docs application. While the actual asset files (images, CSVs, etc.) reside in the root `assets/` directory, `src/assets` houses the code that manages how these assets are delivered to the user. |
| 4 | + |
| 5 | +## Purpose & Scope |
| 6 | + |
| 7 | +The primary responsibilities of this module are: |
| 8 | +- **Dynamic Image Processing**: Converting PNGs to WebP on-the-fly and resizing images based on URL parameters. |
| 9 | +- **Caching Strategy**: Setting appropriate cache headers and surrogate keys for assets, especially those with checksums in their URLs. |
| 10 | +- **Validation & Maintenance**: Scripts to ensure assets are used correctly, identifying orphaned files, and validating image dimensions. |
| 11 | + |
| 12 | +## Architecture |
| 13 | + |
| 14 | +### Middleware |
| 15 | + |
| 16 | +The core logic resides in `src/assets/middleware`: |
| 17 | + |
| 18 | +- **`dynamic-assets.ts`**: Intercepts requests for `/assets/`. It handles: |
| 19 | + - **WebP Conversion**: If a request ends in `.webp` but the source is a `.png`, it converts the image using `sharp`. |
| 20 | + - **Resizing**: Supports virtual path segments like `/mw-1000/` to resize images to a maximum width (e.g., 1000px). |
| 21 | + - **Security**: Validates requested widths against an allowed list (`VALID_MAX_WIDTHS`) to prevent DoS attacks. |
| 22 | +- **`static-asset-caching.ts`**: Detects if an asset URL contains a checksum (e.g., `/assets/cb-12345/...`) and sets aggressive caching headers (`Surrogate-Key: manual-purge`) because the content is immutable. |
| 23 | + |
| 24 | +### Scripts |
| 25 | + |
| 26 | +Located in `src/assets/scripts`, these tools help maintain the asset library: |
| 27 | +- `find-orphaned-assets.ts`: Identifies assets present in the disk but not referenced in the content or code. |
| 28 | +- `validate-asset-images.ts`: Checks for issues like invalid file types or corruption. |
| 29 | +- `list-image-sizes.ts`: Utility for analyzing image dimensions. |
| 30 | + |
| 31 | +### Library |
| 32 | + |
| 33 | +- `src/assets/lib/image-density.ts`: Utilities for handling high-density (Retina) images. |
| 34 | + |
| 35 | +## Setup & Usage |
| 36 | + |
| 37 | +### Adding New Assets |
| 38 | + |
| 39 | +Place static files (images, PDFs, etc.) in the root `assets/` directory. |
| 40 | +- **Images**: `assets/images` |
| 41 | +- **Data**: `assets/` (e.g., CSV files) |
| 42 | + |
| 43 | +### URL Structure |
| 44 | + |
| 45 | +The application (via `src/frame`) often rewrites asset URLs to include a checksum for cache busting. |
| 46 | +- **Source**: `/assets/images/foo.png` |
| 47 | +- **Served**: `/assets/cb-123456/images/foo.png` (The `cb-xxxxx` part is ignored by the file system lookup but used for caching). |
| 48 | + |
| 49 | +### Dynamic Transformations |
| 50 | + |
| 51 | +To request a WebP version of a PNG: |
| 52 | +`GET /assets/images/foo.webp` (Server looks for `foo.png` and converts it). |
| 53 | + |
| 54 | +To request a resized version: |
| 55 | +`GET /assets/mw-1000/images/foo.webp` (Resizes to max-width 1000px). |
| 56 | + |
| 57 | +## Dependencies |
| 58 | + |
| 59 | +- **`sharp`**: Used for high-performance image processing (resizing, format conversion). |
| 60 | +- **`assets/` directory**: The source of truth for static files. |
| 61 | + |
| 62 | +## Ownership |
| 63 | + |
| 64 | +- **Team**: `@github/docs-engineering` |
| 65 | +- **Escalation**: If image serving fails or performance degrades, check the `dynamic-assets` middleware and `sharp` processing. |
| 66 | + |
| 67 | +## Current State & Known Issues |
| 68 | + |
| 69 | +- **On-the-fly Processing**: We currently process images on request (cached by CDN). This avoids a massive build-time step but requires CPU resources on the server for uncached requests. |
| 70 | +- **WebP**: We prefer WebP for performance but maintain PNGs as the source of truth. |
0 commit comments