これは高速で便利でレスポンシブなサイトですか?おそらくこれは多くの人々の実りある仕事の結果ではなく、知覚されたパフォーマンスを改善することを目的とした心理的および工学的なトリックのセットにすぎません。
ほとんどの場合、実際のパフォーマンスが向上すると、知覚パフォーマンスも向上します。また、実際のパフォーマンスを簡単に上げることができない場合は、見かけのパフォーマンスを上げる機会があります。Frontend Live 2020での講演で、元Avito FrontendArchitectureの開発者であるAlexeyOkhrimenkoは、加速できなくなったスピード感を向上させるテクニックについて話しました。
最新のWebアプリケーションを成功させるには、パフォーマンスが必須です。アマゾンとグーグルからの多くの研究は、パフォーマンスの低下はお金の損失に正比例し、あなたのサービスに対する満足度の低下につながると言っています(これもあなたがお金を失うことになります)。
受けたストレスの根本的な原因は予想です。以下の原因となることが科学的に証明されています。
不安;
不確実性;
不快感;
;
.
- , . .
— . , : «, !», , .
: .
, :
lighthouse;
devTools profiler.
, .
Houston. .
: , , . , - .
. Huston , , 8 . .
, . . , . , . . , : 8 .
, ?
Perceived Performance
Perceived Performance, . . .
, , — .
, , . , , .
, . .
Angular , , , . !
: . : « !».
:
, - , , .
? ?
— ! .
?
«» (item ), . , , , , — — . : « 1 !» — . RxJs concat :
import { concat } from 'rxjs';
const source = concat(
myService.saveStuff({ test: 'swag '}),
myService.saveStuff({ test: 'yolo '})
);
, , , .
: « , - . , ».
, , :
<ngx-spinner [fullScreen]="false">
<p class="loading">Loading Awesomeness...</p>
</ngx-spinner>
Angular ngx-spinner, .
, , , -.
.
, . , , . .
: , Motion Blur ( ). . , , , , .
""?
Progress Bar;
, , , Progress Bar, . 12% , . , Progress Bar, 12% . , CSS.
;
— , ? , , .
— :
, .
, , 10 20%.
, .
Angular, React, View. , Angular ngx-skeleton-loader, . :
<ngx-skeleton-loader
appearance="circle"
[theme]="{ width: '80px', height: '80px' }"
>
</ngx-skeleton-loader>
CS:GO? ! , . Latency/Lag compensation.
frontend Optimistic Updates. Twitter
, backend 2 .
Optimistic Updates ? http :
addItem(item) {
return this.http.post<Item>('/add-item', item)
.subscribe(res => {
this.items.push(res);
}, error => {
this.showErrorMessage(error);
})
}
Optimistic Update:
addItem(item) {
this.items.push(item); //
return this.http.post<Item>('/add-item', item)
.subscribe(
res => {
//
}, error => {
// -
this.items.splice(this.items.indexOf(item), 1);
this.showErrorMessage(error);
}
);
}
State Managers , Optimistic Updates. , State Manager (redux, mobx, appollo-graphql, etc.)
, — , . Optimistic Updates : . . Optimistic Update:
addItem(item) {
return this.http.post<Item>('/add-item', item)
.subscribe(res => {
this.items.push(res);
}, error => {
this.showErrorMessage(error);
})
}
, API . , .
addItem(item) {
this.items.push(item); //
return this.http.post<Item>('/add-item', item)
.pipe(retry()) //
.subscribe(
// ...
);
}
best practice -, . , . : . API 100% , 99,9% uptime.
. , - . . , 3 .
addItem(item) {
this.items.push(item); //
return this.http.post<Item>('/add-item', item)
.pipe(
retry(3)
)
.subscribe(
// ...
);
}
DDOS (Distributed Denial of Service). . , Apple MobileMe.
? , , . , - 500. , , .
, , , DDOS. , - .
Best practice: exponential backoff. rxjs npm backoff-rxjs, .
import { retryBackoff } from 'backoff-rxjs';
addItem(item) {
this.items.push(item);
return this.http.post<Item>('/add-item', item)
.pipe(
retryBackoff({
initialInterval: 100,
maxRetries: 3,
resetOnSuccess: true
})
)
.subscribe(
// ...
);
}
, 10 . . , , , . : 1 , 2 , 4 ..
, API.
— Math.random() initialInterval:
import { retryBackoff } from 'backoff-rxjs';
addItem(item) {
this.items.push(item);
return this.http.post<Item>('/add-item', item)
.pipe(
retryBackoff({
initialInterval: Math.random() * 100,
maxRetries: 3,
resetOnSuccess: true
})
)
.subscribe(
// ...
);
}
, , , , . , .
!
, ?
. , , , , . -.
;
— . , SPA-. , . preload , :
var images = [];
function preload() {
for (var i = 0; i < arguments.length; i++) {
images[i] = new Image();
images[i].src = preload.arguments[i];
}
}
preload(
"http://domain.tld/image-001.jpg",
"http://domain.tld/image-002.jpg",
"http://domain.tld/image-003.jpg"
)
«», .
18+
HTML link, stylesheets:
<link
rel="stylesheet"
href="styles/main.css"
>
, :
<link
rel="preload"
href="styles/main.css"
as="style"
>
rel ="preload", (href="styles/main.css"), as .
prefetch.
— prefetch:
<link
rel="prefetch"
href="styles/main.css"
>
— , preload prefetch — . preload prefetch , preload , . , , , hero images ( ).
, , .
- JavaScript , 3 . , , — 1,2 . , .
?
Machine Learning
Guess.js. Google Google Analytics.
, , prefetch 7% .
90%. 7%, 90% . prefetching/preloading, , . Guess.js — .
Guess.js Angular, Nuxt js, Next.js Gatsby. .
Click-
, ?
<div (lick)="onClick()">
button! ;)
</div>
, ? .
, mousedown. 100-200 , Click.
:
<div (onmousedown)="onClick()">
button! ;)
</div>
click mousedown, 100-200 .
( RouR ), mousedown , , click — «» ( , )
mousedown hover - UX Accessibility.
, , mousedown hover :)
, , 240-500 , o_O.
ML? . : - , ( ).
, , , .
futurelink. :
var futurelink = require('futurelink');
futurelink({
links: document.querySelectorAll('a'),
future: function (link) {
// `link` is probably going to be clicked soon
// Preload everything you can!
}
});
DOM , . , callback. .
? : HTML, CSS .
SSR.
Angular :
ng add @nguniversal/express-engine
, Server-Side Rendering.
, Angular? , , ?
prerender: , HTML. webpack, PrerenderSPAPlugin:
const path = require('path')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
module.exports = {
plugins: [
...
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'dist'),
routes: [ '/', '/about', '/some/deep/nested/route' ],
})
]
}
, urls, , .
: SPA :
document.documentElement.outerHTML
HTML : . . , ( ).
Perceived Performance — , . FrontendConf 2019.
, , 68% , . , , Perceived Performance . .
..
, . , . , . , . UX- .
, , Perceived Performance.
Perceived performance — . , , .