街撮りchの中のひとのブログ

webpack+spritesmithでページの高速化

目次

ページの表示を高速化しようとしたら手法はいろいろあるけどフロントエンドエンジニアができることのひとつに画像のスプライト化ってのがある。
たくさんの画像ファイルをサーバーへリクエストして表示ってのをやるとサーバーの負荷になる。 負荷になると応答が遅くなる。こういうことからリクエスト数を減らせば表示の高速化が見込まれたりするので少しでも快適にページを観てもらおうと思えばやったほうがいい。

https://compass-style.org/
で、ソシャゲーとか作ってるとアクセスは多いし負荷となる処理も多いのでスプライト化は必須ってことが多いんだけど以前はCompassを使ってやるのが一般的だった。
けどCompassがさすがに2年くらい放置(更新されない)されているので仕様がいろいろ古い感じがするし単純にメンテナンスされてないことに不安をがあったりするのでできれば使うのを避けたい。
そうなるとSassを使うにしろPostCSSを使うにしろこれらのフレームワークは画像をスプライト化するような仕組みは持ってないのでCompassでやっていたスプライト画像化を何かしら代替した方法方法でやらないといけない。
いくつかあるらしいんだけど無難なのはspritesmithかなってことで採用してやってみた。

https://github.com/Ensighten/spritesmith

いつものごとくwebpackから使いたいってことでwebpack-spritesmithです。

https://github.com/mixtur/webpack-spritesmith

webpackのpluginとして使えるようになるwebpack-spritesmithを使った。
ファイル構成としてはこんな感じです。
appの直下がドキュメントルート。 Sassを使ってます。 src/images/sprite_assetsのなかにいれたpng画像は残らずスプライト化します。
app/images/sprite.pngがスプライト化された後の画像。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
├── app
│   ├── images
│   │   └── sprite.png
│   └── styles
│   └── bundle.css
├── node_modules
├── package.json
├── src
│   ├── images
│   │   └── sprite_assets
│   │   ├── sprite01.png
│   │   ├── sprite02.png
│   │   └── sprite03.png
│   └── scss
│   ├── _sprite.scss
│   └── style.scss
└── webpack.config.js

package.jsonの中はこんな感じ。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"name": "01",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "webpack -w --config webpack.config.js"
},
"repository": {},
"license": "MIT",
"devDependencies": {
"browser-sync": "^2.18.6",
"browser-sync-webpack-plugin": "^1.1.3",
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "^1.0.1",
"node-sass": "^4.4.0",
"path": "^0.12.7",
"sass-loader": "^4.1.1",
"style-loader": "^0.13.1",
"webpack": "^1.14.0",
"webpack-spritesmith": "^0.3.1"
}
}

サーバーはBrowserSyncの機能を使ってます。 src/scss/styles.scssからimportしやすいように同じ場所に_sprite.scssというファイルで出力します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
var path = require("path");
var webpack = require("webpack");
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var BrowserSyncPlugin = require('browser-sync-webpack-plugin');
var SpritesmithPlugin = require('webpack-spritesmith');

module.exports = {
entry: {
application: './src/scss/style.scss'
},
output: {
path: './app/styles',
filename: 'bundle.css'
},
module: {
loaders: [
{
test: /\.css|scss$/,
loader: ExtractTextPlugin.extract("style-loader", "css-loader?minimize!sass-loader")
},
{
test: /\.png$/,
loaders: ['file?name=i/[hash].[ext]']
}
]
},
resolve: {
modulesDirectories: ["web_modules", "node_modules", "sprite_assets"]
},
plugins: [
new ExtractTextPlugin('bundle.css'),
new BrowserSyncPlugin(
{
host: 'localhost',
port: 8081,
server: { baseDir: ['public'] }
}
),
new SpritesmithPlugin({
src: {
cwd: './src/images/sprite_assets/',
glob: '*.png'
},
target: {
image: './app/images/sprite.png',
css: './src/scss/_sprite.scss'
},
apiOptions: {
cssImageRef: "/images/sprite.png"
}
})
]
}

使うときはこんな感じでincludeして元のファイルは変数化されているのでそれを指定してやれば背景にスプライト化された画像が配置される。

1
2
3
.hoge {
@include sprite($sprite01);
}

スプライト化された画像全般に言えることだけど繰り返して表示するものは背景画像の位置を指定するものなどは向いてないので注意が必要だったりする。
次回は複数のスプライト画像を出力する方法やRetinaの場合はどうやったらいいのかなどを書きたいと思う。

いつもvブログを読んでいただきありがとうございます。
YouTubeチャンネルの運用を続けていくために機材購入、資料購入などで困っております。
よろしければAmazonの欲しいものリストから応援いただけると助かります。

街撮りchの欲しいものリスト

管理人:タケグチシゲキ

フロントエンドエンジニアとして働く55歳のジジイです。
首都圏を中心に散歩動画を撮影してYouTubeで配信してます。現在は夜の街のネオンや光が作り出す陰影が好きで撮影することが多いです。

YouTbueチャンネル

YouTubeチャンネルもぜひご覧ください。思い出の街や気になる街の風景を楽しんでいただければと思います

X(旧Twiiter)

X(旧Twiiter)でも情報発信しております。よろしければフォローいただけると嬉しいです

記事や動画について知っている情報を教えていただけると幸いです。どんなささいなことでも大丈夫です。

また、仕事依頼、コラボ依頼、著作物の提供などについてのお問い合わせは下記のお問い合わせフォーム、X(旧Twiiter)のDMでお待ちしております

お問い合わせ

ブログ記事やYouTubeチャンネルの動画に関するコメント、お仕事依頼、コラボ依頼、著作物の提供についてなどなどお問い合わせにて随時募集中です。
情報提供などもお待ちしております。

お問い合わせはこちらのGoogleフォームからお願いいたします