Apakah ini situs yang cepat, nyaman, dan responsif? Mungkin ini bukan hasil kerja bermanfaat banyak orang, tetapi hanya serangkaian trik psikologis dan teknik yang bertujuan untuk meningkatkan Kinerja Persepsi.
Dalam kebanyakan kasus, seiring dengan peningkatan kinerja nyata, begitu pula Perceived Performance. Dan ketika kinerja sebenarnya tidak dapat dengan mudah ditingkatkan, ada peluang untuk meningkatkan kinerja semu. Dalam pidatonya di Frontend Live 2020, mantan pengembang Arsitektur Frontend Avito Alexey Okhrimenko berbicara tentang teknik yang meningkatkan perasaan kecepatan yang tidak memungkinkan lagi untuk berakselerasi.
Performa adalah suatu keharusan untuk keberhasilan aplikasi Web modern. Ada banyak penelitian dari Amazon dan Google yang mengatakan bahwa penurunan kinerja berbanding lurus dengan hilangnya uang dan menyebabkan kepuasan yang buruk terhadap layanan Anda (yang sekali lagi membuat Anda kehilangan uang).
Akar penyebab stres yang diterima adalah antisipasi. Telah terbukti secara ilmiah menyebabkan:
kegelisahan;
ketidakpastian;
ketidaknyamanan;
;
.
- , . .
โ . , : ยซ, !ยป, , .
: .
, :
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 โ . , , .
โ Telegram, Twitter, VK FB .