feat: add native-scrollbars option to workaround scrolling perf issues

This commit is contained in:
Roman Hotsiy 2017-09-21 18:03:31 +03:00
parent d8b6e022b7
commit f2ed92c69e
No known key found for this signature in database
GPG Key ID: 5CB7B3ACABA57CB0
4 changed files with 32 additions and 14 deletions

View File

@ -156,6 +156,7 @@ ReDoc makes use of the following [vendor extensions](http://swagger.io/specifica
* `no-auto-auth` - do not inject Authentication section automatically
* `path-in-middle-panel` - show path link and HTTP verb in the middle panel instead of the right one
* `hide-loading` - do not show loading animation. Useful for small docs
* `native-scrollbars` - use native scrollbar for sidemenu instead of perfect-scroll (scrolling performance optimization for big specs)
## Advanced usage
Instead of adding `spec-url` attribute to the `<redoc>` element you can initialize ReDoc via globally exposed `Redoc` object:

View File

@ -9,6 +9,7 @@ $mobile-menu-compact-breakpoint: 550px;
#resources-nav {
position: relative;
width: 100%;
overflow: scroll;
}
ul.menu-root {

View File

@ -22,6 +22,7 @@ const OPTION_NAMES = new Set([
'untrustedSpec',
'hideLoading',
'ignoredHeaderParameters',
'nativeScrollbars',
]);
export interface Options {
@ -40,6 +41,7 @@ export interface Options {
hideLoading?: boolean;
spec?: any;
ignoredHeaderParameters?: string[];
nativeScrollbars?: boolean;
}
@Injectable()
@ -79,7 +81,7 @@ export class OptionsService {
this._normalizeOptions();
}
_normalizeOptions():void {
_normalizeOptions(): void {
// modify scrollYOffset to always be a function
if (!isFunction(this._options.scrollYOffset)) {
if (isFinite(this._options.scrollYOffset)) {
@ -109,6 +111,8 @@ export class OptionsService {
if (isString(this._options.pathInMiddlePanel)) this._options.pathInMiddlePanel = true;
if (isString(this._options.untrustedSpec)) this._options.untrustedSpec = true;
if (isString(this._options.hideLoading)) this._options.hideLoading = true;
if (isString(this._options.nativeScrollbars))
this._options.nativeScrollbars = true;
if (isString(this._options.expandResponses)) {
let str = this._options.expandResponses as string;
if (str === 'all') return;

View File

@ -1,37 +1,49 @@
'use strict';
import 'perfect-scrollbar/dist/css/perfect-scrollbar.css';
import { Directive, ElementRef, Input, OnInit, OnDestroy } from '@angular/core';
import { BrowserDomAdapter as DOM } from '../../../utils/browser-adapter';
import { Directive, ElementRef, OnDestroy, OnInit } from '@angular/core';
import * as PS from 'perfect-scrollbar';
import { OptionsService } from '../../../services/options.service';
@Directive({
selector: '[perfect-scrollbar]'
selector: '[perfect-scrollbar]',
})
export class PerfectScrollbar implements OnInit, OnDestroy {
$element: any;
subscription: any;
enabled: boolean = true;
constructor(elementRef:ElementRef) {
constructor(elementRef: ElementRef, optionsService: OptionsService) {
this.$element = elementRef.nativeElement;
this.enabled = !optionsService.options.nativeScrollbars;
}
update() {
if (!this.enabled) return;
PS.update(this.$element);
}
ngOnInit() {
requestAnimationFrame(() => PS.initialize(this.$element, {
wheelSpeed: 2,
wheelPropagation: false,
minScrollbarLength: 20,
suppressScrollX: true
}));
if (!this.enabled) return;
requestAnimationFrame(() =>
PS.initialize(this.$element, {
wheelSpeed: 2,
handlers: [
'click-rail',
'drag-scrollbar',
'keyboard',
'wheel',
'touch',
],
wheelPropagation: true,
minScrollbarLength: 20,
suppressScrollX: true,
} as any),
);
}
ngOnDestroy() {
if (!this.enabled) return;
PS.destroy(this.$element);
}
}