Este é um site rápido, conveniente e responsivo? Talvez este não seja o resultado do trabalho frutífero de muitas pessoas, mas apenas um conjunto de truques psicológicos e de engenharia que visam melhorar a Performance Percebida.
Na maioria dos casos, à medida que o desempenho real aumenta, o desempenho percebido também aumenta. E quando o desempenho real não pode ser facilmente aumentado, há uma oportunidade de aumentar o desempenho aparente. Em sua palestra no Frontend Live 2020, o ex-desenvolvedor do Avito Frontend Architecture Alexey Okhrimenko falou sobre técnicas que melhoram a sensação de velocidade onde não é mais possível acelerar.
O desempenho é fundamental para o sucesso dos aplicativos da Web modernos. Há muitos estudos da Amazon e do Google que afirmam que a degradação do desempenho é diretamente proporcional à perda de dinheiro e leva à baixa satisfação com seus serviços (o que, novamente, faz você perder dinheiro).
A causa raiz do estresse recebido é a antecipação. Foi cientificamente comprovado que causa:
ansiedade;
incerteza;
o desconforto;
;
.
- , . .
— . , : «, !», , .
: .
, :
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 — . , , .