Как увеличить скорость работы сайта Front?

373
15 марта 2017, 17:57

На сайте backend отрабатывает за 50 мс, а фронт забирает кучу времени. В итоге полсекунды на отображение страницы с использованием кэша, без кэша 700 мс. Есть правила и способы увеличить скорость отображения?

Для бека используется Laravel.

Answer 1

Оптимизация js одна из острых тем. Что Вы можете сделать:

1) Вы можете использовать встроенный профилировщик хрома http://prntscr.com/ejumdm и проанализировать какой скрипт/метод у Вас больше всего загружается и оптимизировать.

1.1) Есть например гугловский механизм PageSpead

2) Минимизация скриптов. По хорошему Вы можете минимизировать скрипты и стили с помощью инструментов для сборки grunt, gulp .

3) Если даже минимизация не помогает. Можно использовать AMD для асинхронной загрузки модулей. Для этого можно использовать, например, webpack

Answer 2

Я бы посоветовал вам оптимизировать весь статический контент на сайте.

Сжатие графики

В вашем случае кроме сжатия стилей и скриптов посоветую сжимать и графику. К примеру, картинки можно легко сжать без потери качества только за счет удаление exif-данных. На реальном сайте можно сократить размер картинок в среднем на 70%, что на современном сайте равняется примерно 4 МБ. Пример на gulp:

var
    gulp = require('gulp'),
    imagemin = require('gulp-imagemin'),
    imageminJR = require('imagemin-jpeg-recompress'),
    imageminSvgo = require('imagemin-svgo');
// Optimizing images
gulp.task('imagemin', function() {
    gulp.src('./img/**/*')
        .pipe(imagemin([
            imageminJR({
                method: 'ms-ssim'
            }),
            imageminSvgo({
                plugins: [
                    {removeViewBox: false}
                ]
            })
        ]))
        .pipe(gulp.dest('./public/img/'))
});

А для браузеров, которые понимают легковесный формат webp (формат разработан Google), можно сделать еще такой вариант изображений:

var
    gulp = require('gulp'),
    webp = require('gulp-webp');
// Generate Webp
gulp.task('webp', function() {
    gulp.src('./img/**/*')
        .pipe(webp())
        .pipe(gulp.dest('./public/img/'))
});

Оптимизация скриптов

Сперва объедините все скрипты в один файл и минифицируйте их. Это помет сократить количество HTTP-запросов и размер файлов:

var
    gulp = require('gulp'),
    concat = require('gulp-concat'),
    uglify = require('gulp-uglify');
// Concat JS
gulp.task('js', function(){
    gulp.src([
        './js/jquery.js',
        './js/wow.js',
        './js/menu.js',
        './js/scrollspy.js',
        './js/main.js',
        './js/temp/contact.bundled.js',
        './js/owl.carousel.js'
    ])
        .pipe(concat('script.js'))
        .pipe(uglify())
        .pipe(gulp.dest('./public/js/'))
});

Оптимизация стилей

Кроме обычной минификации стилей можно использовать и продвинутую - объединять дубликаты классов и @media. Пример на gulp из моего [web-starter-kit][1]:

var
    gulp = require('gulp'),
    stylus = require('gulp-stylus'),
    // Минифицирует CSS, объединяет классы. Не ломает CSS, в отличие от cssnano, который, к примеру, может неправильно выставлять z-index
    csso = require('gulp-csso'),
    // Объединяет все @media
    cmq = require('gulp-combine-mq'),
    // Сокращает CSS-селекторы    
    gs = require('gulp-selectors'),
    // Проставляет вендорные префиксы
    autoprefixer = require('gulp-autoprefixer'),
    livereload = require('gulp-livereload'),
    nib = require('nib');
// Compiling Stylus in CSS
gulp.task('css', function() {
    gulp.src('./styl/*.styl')
        .pipe(stylus({
            use: nib()
        }))
        .pipe(cmq())
        .pipe(csso())
        .pipe(autoprefixer('last 3 versions'))
        .pipe(gulp.dest('./public/css/'))
});

А если совсем делать нечего, то можно еще и селекторы сократить:

// Minify selectors
    gulp.task('gs', function() {
        var ignores = {
            classes: ['active', 'menu', 'nav', 'slide', 'error', 'form-control', 'loader', 'showLoader', 'fadeLoader', 'webp', 'wow', 'owl-*', 'i-*'],
            ids: '*'
        };
        gulp.src(['./public/**/*.css', './public/**/*.html'])
            .pipe(gs.run({}, ignores))
            .pipe(gulp.dest('./public/'))
    });

Кстати, наверняка у вас есть классы, добавляющиеся через JS, поэтому предварительно стоит все такие классы вынести в переменную ignores.

Кеширование статики на стороне пользователя

Также бы посоветовал кешировать скрипты и стили на стороне пользователя, чтобы исключить их повторную загрузку, если они не изменились:

<FilesMatch ".(flv|gif|jpg|jpeg|png|ico|svg|swf|js|css|pdf|woff2|woff|ttf|eot)$">
  Header set Cache-Control "max-age=2592000"
</FilesMatch>

И включить gzip сжатие на сервере:

# сжатие text, html, javascript, css, xml:
<ifModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript
</ifModule>
Answer 3

Детали конкретно вашего случая вам надо смотреть в DevTools / Timeline и пользоваться каждым из методов с оглядкой туда, потому что общие советы по оптимизации в конкретном случае могут только навредить. К советам выше могу добавить следующие:

  • Посмотреть в таймлайне детали вашего critical rendering path. Постараться его максимально сократить:

    1. Убрать с него блокирующий CSS. Выделить, например, при помощи critical стили для первого экрана и поместить их инлайном в <head><style>. Остальной CSS загружать асинхронно при помощи loadCSS.
    2. Скрипты загружать с атрибутом defer / async.
  • Активно использовать <link rel="preload"> — в современных браузерах прирост в скорости весьма значительный, но использовать его надо с умом и таймлайном.

  • Изображения готовить в нескольких размерах и использовать тег <picture>; отдавать изображения в формате WebP браузерам, которые его могут читать при помощи этого же тега.

    1. Не инлайнить изображения, пропущенные через base64-декодер (в CSS тоже).
    2. Если изображений много, то загружать их «лениво», например, при помощи lazysizes (хорошо дружит с <picture>).
    3. Если есть тяжелые PNG, в которых используется прозрачность, посмотреть в сторону конвертирования такого PNG в JPG + SVG.
  • Если используются кастомные шрифты, то их также рекомендую загружать асинхронно, например, при помощи fontfaceobserver.

Источники:

Статья об оптимизации вообще: https://dev.to/sanjsanj/optimising-the-front-end-for-thebrowser

О <link rel="preload"> https://medium.com/reloading/a-link-rel-preload-analysis-from-the-chrome-data-saver-team-5edf54b08715

WebP https://css-tricks.com/using-webp-images/

Base64 https://csswizardry.com/2017/02/base64-encoding-and-performance/, https://csswizardry.com/2017/02/base64-encoding-and-performance-part-2/

PNG → JPG + SVG (Transparent JPG) https://css-tricks.com/transparent-jpg-svg/

READ ALSO
MySql использует весь ресурс процессора

MySql использует весь ресурс процессора

Сервер постоянно загружен почти на 100% Проблема возникает с запуском службы mysqlCPU на 80% загружает - /usr/sbin/mysql --basedir/var/lib/mysql --plugin-dir/usr/lib/mysql/plugin...

346
Сумма строк, имеющих одинаковое значений

Сумма строк, имеющих одинаковое значений

Есть таблица с даннымиКак мне получить сумму значений discount тех строк, где значения поля by_recomended одинаковые? (сумма по бобкову, докторову и т

275