Долгая загрузка сайта

260
22 февраля 2017, 20:26

Сижу на хостинге, и у некоторых пользователей очень долгая загрузка сайта. Разбирались, и нашли почему такая проблема, но не нашли решения.

На сайт подключается стиль стандартным способом:

<link rel="stylesheet" href="/css/style.css">

В стиле всего 79 строчек, но самую большую нагрузку в стилемов файле беру изображения:

background: url(../images/bg.jpg);

И вот каждая картинка грузит около 3-5 секунд (весом 900кб).

Не понимаем, с чем связана эта проблема, у 95% пользователей все окей, а у остальных 5% - такая вот беда...

При прямом открытии картинки по URL, эту картинку грузит все равно те же 5 секунд, а остальные - шустро (200мс в среднем).

В какую сторону стоит копать в такой ситуации?

Answer 1

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

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

В вашем случае кроме сжатия стилей и скриптов посоветую сжимать и графику. К примеру, картинки можно легко сжать без потери качества только за счет удаление 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 2

Сами ответили на свой же вопрос. У одних хорошо, у других плохо. Зависит от скорости приёма клиентов, и от скорости отдачи веб-сервера. Чем дальше от сервера, тем хуже прием. Чем меньше скорость приёма, тем медленнее скорость загрузки.

Принцип подгрузки больших элементов прост - сначала загружайте всё то, что сформирует страницу предельно быстро - основные стили, основной каркас, минимальные иконки. А вот большие уже элементы, к примеру Ваш фон, подгружайте отдельным стилем, к примеру асинхронно (jQuery), тогда и клиент быстрее увидит страницу, а там уже и картинки подгрузятся.

READ ALSO
Растянуть 2 div&#39;a по ширине

Растянуть 2 div'a по ширине

Задача таковаЕсть контейнер с фиксированой шириной

243
Обязательно ли класть кнопку отправки в форму?

Обязательно ли класть кнопку отправки в форму?

Подскажите пожалуйста обязательно ли класть <button> для отправки в тег <form> Например если я ее вытяну за приделы формы ее можно будет в дальнейшем...

250
Добавление элемента Select Options JQuery

Добавление элемента Select Options JQuery

Имеется ComboBox при выборе который передаёт полученные значения из базы при помощи ajax во второй ComboBox, когда приходит 1 значение все отображается...

274
Выравнивание блоков по высоте CSS/jQuery

Выравнивание блоков по высоте CSS/jQuery

Здравствуйте, верстая одну из страниц сайта,столкнулся з проблемой выравнивания блока по выcотеЕсть три блока

294