Est-ce un site rapide, pratique et réactif? Ce n'est peut-être pas le résultat du travail fructueux de nombreuses personnes, mais simplement un ensemble d'astuces psychologiques et techniques visant à améliorer la performance perçue.
Dans la plupart des cas, à mesure que les performances réelles augmentent, les performances perçues augmentent également. Et lorsque les performances réelles ne peuvent pas être facilement augmentées, il est possible d'augmenter les performances apparentes. Dans son discours à Frontend Live 2020, l'ancien développeur d'Avito Frontend Architecture Alexey Okhrimenko a parlé de techniques qui améliorent la sensation de vitesse là où il n'est plus possible d'accélérer.
La performance est un must pour le succès des applications Web modernes. Il existe de nombreuses études d'Amazon et de Google qui indiquent que la dégradation des performances est directement proportionnelle à la perte d'argent et conduit à une mauvaise satisfaction de vos services (ce qui vous fait encore perdre de l'argent).
La cause première du stress reçu est l'anticipation. Il a été scientifiquement prouvé qu'il cause:
anxiété;
incertitude;
l'inconfort;
;
.
- , . .
— . , : «, !», , .
: .
, :
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 .