0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

口コミコンポーネントをdom一つで実現する

Posted at

はじめに

domの数が多くなるとCoreWebVitalsのパフォーマンス、TTI, TBTの数値が著しく低下します。特に口コミの星の周りのdomの数が多くなってしまったので、dom一つで実装しCoreWebVitalsの数値が向上したので記載します。

step1 webフォントをサイトからダウンロードする

https://webdesign-trends.net/entry/11656

おすすめのwebフォントのサイトが記載されているのでお好みのサービスを選んでください。今回は、Line Awesomeを選びました。

まず、サイトにアクセスするとDownload ZIPボタンが表示されているので、ボタンを押しください。
Screen Shot 2022-07-09 at 12.53.20.png

zipファイルを解凍すると、下記のようなフォルダ構成になっていることが確認できると思います。/fonts以下にwebフォントのファイルが格納されています。今回は、la-solid-900.ttfを使いたいと思います。
Screen Shot 2022-07-09 at 12.54.03.png

適当に作業用のディレクトリに格納してください。
Screen Shot 2022-07-09 at 15.33.17.png

step2 @font-faceでWebフォントを利用できるようにします。

@font-face {
  font-family: 'Line Awesome Icons';
  font-style: normal;
  font-weight: 400;
  src: local('Line Awesome Icons'),
    // 先ほど、ダウンロードした.ttfファイルを指定してください。
    url(../lineAwesome/la-solid-900.ttf) format('truetype');
}

@font-faceを定義することでwebフォントを利用することができます。

.example::before {
  ...略
  // @font-faceで定義したfont-familyを使用することでweb フォントが使えます。
  font-family: 'Line Awesome Icons';
  // F005というのは、webフォントのスターアイコンのunicodeで、beforeもしくはafterの擬似要素にcontentで指定すればスターアイコンが表示されるようになります。
  content: '\F005\F005\F005\F005\F005';
}

iconのunicodeは、サイト内のアイコンをクリックすることで確認できます。
Screen Shot 2022-07-09 at 12.55.20.png

もしくは、vscode内で確認することができます。
Screen Shot 2022-07-09 at 15.46.00.png

step3 実装

完成図
Screen Shot 2022-07-09 at 15.51.17.png

Screen Shot 2022-07-09 at 15.53.47.png

口コミコンポーネント

import React from 'react'

const ReviewPage = () => {
  // 口コミの評価によってCSSのクラス名を出し分けるために、objectで管理
  const reviewClassNameMap = {
    0: 'reviewRating-zero',
    0.5: 'reviewRating-zeroHalf',
    1: 'reviewRating-one',
    1.5: 'reviewRating-oneHalf',
    2: 'reviewRating-two',
    2.5: 'reviewRating-twoHalf',
    3: 'reviewRating-three',
    3.5: 'reviewRating-threeHalf',
    4: 'reviewRating-four',
    4.5: 'reviewRating-fourHalf',
    5: 'reviewRating-five',
    // @ts-expect-error
    [undefined]: 'reviewRating-zero',
  } as const
  
  // 口コミの評価を計算するロジック。
  const calcReviewRating = (rating: number) => {
    if (rating <= 0 || rating > 5) return 0
    const interger = Math.floor(Math.abs(rating)) as Extract<
      keyof typeof reviewClassNameMap,
      0 | 1 | 2 | 3 | 4 | 5
    >
    const diff = rating - interger
    // ex1. 4.4 => 4
    // ex2. 4.6 => 4.5
    return (interger +
      (diff >= 0.5 ? 0.5 : 0)) as keyof typeof reviewClassNameMap
  }

  const createReviewClassName = (rating: number) => {
    const calcedReviewRating = calcReviewRating(rating)
    return reviewClassNameMap[calcedReviewRating]
  }

  // ここが口コミコンポーネント
  return <i className={`reviewRating ${createReviewClassName(4.4)}`}></i>
}

export default ReviewPag

口コミのcss

@font-face {
  font-family: 'Line Awesome Icons';
  font-style: normal;
  font-weight: 400;
  src: local('Line Awesome Icons'),
    url(../lineAwesome/la-solid-900.ttf) format('truetype');
}
.reviewRating {
  display: block;
  position: relative;
}
// 口コミの星のグレー部分は、beforeに定義
.reviewRating::before {
  display: block;
  top: 0;
  left: 0;
  font-style: normal;
  position: absolute;
  color: #9e9e9e; // グレー色
  font-family: 'Line Awesome Icons';
  content: '\F005\F005\F005\F005\F005';
}
// 口コミの星のオレンジの部分は、afterに定義
.reviewRating::after {
  display: block;
  top: 0;
  left: 0;
  font-style: normal;
  position: absolute;
  color: #ffa000; // オレンジ色
  font-family: 'Line Awesome Icons';
}
// 口コミの評価が0の場合に表示するクラス
.reviewRating-zero::after {
  content: '';
}
// 口コミの評価が0.5の場合に表示するクラス
.reviewRating-zeroHalf::after {
  content: '\F089';
}
// 口コミの評価が1の場合に表示するクラス
.reviewRating-one::after {
  content: '\F005';
}
// 口コミの評価が1.5の場合に表示するクラス
.reviewRating-oneHalf::after {
  content: '\F005\F089';
}
// 口コミの評価が2の場合に表示するクラス
.reviewRating-two::after {
  content: '\F005\F005';
}
// 口コミの評価が2.5の場合に表示するクラス
.reviewRating-twoHalf::after {
  content: '\F005\F005\F089';
}
// 口コミの評価が3の場合に表示するクラス
.reviewRating-three::after {
  content: '\F005\F005\F005';
}
// 口コミの評価が3.5の場合に表示するクラス
.reviewRating-threeHalf::after {
  content: '\F005\F005\F005\F089';
}
// 口コミの評価が4の場合に表示するクラス
.reviewRating-four::after {
  content: '\F005\F005\F005\F005';
}
// 口コミの評価が4.5の場合に表示するクラス
.reviewRating-fourHalf::after {
  content: '\F005\F005\F005\F005\F089';
}
// 口コミの評価が5の場合に表示するクラス
.reviewRating-five::after {
  content: '\F005\F005\F005\F005\F005';
}

おまけ サブセット化でwebフォントファイルのサイズを軽量化

226KBもあるので、ファイルの読み込みに時間がかかるので不要なフォントを削除するとよりパフォーマンスが向上します。
Screen Shot 2022-07-09 at 16.03.25.png

ほんの一部しか表示していませんが、使ってないwebフォントまでよみこまれてしまっています。
Screen Shot 2022-07-09 at 16.04.49.png

こちらからサブセットフォントメーカーをダウンロードしてください。
https://opentype.jp/subsetfontmk.htm

フォントに格納する文字に使用するwebフォントのunicodeを指定してください。
Screen Shot 2022-07-09 at 16.10.24.png

作成開始をしてみると...
不要なwebフォントは削除されていることが確認できると思います。
Screen Shot 2022-07-09 at 16.10.51.png

ファイルサイズも226KBから2KBに減っていることが確認できると思います。
Screen Shot 2022-07-09 at 16.12.05.png

最後に

今回は、Line Awesomeを使って説明しましたが、Font AwesomeでもGoogle Material Iconsでもできることを確認できたので他のwebサイトのwebフォントでも今回の記事の内容は実現できると思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?