Ver código fonte

ligthhouse优化

guoziyun 1 ano atrás
pai
commit
f23f508a78

+ 17 - 1
app.js

@@ -2,11 +2,11 @@ const express = require('express');
 const path = require('path');
 const app = express();
 const config = require('./config/app')
-
 const session = require('express-session');
 const RedisStore = require('connect-redis')(session);
 const cookieParser = require('cookie-parser');
 const bodyParser = require('body-parser');
+const compression = require('compression');
 const authChecker = require('./libs/auth/checker');
 
 app.set('trust proxy', 1) //trust first proxy, get ip
@@ -17,6 +17,22 @@ app.set('view engine', 'ejs');
 // 设置视图目录
 app.set('views', path.join(__dirname, 'views'));
 
+/**
+ * Check should compress.
+ */
+function shouldCompress(req, res) {
+  if (req.headers['x-no-compression']) {
+    // don't compress responses with this request header
+    return false
+  }
+  // fallback to standard filter function
+  return compression.filter(req, res)
+}
+
+app.use(compression({
+  filter: shouldCompress
+}));
+
 
 app.use(cookieParser());
 

BIN
dist/assets/icon/icon.webp


+ 6 - 0
dist/stylesheets/album.css

@@ -8,6 +8,12 @@
   align-items: center;
 }
 
+.album-header img {
+  width: 480px;
+  aspect-ratio: 2;
+  border-radius: 8px;
+}
+
 /* 响应式设计 */
 @media (max-width: 768px) {
   .album-header img {

+ 0 - 1
dist/stylesheets/header.css

@@ -8,7 +8,6 @@
 }
 
 .logo {
-  height: 42px;
   border: 1px solid #ddd;
   border-radius: 8px;
 }

+ 9 - 5
dist/stylesheets/styles.css

@@ -34,7 +34,6 @@ body {
 
 .content {
   margin-top: 20px;
-  font-family: Arial, sans-serif;
   display: flex;
   justify-content: center;
   align-items: center;
@@ -68,16 +67,21 @@ body {
 }
 
 .album-grid-card {
-  width: 100%;
-  height: auto;
   border: 1px solid #ccc;
   border-radius: 8px;
   box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
 }
 
-.album-grid-card img {
+.album-icon-img {
+  width: 100%;
+  aspect-ratio: 1;
+  cursor: pointer;
+  border-radius: 8px;
+}
+
+.album-cover-img {
   width: 100%;
-  height: auto;
+  aspect-ratio: 2;
   cursor: pointer;
   border-radius: 8px;
 }

+ 37 - 0
package-lock.json

@@ -13,6 +13,7 @@
         "bcryptjs": "^2.4.3",
         "bluebird": "^3.7.2",
         "body-parser": "^1.20.3",
+        "compression": "^1.8.0",
         "connect-redis": "^3.3.3",
         "cookie-parser": "^1.4.7",
         "date-fns": "^4.1.0",
@@ -584,6 +585,42 @@
         "simple-swizzle": "^0.2.2"
       }
     },
+    "node_modules/compressible": {
+      "version": "2.0.18",
+      "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+      "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+      "dependencies": {
+        "mime-db": ">= 1.43.0 < 2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/compression": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz",
+      "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==",
+      "dependencies": {
+        "bytes": "3.1.2",
+        "compressible": "~2.0.18",
+        "debug": "2.6.9",
+        "negotiator": "~0.6.4",
+        "on-headers": "~1.0.2",
+        "safe-buffer": "5.2.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/compression/node_modules/negotiator": {
+      "version": "0.6.4",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
+      "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",

+ 1 - 0
package.json

@@ -14,6 +14,7 @@
     "bcryptjs": "^2.4.3",
     "bluebird": "^3.7.2",
     "body-parser": "^1.20.3",
+    "compression": "^1.8.0",
     "connect-redis": "^3.3.3",
     "cookie-parser": "^1.4.7",
     "date-fns": "^4.1.0",

+ 63 - 41
routes/index.js

@@ -15,8 +15,8 @@ const { format } = require('date-fns');
 const { getListBuilder } = require('../libs/pager');
 
 const CACHE_PREFIX = "art_v1";
-// const CACHE_EXPIRES = 60; // 60s刷新一次
-const CACHE_EXPIRES = 3600; // 1小时刷新一次即可
+const CACHE_EXPIRES = 60; // 60s刷新一次
+// const CACHE_EXPIRES = 3600; // 1小时刷新一次即可
 
 const artSelect = 'name title desc width height date publishTime tags lastMod mystery hasSpecial useSpecialThumb publishVersion lock pageId';
 
@@ -64,7 +64,9 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) {  // 限制严格
       console.log(`${req.originalUrl} set cookie: lang=${lang}`);
     }
 
-    let cacheKey = `${CACHE_PREFIX}_home_${lang}`;
+    let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg';  // 浏览器支持webp就用webp
+
+    let cacheKey = `${CACHE_PREFIX}_home_${lang}_${imageType}`;
     let htmlData = await redis.getAsync(cacheKey);
     if (!htmlData) {
       let host = config.cdnHost ?? config.resHost;
@@ -80,7 +82,7 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) {  // 限制严格
         .exec();
       if (dailydocs && dailydocs.length >= 1) {
         todayDoc = dailydocs[0];
-        todayDoc.artInfo.thumb = `${host}/thumbs/coloring-page/page/480/${todayDoc.artInfo._id}.webp`;
+        todayDoc.artInfo.thumb = `${host}/thumbs/coloring-page/page/480/${todayDoc.artInfo._id}.${imageType}`;
       }
 
       let baseSort = { publishTime: 'desc' };
@@ -93,7 +95,7 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) {  // 限制严格
         .limit(12)
         .lean()
         .exec();
-      organizeData(latest, lang);
+      organizeData(latest, lang, imageType);
 
       // 热门精选
       let recommend = await models.Art
@@ -103,7 +105,7 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) {  // 限制严格
         .limit(12)
         .lean()
         .exec();
-      organizeData(recommend, lang);
+      organizeData(recommend, lang, imageType);
 
       // special 专区
       let special = await models.Art
@@ -113,7 +115,7 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) {  // 限制严格
         .limit(12)
         .lean()
         .exec();
-      organizeData(special, lang);
+      organizeData(special, lang, imageType);
 
       // 专辑
       let albums = await models.ArtAlbum
@@ -127,8 +129,8 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) {  // 限制严格
         .exec();
 
       for (let doc of albums) {
-        doc.icon = `${host}/thumbs/coloring-page/album_icon/320/${doc._id}.webp`;
-        doc.cover = `${host}/thumbs/coloring-page/album_cover/320/${doc._id}.webp`;
+        doc.icon = `${host}/thumbs/coloring-page/album_icon/320/${doc._id}.${imageType}`;
+        doc.cover = `${host}/thumbs/coloring-page/album_cover/480/${doc._id}.${imageType}`;
         doc.title = doc.title ? doc.title[lang] : '';
         doc.slogon = doc.slogon ? doc.slogon[lang] : '';
         doc.size = doc.contents.length;
@@ -166,7 +168,7 @@ router.get(/^\/(en|zh|es|pt|ja)$/, function (req, res, next) {  // 限制严格
       ]);
 
       for (let doc of designers) {
-        doc.avatar = `/thumbs/v1/avatar/320/${doc._id}.webp`;
+        doc.avatar = `/thumbs/v1/avatar/320/${doc._id}.${imageType}`;
       }
 
 
@@ -233,8 +235,9 @@ router.get('/:lang/category/:tag?', function (req, res, next) {
     let tag = req.params.tag;
     if (!tag) tag = 'latest';
 
+    let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg';  // 浏览器支持webp就用webp
 
-    let cacheKey = `${CACHE_PREFIX}_category_${tag}_${lang}`;
+    let cacheKey = `${CACHE_PREFIX}_category_${tag}_${lang}_${imageType}`;
     let htmlData = await redis.getAsync(cacheKey);
     if (!htmlData) {
 
@@ -248,7 +251,7 @@ router.get('/:lang/category/:tag?', function (req, res, next) {
       }
 
       let result = await getListBuilder(query, models.Art);
-      organizeData(result.data, lang);
+      organizeData(result.data, lang, imageType);
 
       let data = {
         title: meta.categoryTitle[lang],
@@ -305,7 +308,9 @@ router.get('/:lang/tag/:tag?', function (req, res, next) {
     let tag = req.params.tag;
     if (!tag) tag = 'latest';
 
-    let cacheKey = `${CACHE_PREFIX}_tag_${tag}_${lang}`;
+    let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg';  // 浏览器支持webp就用webp
+
+    let cacheKey = `${CACHE_PREFIX}_tag_${tag}_${lang}_${imageType}`;
     let htmlData = await redis.getAsync(cacheKey);
     if (!htmlData) {
       let query = {
@@ -319,7 +324,7 @@ router.get('/:lang/tag/:tag?', function (req, res, next) {
       }
 
       let result = await getListBuilder(query, models.Art);
-      organizeData(result.data, lang);
+      organizeData(result.data, lang, imageType);
 
       let data = {
         title: meta.tagTitle[lang],
@@ -374,9 +379,11 @@ router.get('/:lang/search', function (req, res, next) {
       res.cookie('lang', lang, config.cookie);
     }
 
+    let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg';  // 浏览器支持webp就用webp
+
     let search = req.query.search;
 
-    let cacheKey = `${CACHE_PREFIX}_search_${search}_${lang}`;
+    let cacheKey = `${CACHE_PREFIX}_search_${search}_${lang}_${imageType}`;
     let htmlData = await redis.getAsync(cacheKey);
     if (!htmlData) {
       let query = {
@@ -390,7 +397,7 @@ router.get('/:lang/search', function (req, res, next) {
       }
 
       let result = await getListBuilder(query, models.Art);
-      organizeData(result.data, lang);
+      organizeData(result.data, lang, imageType);
 
       let data = {
         title: meta.searchTitle[lang],
@@ -442,7 +449,9 @@ router.get('/:lang/special', function (req, res, next) {
       res.cookie('lang', lang, config.cookie);
     }
 
-    let cacheKey = `${CACHE_PREFIX}_special_${lang}`;
+    let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg';  // 浏览器支持webp就用webp
+
+    let cacheKey = `${CACHE_PREFIX}_special_${lang}_${imageType}`;
     let htmlData = await redis.getAsync(cacheKey);
     if (!htmlData) {
       let query = {
@@ -458,7 +467,7 @@ router.get('/:lang/special', function (req, res, next) {
       }
 
       let result = await getListBuilder(query, models.Art);
-      organizeData(result.data, lang);
+      organizeData(result.data, lang, imageType);
 
       let data = {
         title: meta.specialTitle[lang],
@@ -509,7 +518,9 @@ router.get('/:lang/albums', function (req, res, next) {
       res.cookie('lang', lang, { maxAge: 900000, httpOnly: true });
     }
 
-    let cacheKey = `${CACHE_PREFIX}_albums_${lang}`;
+    let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg';  // 浏览器支持webp就用webp
+
+    let cacheKey = `${CACHE_PREFIX}_albums_${lang}_${imageType}`;
     let htmlData = await redis.getAsync(cacheKey);
     if (!htmlData) {
       // 专辑
@@ -524,8 +535,8 @@ router.get('/:lang/albums', function (req, res, next) {
 
       let host = config.cdnHost ?? config.resHost;
       for (let doc of albums) {
-        doc.icon = `${host}/thumbs/coloring-page/album_icon/320/${doc._id}.webp`;
-        doc.cover = `${host}/thumbs/coloring-page/album_cover/480/${doc._id}.webp`;
+        doc.icon = `${host}/thumbs/coloring-page/album_icon/320/${doc._id}.${imageType}`;
+        doc.cover = `${host}/thumbs/coloring-page/album_cover/480/${doc._id}.${imageType}`;
         doc.title = doc.title ? doc.title[lang] : '';
         doc.slogon = doc.slogon ? doc.slogon[lang] : '';
         doc.size = doc.contents.length;
@@ -580,7 +591,9 @@ router.get('/:lang/album/:id', function (req, res, next) {
     let id = req.params.id;
     utils.validators.validateId(id);
 
-    let cacheKey = `${CACHE_PREFIX}_album_${id}_${lang}`;
+    let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg';  // 浏览器支持webp就用webp
+
+    let cacheKey = `${CACHE_PREFIX}_album_${id}_${lang}_${imageType}`;
     let htmlData = await redis.getAsync(cacheKey);
     if (!htmlData) {
       // 专辑
@@ -596,13 +609,13 @@ router.get('/:lang/album/:id', function (req, res, next) {
       if (!doc) throw createError(404, 'Album Not Found!');
 
       let host = config.cdnHost ?? config.resHost;
-      doc.icon = `${host}/thumbs/coloring-page/album_icon/320/${doc._id}.webp`;
-      doc.cover = `${host}/thumbs/coloring-page/album_cover/640/${doc._id}.webp`;
+      doc.icon = `${host}/thumbs/coloring-page/album_icon/320/${doc._id}.${imageType}`;
+      doc.cover = `${host}/thumbs/coloring-page/album_cover/480/${doc._id}.${imageType}`;
       doc.title = doc.title ? doc.title[lang] : '';
       doc.slogon = doc.slogon ? doc.slogon[lang] : '';
       doc.size = doc.contents.length;
 
-      organizeData(doc.contents, lang);
+      organizeData(doc.contents, lang, imageType);
 
 
       let data = {
@@ -650,7 +663,9 @@ router.get('/:lang/designers', function (req, res, next) {
       res.cookie('lang', lang, config.cookie);
     }
 
-    let cacheKey = `${CACHE_PREFIX}_designers_${lang}`;
+    let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg';  // 浏览器支持webp就用webp
+
+    let cacheKey = `${CACHE_PREFIX}_designers_${lang}_${imageType}`;
     let htmlData = await redis.getAsync(cacheKey);
     if (!htmlData) {
       let docs = await models.Art.aggregate([
@@ -686,7 +701,7 @@ router.get('/:lang/designers', function (req, res, next) {
 
 
       for (let doc of docs) {
-        doc.avatar = `/thumbs/v1/avatar/320/${doc._id}.webp`;
+        doc.avatar = `/thumbs/v1/avatar/320/${doc._id}.${imageType}`;
       }
 
       let data = {
@@ -739,14 +754,16 @@ router.get('/:lang/designer/:id', function (req, res, next) {
     let id = req.params.id;
     utils.validators.validateId(id);
 
-    let cacheKey = `${CACHE_PREFIX}_designer_${id}_${lang}`;
+    let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg';  // 浏览器支持webp就用webp
+
+    let cacheKey = `${CACHE_PREFIX}_designer_${id}_${lang}_${imageType}`;
     let htmlData = await redis.getAsync(cacheKey);
     if (!htmlData) {
       let user = await models.User.findById(id).select('name username');
       if (!user) throw createError(404, 'User Not Found!');
       let count = await models.Art.countDocuments({ user: id, status: 9000 });
       user.count = count;
-      user.avatar = `/thumbs/v1/avatar/320/${user._id}.webp`;
+      user.avatar = `/thumbs/v1/avatar/320/${user._id}.${imageType}`;
 
 
       // find user arts
@@ -762,7 +779,7 @@ router.get('/:lang/designer/:id', function (req, res, next) {
       }
 
       let result = await getListBuilder(query, models.Art);
-      organizeData(result.data, lang);
+      organizeData(result.data, lang, imageType);
 
 
       let data = {
@@ -832,7 +849,9 @@ router.get('/:lang/coloring-page/:str', function (req, res, next) {
     let id = getRealId(str);
     utils.validators.validateId(id);
 
-    let cacheKey = `${CACHE_PREFIX}_detail_${id}_${lang}`;
+    let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg';  // 浏览器支持webp就用webp
+
+    let cacheKey = `${CACHE_PREFIX}_detail_${id}_${lang}_${imageType}`;
     let htmlData = await redis.getAsync(cacheKey);
     if (!htmlData) {
       let doc = await models.Art
@@ -843,7 +862,7 @@ router.get('/:lang/coloring-page/:str', function (req, res, next) {
         .exec();
       if (!doc) throw createError(404, 'Art Not Found!');
 
-      organizeDetail(doc, lang);
+      organizeDetail(doc, lang, imageType);
 
       // find relate
       let tags = [...doc.tags];
@@ -861,7 +880,7 @@ router.get('/:lang/coloring-page/:str', function (req, res, next) {
       }
 
       let result = await getListBuilder(query, models.Art);
-      organizeData(result.data, lang);
+      organizeData(result.data, lang, imageType);
 
 
       let data = {
@@ -919,7 +938,10 @@ router.get('/:lang/detail/:id', function (req, res, next) {
 
     let id = req.params.id;
     utils.validators.validateId(id);
-    let cacheKey = `${CACHE_PREFIX}_detail_${id}_${lang}`;
+
+    let imageType = req.headers.accept?.includes('image/webp') ? 'webp' : 'jpeg';  // 浏览器支持webp就用webp
+
+    let cacheKey = `${CACHE_PREFIX}_detail_${id}_${lang}_${imageType}`;
     let htmlData = await redis.getAsync(cacheKey);
     if (!htmlData) {
       let doc = await models.Art
@@ -930,7 +952,7 @@ router.get('/:lang/detail/:id', function (req, res, next) {
         .exec();
       if (!doc) throw createError(404, 'Art Not Found!');
 
-      organizeDetail(doc, lang);
+      organizeDetail(doc, lang, imageType);
 
       // find relate
       let tags = [...doc.tags];
@@ -948,7 +970,7 @@ router.get('/:lang/detail/:id', function (req, res, next) {
       }
 
       let result = await getListBuilder(query, models.Art);
-      organizeData(result.data, lang);
+      organizeData(result.data, lang, imageType);
 
       let data = {
         // title: `${doc.name.replace(/[_]+/g, '-')}`,
@@ -1083,13 +1105,13 @@ router.get('/:lang/info', function (req, res, next) {
 });
 
 
-const organizeData = (data, lang) => {
+const organizeData = (data, lang, imageType) => {
   data.forEach(doc => {
     let host = config.cdnHost ?? config.resHost;
     let publishVersion = doc.publishVersion || 0;
     let version = publishVersion + 1500;
 
-    doc.thumb = `${host}/thumbs/coloring-page/page/480/${doc._id}.webp`;
+    doc.thumb = `${host}/thumbs/coloring-page/page/480/${doc._id}.${imageType}`;
     doc.zip = `${host}/zips/v2/number_mini/${version}/${doc._id}.zip`;
 
     let uriTitle = doc.name;
@@ -1119,12 +1141,12 @@ const organizeData = (data, lang) => {
 }
 
 
-const organizeDetail = (doc, lang) => {
+const organizeDetail = (doc, lang, imageType) => {
   let host = config.cdnHost ?? config.resHost;
   let publishVersion = doc.publishVersion || 0;
   let version = publishVersion + 1500;
 
-  doc.thumb = `${host}/thumbs/coloring-page/page/480/${doc._id}.webp`;
+  doc.thumb = `${host}/thumbs/coloring-page/page/480/${doc._id}.${imageType}`;
   doc.zip = `${host}/zips/v2/number_mini/${version}/${doc._id}.zip`
 
   // doc.title = translate.titleTest[lang];
@@ -1157,7 +1179,7 @@ const organizeDetail = (doc, lang) => {
   let utf8name = encodeURIComponent(uriTitle.replace(/[\s_]+/g, '-')).toLowerCase();
   doc.uri = `/${lang}/coloring-page/${utf8name}-${doc._id}`;
 
-  doc.downlink = `${host}/thumbs/coloring-page/page/1200/${doc._id}.webp`;
+  doc.downlink = `${host}/thumbs/coloring-page/page/1200/${doc._id}.${imageType}`;
 
   delete doc.hasSpecial;
   delete doc.useSpecialThumb;

+ 17 - 9
views/album-section.ejs

@@ -1,20 +1,28 @@
-
 <div class="content-wrapper">
   <div class="content-title">
-    <div style="font-size: 20px; font-weight: bold;"><%= translate.selectAlbums[lang] %>:</div>
-    <a href="<%= lang %>/albums"><%= translate.more[lang] %> >>></a>
+    <div style="font-size: 20px; font-weight: bold;">
+      <%= translate.selectAlbums[lang] %>:
+    </div>
+    <a href="<%= lang %>/albums">
+      <%= translate.more[lang] %> >>>
+    </a>
   </div>
 
   <div class="content">
     <div class="album-icon-grid">
-        <% albums.forEach(album => { %>
-          <div class="album-grid-card">
-            <div style="padding: 2px; font-size: 14px; color: grey;"><%= translate.coloringPageAlbum[lang] %></div>
-            <a href="/<%= lang %>/album/<%= album._id %>"><img src="<%= album.icon %>" alt="<%= translate.coloringPageAlbum[lang] %>: <%= album.title %>" ></a>
-            <div style="padding: 2px; font-weight: bold;"><%= album.title %></div>
+      <% albums.forEach(album=> { %>
+        <div class="album-grid-card">
+          <div style="padding: 2px; font-size: 14px; color: grey;">
+            <%= translate.coloringPageAlbum[lang] %>
+          </div>
+          <a href="/<%= lang %>/album/<%= album._id %>"><img src="<%= album.icon %>" class="album-icon-img"
+              alt="<%= translate.coloringPageAlbum[lang] %>: <%= album.title %>"></a>
+          <div style="padding: 2px; font-weight: bold;">
+            <%= album.title %>
           </div>
+        </div>
         <% }); %>
     </div>
   </div>
 
-</div>
+</div>

+ 2 - 2
views/album.ejs

@@ -4,6 +4,7 @@
 <head>
   <%- include('common-meta') %>
     <link rel="stylesheet" href="/stylesheets/styles.css">
+    <link rel="stylesheet" href="/stylesheets/header.css">
     <link rel="stylesheet" href="/stylesheets/album.css">
 </head>
 <!-- Google tag (gtag.js) -->
@@ -23,8 +24,7 @@
       <h1 style="color: purple">
         <%= data.title %>
       </h1>
-      <img style="border-radius: 8px;" src="<%= data.cover %>"
-        alt="<%= data.title %> | <%= translate.coloringPageAlbum[lang] %>">
+      <img src="<%= data.cover %>" alt="<%= data.title %> | <%= translate.coloringPageAlbum[lang] %>">
       <div style="color: gray; font-size: 18px; padding: 10px">
         <%= data.slogon %>
       </div>

+ 3 - 2
views/albums.ejs

@@ -11,6 +11,7 @@
     <link rel="alternate" href="https://art.pcoloring.com/ja/albums" hrefLang="ja" />
 
     <link rel="stylesheet" href="/stylesheets/styles.css">
+    <link rel="stylesheet" href="/stylesheets/header.css">
 
 </head>
 <!-- Google tag (gtag.js) -->
@@ -34,9 +35,9 @@
       <div class="album-grid">
         <% data.forEach(album=> { %>
           <div class="album-grid-card">
-            <a href="/<%= lang %>/album/<%= album._id %>"><img src="<%= album.cover %>"
+            <a href="/<%= lang %>/album/<%= album._id %>"><img src="<%= album.cover %>" class="album-cover-img"
                 alt="<%= album.title %> | <%= translate.coloringPageAlbum[lang] %>"></a>
-            <div style="padding: 0px 0px 4px 4px">
+            <div style="padding: 0px 0px 4px 4px; font-size: 14px;">
               <%= album.title %>
             </div>
           </div>

+ 1 - 0
views/category.ejs

@@ -11,6 +11,7 @@
     <link rel="alternate" href="https://art.pcoloring.com/ja/category" hrefLang="ja" />
 
     <link rel="stylesheet" href="/stylesheets/styles.css">
+    <link rel="stylesheet" href="/stylesheets/header.css">
     <link rel="stylesheet" href="/stylesheets/category.css">
 </head>
 <!-- Google tag (gtag.js) -->

+ 1 - 1
views/designer-section.ejs

@@ -10,7 +10,7 @@
   <div class="container">
     <% designers.forEach(item=> { %>
       <div class="card">
-        <a href="/<%= lang %>/designer/<%= item._id %>"><img src="<%= item.avatar %>" alt="<%= item.username %> | <%= translate.coloringPageDesigner[lang]%>"></a>
+        <a href="/<%= lang %>/designer/<%= item._id %>"><img src="<%= item.avatar %>" loading="lazy" alt="<%= item.username %> | <%= translate.coloringPageDesigner[lang]%>"></a>
         <div class="info">
           <p><strong><%= item.username %></strong></p>
           <p><%= translate.worksCount[lang] %>: <strong><%= item.count %></strong></p>

+ 1 - 0
views/designer.ejs

@@ -4,6 +4,7 @@
 <head>
   <%- include('common-meta') %>
     <link rel="stylesheet" href="/stylesheets/styles.css">
+    <link rel="stylesheet" href="/stylesheets/header.css">
     <link rel="stylesheet" href="/stylesheets/designer.css">
 </head>
 <!-- Google tag (gtag.js) -->

+ 1 - 0
views/designers.ejs

@@ -10,6 +10,7 @@
     <link rel="alternate" href="https://art.pcoloring.com/pt/designers" hrefLang="pt" />
     <link rel="alternate" href="https://art.pcoloring.com/ja/designers" hrefLang="ja" />
 
+    <link rel="stylesheet" href="/stylesheets/header.css">
     <link rel="stylesheet" href="/stylesheets/designer.css">
 
 </head>

+ 1 - 0
views/detail.ejs

@@ -11,6 +11,7 @@
         <link rel="alternate" href="https://art.pcoloring.com/ja/<%= uri.substring(3) %>" hrefLang="ja" />
 
         <link rel="stylesheet" href="/stylesheets/styles.css">
+        <link rel="stylesheet" href="/stylesheets/header.css">
         <link rel="stylesheet" href="/stylesheets/detail.css">
 </head>
 <!-- Google tag (gtag.js) -->

+ 3 - 4
views/header.ejs

@@ -1,5 +1,3 @@
-<link rel="stylesheet" href="/stylesheets/header.css">
-
 <header class="header">
   <div class="header-left">
     <div class="dropdown">
@@ -58,8 +56,9 @@
 
     <!-- <a href="/<%= lang %>"><img src="/assets/svg/logo.svg" , alt="Art Number Coloring"></a> -->
 
-    <a href="/<%= lang %>"><img src="/assets/icon/icon.png" , class="logo" , alt="Art Number Coloring Logo"></a>
-    <a href="/<%= lang %>"><img src="/assets/svg/logo.svg" , alt="Art Number Coloring"></a>
+    <a href="/<%= lang %>"><img src="/assets/icon/icon.webp" , class="logo" , width="42px" height="42px"
+        alt="Art Number Coloring Logo"></a>
+    <a href="/<%= lang %>"><img src="/assets/svg/logo.svg" , width="160px" height="60px" alt="Art Number Coloring"></a>
 
   </div>
 

+ 10 - 9
views/index.ejs

@@ -10,6 +10,7 @@
     <link rel="alternate" href="https://art.pcoloring.com/ja" hrefLang="ja" />
 
     <link rel="stylesheet" href="/stylesheets/styles.css">
+    <link rel="stylesheet" href="/stylesheets/header.css">
 </head>
 <!-- Google tag (gtag.js) -->
 <script async src="https://www.googletagmanager.com/gtag/js?id=G-JBGGVGLHTP"></script>
@@ -23,15 +24,15 @@
 
 <body>
   <%- include('header') %>
-  <!-- <%- include('banner') %> -->
-  <%- include('latest-section') %>
-  <%- include('album-section') %>
-  <%- include('hot-section') %>
-  <%- include('designer-section') %>
-  <%- include('special-section') %>
-  <%- include('footer') %>
-  <%- include('cookie-banner') %>
-  <div style="height: 50px;"></div>
+    <!-- <%- include('banner') %> -->
+    <%- include('latest-section') %>
+      <%- include('album-section') %>
+        <%- include('hot-section') %>
+          <%- include('designer-section') %>
+            <%- include('special-section') %>
+              <%- include('footer') %>
+                <%- include('cookie-banner') %>
+                  <div style="height: 50px;"></div>
 </body>
 
 </html>

+ 1 - 0
views/search.ejs

@@ -11,6 +11,7 @@
     <link rel="alternate" href="https://art.pcoloring.com/ja/search" hrefLang="ja" />
 
     <link rel="stylesheet" href="/stylesheets/styles.css">
+    <link rel="stylesheet" href="/stylesheets/header.css">
 
 </head>
 <!-- Google tag (gtag.js) -->

+ 1 - 0
views/special.ejs

@@ -11,6 +11,7 @@
     <link rel="alternate" href="https://art.pcoloring.com/ja/special" hrefLang="ja" />
 
     <link rel="stylesheet" href="/stylesheets/styles.css">
+    <link rel="stylesheet" href="/stylesheets/header.css">
 
 </head>
 <!-- Google tag (gtag.js) -->

+ 1 - 0
views/tag.ejs

@@ -11,6 +11,7 @@
     <link rel="alternate" href="https://art.pcoloring.com/ja/tag" hrefLang="ja" />
 
     <link rel="stylesheet" href="/stylesheets/styles.css">
+    <link rel="stylesheet" href="/stylesheets/header.css">
     <link rel="stylesheet" href="/stylesheets/tag.css">
 </head>
 <!-- Google tag (gtag.js) -->