A client-side library to make absolutely positioned elements attach to elements in the page efficiently.
—
Performance optimizations and positioning strategies for smooth user experiences. Tether provides various optimization options to improve rendering performance and reduce layout thrashing.
Configure performance optimizations for better positioning performance.
interface OptimizationOptions {
/** Whether to move elements to optimize positioning (defaults to true) */
moveElement?: boolean;
/** Whether to allow position: fixed for better performance (defaults to true) */
allowPositionFixed?: boolean;
/** Whether to use GPU acceleration via transforms (defaults to true unless false) */
gpu?: boolean;
}Usage in Tether Options:
import Tether from "tether";
const tether = new Tether({
element: '.tooltip',
target: '.button',
attachment: 'top center',
targetAttachment: 'bottom center',
optimizations: {
moveElement: true,
allowPositionFixed: true,
gpu: true
}
});Control GPU acceleration through CSS transforms for better performance.
/**
* GPU acceleration options
* - true (default): Use transforms with GPU acceleration
* - false: Use traditional top/left positioning
*/
gpu?: boolean;Performance Impact:
transform: translateX() translateY() translateZ(0) for hardware accelerationtop and left CSS properties for positioningUsage Examples:
// Enable GPU acceleration (default)
{
optimizations: {
gpu: true
}
}
// Disable GPU acceleration for compatibility
{
optimizations: {
gpu: false
}
}Control CSS positioning strategy for optimal performance.
/**
* Position strategy options
* - allowPositionFixed: true - Use position: fixed when beneficial
* - allowPositionFixed: false - Always use position: absolute
*/
allowPositionFixed?: boolean;Positioning Strategies:
Usage Examples:
// Allow fixed positioning (default - better performance)
{
optimizations: {
allowPositionFixed: true
}
}
// Force absolute positioning (compatibility mode)
{
optimizations: {
allowPositionFixed: false
}
}Control whether Tether can move elements in the DOM for better positioning.
/**
* Element movement options
* - moveElement: true - Allow moving element to optimize positioning
* - moveElement: false - Keep element in original DOM location
*/
moveElement?: boolean;Movement Behaviors:
Usage Examples:
// Allow element movement (default - better performance)
{
optimizations: {
moveElement: true
}
}
// Prevent element movement (preserve DOM structure)
{
optimizations: {
moveElement: false
}
}Tether automatically caches expensive computations for better performance.
/**
* Internal caching system (automatic)
* Caches: element bounds, target bounds, offset parent info, scrollbar size
*/
cache(key: string, getter: Function): any;
clearCache(): void;Cached Values:
Built-in throttling prevents excessive positioning calls.
Throttling Features:
Deferred DOM updates reduce layout thrashing.
/**
* Deferred update system (internal)
* Batches CSS changes and class updates for better performance
*/
defer(callback: Function): void;
flush(): void;Benefits:
Control all active tethers simultaneously.
/**
* Global positioning function for all active tethers
* Efficiently updates all tether instances at once
*/
Tether.position(): void;Usage Example:
// Manually trigger positioning for all tethers
Tether.position();
// Useful after significant DOM changes
document.addEventListener('orientationchange', () => {
setTimeout(Tether.position, 100);
});Built-in event listeners for automatic repositioning.
Auto-handled Events:
window.resize - Viewport size changeswindow.scroll - Window scrollingtouchmove - Touch-based scrolling// Optimal configuration for performance
const tether = new Tether({
element: '.element',
target: '.target',
attachment: 'top center',
targetAttachment: 'bottom center',
// Performance optimizations
optimizations: {
moveElement: true, // Allow DOM restructuring
allowPositionFixed: true, // Use fixed positioning when possible
gpu: true // Enable hardware acceleration
},
// Efficient class management
classPrefix: 'tether', // Use short prefixes
addTargetClasses: false // Skip target classes if not needed
});// Proper cleanup to prevent memory leaks
class MyComponent {
constructor() {
this.tether = new Tether({
element: '.my-element',
target: '.my-target',
attachment: 'top center',
targetAttachment: 'bottom center'
});
}
destroy() {
// Always destroy tether instances
this.tether.destroy();
this.tether = null;
}
}// Efficient management of multiple tethers
class MultiTether {
constructor() {
this.tethers = [];
}
addTether(options) {
const tether = new Tether(options);
this.tethers.push(tether);
return tether;
}
updateAll() {
// Use global positioning for efficiency
Tether.position();
}
destroy() {
// Clean up all tethers
this.tethers.forEach(tether => tether.destroy());
this.tethers = [];
}
}// Monitor positioning performance
const tether = new Tether({
element: '.element',
target: '.target',
attachment: 'top center',
targetAttachment: 'bottom center'
});
tether.on('repositioned', function() {
// Track positioning frequency
console.time('reposition-time');
requestAnimationFrame(() => {
console.timeEnd('reposition-time');
});
});// Access internal positioning data for debugging
tether.on('repositioned', function() {
// Check positioning history
console.log('Position history:', this.history);
// Check cache status
console.log('Cache keys:', Object.keys(this._cache || {}));
});Install with Tessl CLI
npx tessl i tessl/npm-tether