Оптимизация производительности критических путей с помощью экспресс-сервера и руля

В последнее время я работаю на изоморфных React сайте. Этот веб-сайт был разработан с использованием React, работая на сервере Express. Все шло хорошо, но я все еще не был удовлетворен нагрузкой блокировки CSS расслоение. Итак, я начал думать о вариантах реализации техники критического пути на сервере Express.

Эта статья содержит мои заметки об установке и настройке оптимизации производительности критического пути с использованием Express и Handlebars.

Дальнейшее чтение на Smashing:

Необходимые условия

На протяжении всей этой статьи, я буду использовать Node.js и Express. Знакомство с ними поможет вам понять примеры.

Lifecycle of Critical Path Performance Optimization
Цикл оптимизации производительности критического пути(просмотр большой версии)

tl;dr

Я подготовил репозиторий с быстрой и легкой демонстрацией.

Основы

Оптимизация критических путей — это метод, который устраняет блокировку CSS. Этот метод может значительно увеличить скорость, с которой веб-сайт загружается. Цель этого метода состоит в том, чтобы избавиться от времени, которое пользователь ждет CSS расслоение для загрузки. После загрузки пакета браузер сохраняет его в кэше, и все последующие перезарядки подаются из кэша. Исходя из этого, наши цели заключаются в следующем:

  • Различать первую и вторую (и n-ую) нагрузки.
  • При первой нагрузке, загрузите расслоение CSS асинхронно, и приложите слушателя события нагрузки, чтобы мы могли узнать, когда расслоение готово к обслуже.
  • В то время как пакет загружается, вставьте некоторые небольшие критические CSS, чтобы сделать пользовательский опыт как можно более похожим на конечный результат.
  • Как только слушатель события сообщает, что пакет CSS готов, удалите внеочередную CSS и обслуживаем пакет.
  • Убедитесь, что другие источники (пакеты JavaScript и т.д.) не блокируют рендеринг.

Обнаружение первой нагрузки

Чтобы обнаружить первую нагрузку, мы собираемся использовать файл cookie. Если файл cookie не установлен, это означает, что это первая нагрузка. В противном случае, это будет вторая или nth нагрузка.

Загрузка csS Bundle асинхронно

Чтобы начать асинхронную загрузку пакета CSS, мы собираемся использовать простой метод, включающий недействительное media значение атрибута. Установка media атрибута на недействительное значение приведет к асинхронной загрузке расслоения CSS, но не будет применяться никаких стилей до тех пор, пока атрибут не media будет установлен на допустимое значение. Другими словами, для того, чтобы применить стили из расслоения CSS, мы изменим media атрибут на допустимое значение после загрузки пакета.

Критические CSS против CSS расслоение

Мы будем держать критические стили в строке разметки только во время загрузки расслоения CSS. После загрузки пакета, что критические CSS будут удалены из разметки. Для этого мы также создадим критический JavaScript, который будет в основном небольшим обработчиком JavaScript.

Жизненного цикла

Подводя итог, можно сказать, что вот простая схема нашего жизненного цикла:

Lifecycle of critical path performance optimization
Цикл оптимизации производительности критического пути(просмотр большой версии)

Переход изоморфных

Теперь, когда вы знаете больше об этом методе, представьте его в сочетании с изоморфным приложением JavaScript. Isomorphic JavaScript, также называемый универсальным JavaScript, просто означает, что приложение, написанное в JavaScript, способно запускать и генерировать HTML разметку на сервере. Если вам интересно, узнайте больше о подходе React относительно ReactDOM.renderToString и ReactDOM.renderToStaticMark.

Возможно, вы все еще задаетесь вопросом, почему мы должны генерировать HTML на сервере. Ну, подумай о первой нагрузке. При использовании кода только для клиентов нашим посетителям придется ждать расслоения JavaScript. Во время загрузки пакета JavaScript посетители увидят пустую страницу или предзагрузчик. Я считаю, что цель юн-энд-разработчиков должна заключаться в том, чтобы свести к минимуму такие сценарии. С изоморфным кодом все по-другому. Вместо пустой страницы и предзагрузчика посетители увидят сгенерированную разметку, даже без пакета JavaScript. Конечно, расслоение CSS также займет некоторое время для загрузки, и без него наши посетители увидят только нестильную разметку. К счастью, используя оптимизацию производительности критического пути, это легко решить.

Isomorphic JavaScript application
Изоморфное javaScript приложение(Посмотреть большую версию)

Подготовка окружающей среды

Ускоренная регистрация

Express — это минимальная и гибкая платформа веб-приложений Node.js.

Во-первых, установите все необходимые пакеты: express , и . является express-handlebars cookie-parser express-handlebars движок Просмотров Handlebars для Express, и cookie-parser поможет нам с печеньем позже.

npm install express express-handlebars cookie-parser --save-dev

Создайте server.js файл с импортом этих пакетов. Мы также будем использовать path пакет позже, который является частью Node.js.

import express from 'express';
import expressHandlebars from 'express-handlebars';
import cookieParser from 'cookie-parser';
import path from 'path';

Создайте приложение Express:

var app = express();

Гора cookie-parser :

app.use(cookieParser());

Наш пакет CSS будет доступен по адресу /assets/css/bundle.css . Для обслуживания статических файлов из Express мы должны установить имя пути каталога, где находятся наши статические файлы. Это можно сделать с помощью встроенной функции промежуточного express.static ПО. Наши файлы будут в каталоге с именем build ; так, локальный файл на /build/assets/css/bundle.css будет обслуживаться браузером на /assets/css/bundle.css .

app.use(express.static('build'));

Для этой демонстрации, создание одного маршрута HTTP GET ( ) / будет достаточно:

// Register simple HTTP GET route for /
app.get('/', function(req, res){
  // Send status 200 and render content. Content, in this case, is a non-existent template. For me, rendering the layout is important.
  res.status(200).render('content');
});

И давайте связывать Экспресс слушать на порту 3000 :

// Set the server port to 3000, and log the message when the server is ready.
app.listen(3000, function(){
  console.log('Local server is listening…');
});

Вавилон и ES2016

Учитывая синтаксис ECMAScript 2016 (или ES2016), мы собираемся установить Babel и его пресеты. Babel — это компилятор JavaScript, который позволяет нам использовать JavaScript нового поколения сегодня. Вавилонские пресеты — это лишь специфическая логика преобразования Вавилонов, извлеченная в меньшие группы плагинов (или пресетов). Наша демо требует React и ES2015 пресетов.

npm install babel-core babel-preset-es2015 babel-preset-react --save-dev

Создайте .babelrc файл со следующим кодом. Здесь мы по существу говорим: «Эй, Вавилон, используйте эти пресеты»:

{
  "presets": [
    "es2015",
    "react"
  ]
}

Как говоритсяв документации Babel, для обработки синтаксиса ES2016, Babel требует babel-core/register крючка в точке входа приложения. В противном случае, он будет бросать ошибку. Давайте entry.js создадим:

require("babel-core/register");
require('./server.js');

Теперь проверьте конфигурацию:

$ node entry.js

Ваш терминал должен войти в это сообщение:

Local server is listening…

Однако, если вы перемещаетесь в браузер еhttp://localhost:3000/,вы получите эту ошибку:

Error: No default engine was specified and no extension was provided.

Это просто означает, что Express не знает, что и как визуализировать. Мы избавимся от этой ошибки в следующем разделе.

Руле

Handlebars называется «минимальной шаблоны на стероидах». Давайте вспомним. Открыто server.js :

// register new template engine
// first parameter = file extension
// second parameter = callback = expressHandlebars
// defaultLayout is the name of default layout located in layoutsDir.
app.engine('handlebars', expressHandlebars(
{
  defaultLayout: 'main',
  layoutsDir:    path.join(__dirname, 'views/layouts'),
  partialsDir: path.join(__dirname, 'views/partials')
}
));
// register new view engine
app.set('view engine', 'handlebars');

Создайте каталоги views/layouts и views/partials . В, views/layouts создать файл с именем , и main.handlebars вставить следующий HTML. Это будет наш основной макет.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Critical-Path Performance Optimization</title>
    <link rel="stylesheet" href="assets/css/bundle.css" id="cssbundle" media="none"/>
  </head>
  <body>
  </body>
</html>

Также создайте файл, названный content.handlebars в views каталоге, и вставьте следующий HTML.

<div id="app">magic here</div>

Запустите сервер сейчас:

$ node entry.js

Перейти к http://localhost:3000. Ошибка исчезла, и разметка макета готова.

Критический путь

Наша окружающая среда готова. Теперь мы можем реализовать оптимизацию критического пути.

Определение первой нагрузки

Как вы помните, наша первая цель состоит в том, чтобы определить, является ли нагрузка первой. На основе этого мы можем решить, обслуживать ли критические стили или расслоение CSS из кэша браузера. Мы будем использовать печенье для этого. Если настроено файл cookie, то это означает, что это не первая нагрузка; в противном случае, это так. Файл cookie будет создан в критическом файле JavaScript, который будет введен в шаблон с критическими стилями. Проверка файлов cookie будет осуществляться Express.

Назовем критический файл fastjs JavaScript. Мы должны быть в состоянии вставить содержимое fastjs файла макета, если файл файла не существует. Я нашел Handlebars частик быть довольно простым в использовании. Частичные полезны, когда у вас есть разметка, которую вы хотите повторно использовать в нескольких местах. Они могут быть вызваны другими шаблонами и в основном используются для заголовка, колонтитула, навигации и так далее.

В разделе Handlebars я определил каталог частик в /views/partials . Давайте создадим /views/partials/fastjs.handlebars файл. В этом файле мы добавим тег скрипта с идентификатором. fastjs Мы будем использовать этот идентификатор позже, чтобы удалить скрипт из DOM.

<script id='fastjs'>
</script>

Теперь, открыть /views/layouts/main.handlebars . Вызов частичного осуществляется через {{> partialName }} синтаксис. Этот код будет заменен на содержание нашей целевой части. Наш частичный fastjs назван, поэтому добавьте следующую строку до конца head тега:

<head>
…
{{> fastjs}}
</head>

Разметка на http://localhost:3000 теперь содержит содержимое fastjs частичного. Файлы cookie будут созданы с помощью этой простой функции JavaScript.

<script id='fastjs'>
// Let's create a cookie named 'fastweb', setting its value to 'cache' and its expiration to one day
createCookie('fastweb', 'cache', 1);

// function to create cookie
function createCookie(name,value,days) {
  var expires = "";
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  }
  document.cookie = name+"="+value+expires+"; path=/";
}
</script>

Вы можете проверить, что http://localhost:3000 содержит файл cookie с именем fastweb . Содержимое fastjs должно быть вставлено только в том случае, если файл cookie не существует. Чтобы определить это, мы должны проверить на стороне Express, существует ли он. Это легко сделать с cookie-parser пакетом npm и курьерским. Перейти к этому немного кода server.js в:

app.get('/', function(req, res){
  res.status(200).render('content');
});

renderФункция принимает во втором положении дополнительный объект, содержащий локальные переменные для представления. Мы можем передать переменную в представление следующим образом:

app.get('/', function(req, res){
  res.status(200).render('content', {needToRenderFast: true});
});

Теперь, на наш взгляд, мы можем распечатать needToRenderFast переменную, значение которой будет true . Мы хотим, чтобы значение этой переменной было установлено, true если имя файла cookie fastweb не существует. В противном случае переменная должна быть установлена на false . Использование, cookie-parser проверка существования cookie возможно с помощью этого простого кода:

//Check whether cookie named fastweb is set to a value of 'cache'
req.cookies.fastweb === 'cache'

И вот она переписана для наших нужд:

app.get('/', function(req, res){
  res.status(200).render('content', {
    needToRenderFast: !(req.cookies.fastweb === 'cache')
  });
});

Представление знает, основываясь на значении этой переменной, следует ли визуализировать критические файлы. Благодаря встроенным помощникам Handlebars, а именно if block помощнику, это также легко реализовать. Откройте файл макета и добавьте if помощника:

<head>
…
{{#if needToRenderFast}}
{{> fastjs}}
{{/if}}
</head>

Вуаля! fastjsСодержимое вставляется только в том случае, если файл cookie не существует.

Инъекционные критические CSS

Критический файл CSS должен быть вставлен одновременно с критическим файлом JavaScript. Во-первых, создать еще один частичный имени /views/partials/fastcss.handlebars . Содержимое этого fastcss файла просто:

<style id="fastcss">
  body{background:#E91E63;}
</style>

Просто импортировать его, как мы сделали fastjs частичное. Откройте файл макета:

<head>
…
{{#if needToRenderFast}}
{{> fastcss}}
{{> fastjs}}
{{/if}}
</head>

Обработка загрузки расслоения CSS

Беда в том, что, даже несмотря на то, что пакет CSS загрузился, критические частичные все еще остаются в DOM. К счастью, это легко исправить. Разметка нашего макета выглядит следующим образом:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Critical-Path Performance Optimization</title>
    {{#if needToRenderFast}}
    <link rel="stylesheet" href="assets/css/bundle.css" id="cssbundle" media="none"/>
    {{> fastcss}}
    {{> fastjs}}
    {{/if}}
  </head>
  <body>
  </body>
</html>

Наши, fastjs fastcss и CSS расслоение имеют свои собственные идентиматы. Мы можем этим воспользоваться. Откройте fastjs частичное и найти ссылки на эти элементы.

var cssBundle = document.getElementById('cssbundle'),
fastCss = document.getElementById('fastcss'),
fastJs = document.getElementById('fastjs');

Мы хотим, чтобы нас уведомили при загрузке пакета CSS. Это возможно с помощью слушателя события:

cssBundle.addEventListener('load', handleFastcss);

handleFastcssФункция будет вызываться сразу после загрузки пакета CSS. В этот момент мы хотим распространять стили из расслоения CSS, удалять #fastjs #fastcss элементы и создавать файлы cookie. Как уже упоминалось в начале этой статьи, стили из расслоения CSS будут распространяться путем изменения media атрибута расслоения CSS на допустимое значение — в нашем случае, значение all .

function handleFastcss() {
  cssBundle.setAttribute('media', 'all');
}

Теперь просто удалите #fastjs #fastcss элементы:

function handleFastcss() {
  cssBundle.setAttribute('media', 'all');
  fastCss.parentNode.removeChild(fastCss);
  fastJs.parentNode.removeChild(fastJs);
}

И вызов createCookie функции внутри handleFastcss функции.

function handleFastcss() {
  createCookie('fastweb', 'cache', 1);
  cssBundle.setAttribute('media', 'all');
  fastCss.parentNode.removeChild(fastCss);
  fastJs.parentNode.removeChild(fastJs);
}

Наш последний fastjs сценарий:

<script id='fastjs'>
var cssBundle = document.getElementById('cssbundle'),
fastCss =  document.getElementById('fastcss'),
fastJs =  document.getElementById('fastjs');

cssBundle.addEventListener('load', handleFastcss);

function handleFastcss() {
  createCookie('fastweb', 'cache', 1);
  cssBundle.setAttribute('media', 'all');
  fastCss.parentNode.removeChild(fastCss);
  fastJs.parentNode.removeChild(fastJs);
}
function createCookie(name,value,days) {
  var expires = "";
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  }
  document.cookie = name+"="+value+expires+"; path=/";
}
</script>

Обратите внимание, что этот обработчик нагрузки CSS работает только на стороне клиента. Если JavaScript на стороне клиента отключен, он будет продолжать использовать стили в fastcss .

Обработка второй и N-й нагрузки

Первая нагрузка теперь ведет себя так, как ожидалось. Но когда мы перезагружаем страницу в браузере, она остается без стилей. Это потому, что мы имели дело только со сценарием, в котором файл cookie не существует. Если файл cookie существует, пакет CSS должен быть связан стандартным способом.

Отоверьте файл макета:

<head>
  …
  {{#if needToRenderFast}}
  <link rel="stylesheet" href="assets/css/bundle.css" id="cssbundle" media="none"/>
  {{> fastcss}}
  {{> fastjs}}
  {{else}}
  <link rel="stylesheet" href="assets/css/bundle.css" id="cssbundle" media="all"/>
  {{/if}}
</head>

Сохраните его и просмотрите результат.

Результат

На GIF ниже показана первая нагрузка. Как вы можете видеть, в то время как csS расслоение загрузки, страница имеет другой фон. Это вызвано стилями в fastcss частичном. Файлы cookie создаются, и bundle.css запрос заканчивается статусом«200 OK».

Оптимизация производительности критических путей: первая нагрузка

Как вы помните, наша первая цель состоит в том, чтобы определить, является ли нагрузка первой. На основе этого мы можем решить, обслуживать ли критические стили или расслоение CSS из кэша браузера. Мы будем использовать печенье для этого. Если настроено файл cookie, то это означает, что это не первая нагрузка; в противном случае, это так. Файл cookie будет создан в критическом файле JavaScript, который будет введен в шаблон с критическими стилями. Проверка файлов cookie будет осуществляться Express.

Назовем критический файл fastjs JavaScript. Мы должны быть в состоянии вставить содержимое fastjs файла макета, если файл файла не существует. Я нашел Handlebars частик быть довольно простым в использовании. Частичные полезны, когда у вас есть разметка, которую вы хотите повторно использовать в нескольких местах. Они могут быть вызваны другими шаблонами и в основном используются для заголовка, колонтитула, навигации и так далее.

В разделе Handlebars я определил каталог частик в /views/partials . Давайте создадим /views/partials/fastjs.handlebars файл. В этом файле мы добавим тег скрипта с идентификатором. fastjs Мы будем использовать этот идентификатор позже, чтобы удалить скрипт из DOM.

<script id='fastjs'>
</script>

Теперь, открыть /views/layouts/main.handlebars . Вызов частичного осуществляется через {{> partialName }} синтаксис. Этот код будет заменен на содержание нашей целевой части. Наш частичный fastjs назван, поэтому добавьте следующую строку до конца head тега:

<head>
…
{{> fastjs}}
</head>

Разметка на http://localhost:3000 теперь содержит содержимое fastjs частичного. Файлы cookie будут созданы с помощью этой простой функции JavaScript.

<script id='fastjs'>
// Let's create a cookie named 'fastweb', setting its value to 'cache' and its expiration to one day
createCookie('fastweb', 'cache', 1);

// function to create cookie
function createCookie(name,value,days) {
  var expires = "";
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  }
  document.cookie = name+"="+value+expires+"; path=/";
}
</script>

Вы можете проверить, что http://localhost:3000 содержит файл cookie с именем fastweb . Содержимое fastjs должно быть вставлено только в том случае, если файл cookie не существует. Чтобы определить это, мы должны проверить на стороне Express, существует ли он. Это легко сделать с cookie-parser пакетом npm и курьерским. Перейти к этому немного кода server.js в:

app.get('/', function(req, res){
  res.status(200).render('content');
});

renderФункция принимает во втором положении дополнительный объект, содержащий локальные переменные для представления. Мы можем передать переменную в представление следующим образом:

app.get('/', function(req, res){
  res.status(200).render('content', {needToRenderFast: true});
});

Теперь, на наш взгляд, мы можем распечатать needToRenderFast переменную, значение которой будет true . Мы хотим, чтобы значение этой переменной было установлено, true если имя файла cookie fastweb не существует. В противном случае переменная должна быть установлена на false . Использование, cookie-parser проверка существования cookie возможно с помощью этого простого кода:

//Check whether cookie named fastweb is set to a value of 'cache'
req.cookies.fastweb === 'cache'

И вот она переписана для наших нужд:

app.get('/', function(req, res){
  res.status(200).render('content', {
    needToRenderFast: !(req.cookies.fastweb === 'cache')
  });
});

Представление знает, основываясь на значении этой переменной, следует ли визуализировать критические файлы. Благодаря встроенным помощникам Handlebars, а именно if block помощнику, это также легко реализовать. Откройте файл макета и добавьте if помощника:

<head>
…
{{#if needToRenderFast}}
{{> fastjs}}
{{/if}}
</head>

Вуаля! fastjsСодержимое вставляется только в том случае, если файл cookie не существует.

Инъекционные критические CSS

Критический файл CSS должен быть вставлен одновременно с критическим файлом JavaScript. Во-первых, создать еще один частичный имени /views/partials/fastcss.handlebars . Содержимое этого fastcss файла просто:

<style id="fastcss">
  body{background:#E91E63;}
</style>

Просто импортировать его, как мы сделали fastjs частичное. Откройте файл макета:

<head>
…
{{#if needToRenderFast}}
{{> fastcss}}
{{> fastjs}}
{{/if}}
</head>

Обработка загрузки расслоения CSS

Беда в том, что, даже несмотря на то, что пакет CSS загрузился, критические частичные все еще остаются в DOM. К счастью, это легко исправить. Разметка нашего макета выглядит следующим образом:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Critical-Path Performance Optimization</title>
    {{#if needToRenderFast}}
    <link rel="stylesheet" href="assets/css/bundle.css" id="cssbundle" media="none"/>
    {{> fastcss}}
    {{> fastjs}}
    {{/if}}
  </head>
  <body>
  </body>
</html>

Наши, fastjs fastcss и CSS расслоение имеют свои собственные идентиматы. Мы можем этим воспользоваться. Откройте fastjs частичное и найти ссылки на эти элементы.

var cssBundle = document.getElementById('cssbundle'),
fastCss = document.getElementById('fastcss'),
fastJs = document.getElementById('fastjs');

Мы хотим, чтобы нас уведомили при загрузке пакета CSS. Это возможно с помощью слушателя события:

cssBundle.addEventListener('load', handleFastcss);

handleFastcssФункция будет вызываться сразу после загрузки пакета CSS. В этот момент мы хотим распространять стили из расслоения CSS, удалять #fastjs #fastcss элементы и создавать файлы cookie. Как уже упоминалось в начале этой статьи, стили из расслоения CSS будут распространяться путем изменения media атрибута расслоения CSS на допустимое значение — в нашем случае, значение all .

function handleFastcss() {
  cssBundle.setAttribute('media', 'all');
}

Теперь просто удалите #fastjs #fastcss элементы:

function handleFastcss() {
  cssBundle.setAttribute('media', 'all');
  fastCss.parentNode.removeChild(fastCss);
  fastJs.parentNode.removeChild(fastJs);
}

И вызов createCookie функции внутри handleFastcss функции.

function handleFastcss() {
  createCookie('fastweb', 'cache', 1);
  cssBundle.setAttribute('media', 'all');
  fastCss.parentNode.removeChild(fastCss);
  fastJs.parentNode.removeChild(fastJs);
}

Наш последний fastjs сценарий:

<script id='fastjs'>
var cssBundle = document.getElementById('cssbundle'),
fastCss =  document.getElementById('fastcss'),
fastJs =  document.getElementById('fastjs');

cssBundle.addEventListener('load', handleFastcss);

function handleFastcss() {
  createCookie('fastweb', 'cache', 1);
  cssBundle.setAttribute('media', 'all');
  fastCss.parentNode.removeChild(fastCss);
  fastJs.parentNode.removeChild(fastJs);
}
function createCookie(name,value,days) {
  var expires = "";
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  }
  document.cookie = name+"="+value+expires+"; path=/";
}
</script>

Обратите внимание, что этот обработчик нагрузки CSS работает только на стороне клиента. Если JavaScript на стороне клиента отключен, он будет продолжать использовать стили в fastcss .

Обработка второй и N-й нагрузки

Первая нагрузка теперь ведет себя так, как ожидалось. Но когда мы перезагружаем страницу в браузере, она остается без стилей. Это потому, что мы имели дело только со сценарием, в котором файл cookie не существует. Если файл cookie существует, пакет CSS должен быть связан стандартным способом.

Отоверьте файл макета:

<head>
  …
  {{#if needToRenderFast}}
  <link rel="stylesheet" href="assets/css/bundle.css" id="cssbundle" media="none"/>
  {{> fastcss}}
  {{> fastjs}}
  {{else}}
  <link rel="stylesheet" href="assets/css/bundle.css" id="cssbundle" media="all"/>
  {{/if}}
</head>

Сохраните его и просмотрите результат.

Результат

На GIF ниже показана первая нагрузка. Как вы можете видеть, в то время как csS расслоение загрузки, страница имеет другой фон. Это вызвано стилями в fastcss частичном. Файлы cookie создаются, и bundle.css запрос заканчивается статусом«200 OK».

Оптимизация производительности критических путей: первая нагрузка

Второй GIF показывает сценарий перезагрузки. Файлы cookie уже созданы, критические файлы игнорируются, а bundle.css запрос заканчивается состоянием«304 Не изменен».

Оптимизация производительности критических путей: вторая и n-я нагрузка

Заключение

Мы прошли через весь жизненный цикл, показанный в схеме выше. В качестве следующего шага убедитесь, что все запросы на скрипты, изображения, шрифты и так далее являются асинхронными и не блокируют рендеринг. Кроме того, не забудьте включить сжатие гзип на сервере; хороший Экспресс промежуточное программное обеспечение доступно для этого.

Lifecycle of critical path performance optimization
Цикл оптимизации производительности критического пути(просмотр большой версии)

Источник: smashingmagazine.com

Великолепный Журнал

Великолепный, сокрушительный, разящий (см. перевод smashing) независимый журнал о веб-разработке. Основан в 2006 году в Германии. Имеет няшный дизайн и кучу крутых авторов, которых читают 2 млн человек в месяц.

Добавить комментарий

%d такие блоггеры, как: