信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

LIST OF ARTICLES

記事一覧

  • テクログ

    Webサイトのパフォーマンスを改善するならクリティカルレンダリングパスを知っておこう

    ご無沙汰してますじゅんすです!最近やっと涼しくなってきましたね。それはさておき皆さんクリティカルレンダリングパス(Critical Rendering Path)ってご存じですか?僕はつい最近知ったばかりなのでちょっと紹介しようかと思います。Webサイトを開発している時になんか重いなぁと思う時が必ずありますよね。重いWebサイトのパフォーマンスを改善する際に、このクリティカルレンダリングパスはかなり重要なものになってきます。クリティカルレンダリングパスというのはブラウザがページを表示する際、サーバーからHTMLのレスポンスを受け取って要素を描画するまでのステップのことです。このステップは以下の通りです。・DOMツリーの構築・CSSOMツリーの構築・レンダリング ツリーの作成・レイアウトの生成・ペインティング(描画)順を追って説明していきますね。DOMツリーの構築Q. DOMツリーって何ですか?A. DOM(Document Object Model)ツリーはパース(文法を元に解析)されたHTMLのドキュメントをツリー構造として表現したものです(下図)。■critical.html<html>     <head>         <link rel="stylesheet" href="style.css">         <title>クリティカルレンダリングパスとは</title>     </head>     <body>         <header>             <h1>クリティカルレンダリングパスとは</h1>         </header>         <main>             <h2>概要</h2>             <p>概要テキスト</p>         </main>         <footer>             <small>Copyright 2019</small>         </footer>     </body> </html> ■DOMツリールート要素の<html>から始ってページ上のあらゆる要素やテキストごとにノード(結び目)が作成されます。他の要素にネスト(入れ子)された要素は子ノードとして表現され、各ノードにはその要素の属性すべてが含まれます。例えば、<a>要素はそのノードに関連づけられたhref属性を持ちます。HTMLは部分的に実行することができ、ページのコンテンツが表示される際もドキュメントを完全に読み込む必要はありません。ですがCSSがページのレンダリングをブロックする可能性があるのです。CSSOMツリーの構築Q. CSSOMツリーも知らないのですが...。A. CSSOM(CSS Object Model)ツリーはDOMに関連付けられたスタイルのオブジェクトを表現したものです(下図)。DOMと似た感じで各ノードのスタイルが関連づけられて表現されます。■style.cssbody { font-size: 18px; } header { color: #ff9bba; } h1 { font-size: 28px; } main { color: #ff7974; } h2 { font-size: 20px; } footer { display: none; } ■CSSOMツリーそういえばさっき「CSSがページのレンダリングをブロックする可能性がある」と言いましたがどういうことかというと、CSSは「レンダーブロッキングリソース(render blocking resource)」とみなされています。というのもHTMLと違って上流で定義されたものが下流へ引き継がれて文書に適用されるため、CSSを部分的に使用することはできません。途中で定義されたものを使ってしまうと間違ったCSSが適用されることがあるため、次の段階(レンダリングツリーの作成)に進む前に完全に読み込む必要があるのです。しかし常にレンダーブロッキングと見なされるわけではなく、現在のデバイスに適用される場合だけみなされます。例として<link>タグを挙げますね。<link>タグはmedia属性を指定することができ、適用されるスタイルのメディアクエリを指定することができます。例えば以下のようにmedia属性に「min-width:480px」を指定した場合、画面サイズが480pxより大きくなったら読み込むため、それ以下の場合はレンダーブロッキングとみなされません。■link要素として指定する場合<link href="URL" rel="リンクタイプ" media="screen and(min-width:480px)" > ■スタイルシートに指定する場合@media screen and (min-width:480px) {   p { color: #ededed; } } レンダリングツリーの作成Q. レンダリングツリー?A. DOMとCSSOMの両方を組み合わせたもので、ページに最終的に表示される内容を表現するツリーのことです(下図)。ただし目に見えるコンテンツのみを取得するため、「display: none;」を使用してCSSで非表示にした要素は含まれません。■レンダリングツリーこれで画面に表示する要素を整理することができました。しかしまだ端末のビューポート内における要素の正確な位置やサイズは決まっていません。それを決めるためには次のステップが必要になります。レイアウトの生成レイアウトはビューポートのサイズを決定するもので、パーセンテージやビューポートの単位に依存するCSSスタイルのコンテキストを提供します。ビューポートのサイズはhead内の<meta name = "viewport">タグによって決まり、タグが指定されていない場合は、デフォルトの980pxが適用されます。一般的な<meta name = "viewport">の値は、デバイスの幅に対応するようにビューポートサイズを設定することです。ペインティング(描画)クリティカルパスの最後の段階で、ページの目に見えるコンテンツをピクセルに変換して画面に表示します。ペインティングにかかる時間はDOMのサイズや適用されるスタイルによって異なりますので時間がかかっている場合はDOMやCSSを見てみるといいかもしれません。改めてコンテンツが表示されるまでのステップを表すとこのようになります。一見シンプルなページでも様々な処理が必要だということがわかりますね。最近サイトが重いなぁと思ったらちょっと考えてみるのもいいかもしれません。クリティカルレンダリングパスを改善するためのツールもちらほらありますので試してみてはいかがでしょうか。下にちょっとだけ貼っておきます。■Critical Path CSS Generatorhttps://www.sitelocity.com/critical-path-css-generatorhttps://jonassebastianohlsson.com/criticalpathcssgenerator/ではではっ!
  • テクログ

    関数型プログラミングに触れるためにJavaScriptのreduceに触れてみる

     秘密裏に関数型を調べたりしているのですが、その一環でJavaScriptのreduce関数に触れてみました。 この関数はArray オブジェクトを1つにまとめます。以下のコードでは配列内にある数値を全て加算します。コード1const points = [50,5,200]; const reducer = (accumulator, current) => accumulator + current;   console.log(points.reduce(reducer)); 結果1 2つの変数 accumulator, current に入る値に最初は困惑しました。リファレンスを参照すると、累積値は、ひとつ前の戻り値、もしくは initialValue です引用元: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceとあります。「初期値が設定されていない状態で、ひとつ前の戻り値って・・・?」という感じでした。そこで少し書き直してログ出力すると以下のようになります。コード2const points = [50,5,200]; const reducer = function(accumulator, current){    console.log(accumulator, current);    return accumulator + current; }   points.reduce(reducer); 結果2 挙動を見ると、1回目のループでaccumulatorに最初の要素が入っていますね。「だとしたら、currentという変数名はおかしいのでは・・?」と思い、再びリファレンスを参照すると以下の注釈がありました。注: initialValue が指定されなかった場合は、reduce() は最初のインデックスを飛ばしてインデックス 1 から実行されます。initialValue が指定されていたらインデックス 0 から開始します。引用元: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce 初期値がない場合は0番目ではなく、1番目の要素から始まるようです。  reduce関数には4つの引数を取ることができますが、強そうなので仲良くなりたいものです。【参考記事】https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
  • テクログ

    NuxtJs

    皆さんこんにちは。本日はNuxtjsというものを少し触ってみます結構前ですが同じくブログでVueJsを紹介しました。↓https://core-tech.jp/blog/article196/NuxtJsはこれに対して機能を足してSSR(サーバサイドレンダリング)を可能にしたフレームワークのようです。これだけSPAサイトが流行っている中ですが、クローラにちゃんとキーワードを読ませたいよってなったらこういったSSRができるフレームワークを使わないといけませんね。では早速。Nodejsがインストール済で、NPM5.2以降が入っている前提で話をします。私はOSはMACOS(Mojave)です。コンソールで以下を入力します。npx create-nuxt-app sample 初期設定コンソールがでるので適当に好みにあったものを選択します。で、おわるとこんな感じのがでます。 To get started: cd sample npm run dev  To build & start for production: cd sample npm run build npm run start To get startedの手順をそのまま叩くと起動します。 cd sample npm run dev で、http://localhost:3000にアクセス。はいできた。ここで終わっても面白くはないので少しだけいじって体験してみます。作成したプロジェクトにはすでにGitまで入っているので一応登録しておきます。同じ場所でgit add . git commit :wq デザインの部分に関しては、今回はBootsnippさんにサンプルとしてあるhttps://bootsnipp.com/snippets/1ea0Nを使わせてもらいます。いじるファイルは2ファイル★変更点sample/nuxt.config.jsheadの部分をまるっとこの形にします。head: {   title: 'nuxt-example',   meta: [     { charset: 'utf-8' },     { name: 'viewport', content: 'width=device-width, initial-scale=1' },     { hid: 'description', name: 'description', content: 'Nuxt.js project' }   ],   script: [     { src: 'https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js' },     { src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js' }   ],   link: [     { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },     { rel: 'stylesheet', id: 'bootstrap-css', href: 'https://maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css' },     { rel: 'stylesheet', type: 'text/css', href: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css' },   ] }, これは、ページのヘッダなどを設定する部分で前回同様CDNでスタイルなど引けるようにしています。Sample/pages/index.vueまるっと下記を貼り付けます<template>   <div class="container">     <div class="messaging">       <div class="inbox_msg">         <div class="inbox_people">           <div class="headind_srch">             <div class="recent_heading">               <h4>Recent</h4>             </div>             <div class="srch_bar">               <div class="stylish-input-group">                 <input type="text" class="search-bar"  placeholder="Search" >                 <span class="input-group-addon">                 <button type="button"> <i class="fa fa-search" aria-hidden="true"></i> </button>                 </span> </div>             </div>           </div>           <div class="inbox_chat">             <div class="chat_list active_chat">               <div class="chat_people">                 <div class="chat_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>                 <div class="chat_ib">                   <h5>Coretec-Nuxt-Sample<span class="chat_date">Aug 6</span></h5>                   <p>テストのためのサンプルです</p>                 </div>               </div>             </div>             <div class="chat_list">               <div class="chat_people">                 <div class="chat_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>                 <div class="chat_ib">                   <h5>テストです<span class="chat_date">Aug 7</span></h5>                   <p>テスト部屋2番です</p>                 </div>               </div>             </div>           </div>         </div>         <div class="mesgs">           <div class="msg_history">             <div class="outgoing_msg">               <div class="sent_msg">                 <p>最初からいれてあるサンプルの部分です</p>                 <span class="time_date"> 11:01 AM    |    Today</span> </div>             </div>             <div class="incoming_msg">               <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>               <div class="received_msg">                 <div class="received_withd_msg">                   <p>最初からいれてあるサンプルの部分です                   </p>                   <span class="time_date"> 11:01 AM    |    Today</span></div>               </div>             </div>             <div v-for='(meg, index) in talks' :key='index' >               <div class="incoming_msg" v-if=meg.flg>                 <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>                 <div class="received_msg">                   <div class="received_withd_msg">                     <p>{{ meg.item }}</p>                     <span class="time_date">{{ meg.timestamp }}</span></div>                 </div>               </div>               <div class="outgoing_msg" v-else>                 <div class="sent_msg">                   <p>{{ meg.item }}</p>                   <span class="time_date">{{ meg.timestamp }}</span> </div>               </div>             </div>           </div>           <form v-on:submit.prevent>             <div class="type_msg">               <div class="input_msg_write">                 <input type="text" class="write_msg" placeholder="メッセージをいれてね" v-model="newItem" />                 <button class="msg_send_btn" type="button"><i class="fa fa-paper-plane-o" aria-hidden="true" v-on:click="addItem"></i></button>               </div>             </div>           </form>         </div>       </div>     </div></div> </template> <script>     export default {         data() {             return {                 newItem: '',                 talks: [],                 flg: false             }         },         methods: {             addItem: function(event) {               var val = this.flg               var todo = {                   item: this.newItem,                   timestamp:new Date(),                   flg:!val               };               this.flg = todo.flg               this.talks.push(todo)             }         }     } </script> <style>   .container {     min-height: 100vh;     display: flex;     justify-content: center;     align-items: center;     text-align: center;   }   .title {     font-family: "Quicksand", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* 1 */     display: block;     font-weight: 300;     font-size: 100px;     color: #35495e;     letter-spacing: 1px;   }   .subtitle {     font-weight: 300;     font-size: 42px;     color: #526488;     word-spacing: 5px;     padding-bottom: 15px;   }   .links {     padding-top: 15px;   }   .container{max-width:1170px; margin:auto;}   img{ max-width:100%;}   .inbox_people {     background: #f8f8f8 none repeat scroll 0 0;     float: left;     overflow: hidden;     width: 40%; border-right:1px solid #c4c4c4;   }   .inbox_msg {     border: 1px solid #c4c4c4;     clear: both;     overflow: hidden;   }   .top_spac{ margin: 20px 0 0;}   .recent_heading {float: left; width:40%;}   .srch_bar {     display: inline-block;     text-align: right;     width: 60%; padding:   }   .headind_srch{ padding:10px 29px 10px 20px; overflow:hidden; border-bottom:1px solid #c4c4c4;}   .recent_heading h4 {     color: #05728f;     font-size: 21px;     margin: auto;   }   .srch_bar input{ border:1px solid #cdcdcd; border-width:0 0 1px 0; width:80%; padding:2px 0 4px 6px; background:none;}   .srch_bar .input-group-addon button {     background: rgba(0, 0, 0, 0) none repeat scroll 0 0;     border: medium none;     padding: 0;     color: #707070;     font-size: 18px;   }   .srch_bar .input-group-addon { margin: 0 0 0 -27px;}   .chat_ib h5{ font-size:15px; color:#464646; margin:0 0 8px 0;}   .chat_ib h5 span{ font-size:13px; float:right;}   .chat_ib p{ font-size:14px; color:#989898; margin:auto}   .chat_img {     float: left;     width: 11%;   }   .chat_ib {     float: left;     padding: 0 0 0 15px;     width: 88%;   }   .chat_people{ overflow:hidden; clear:both;}   .chat_list {     border-bottom: 1px solid #c4c4c4;     margin: 0;     padding: 18px 16px 10px;   }   .inbox_chat { height: 550px; overflow-y: scroll;}   .active_chat{ background:#ebebeb;}   .incoming_msg_img {     display: inline-block;     width: 6%;   }   .received_msg {     display: inline-block;     padding: 0 0 0 10px;     vertical-align: top;     width: 92%;   }   .received_withd_msg p {     background: #ebebeb none repeat scroll 0 0;     border-radius: 3px;     color: #646464;     font-size: 14px;     margin: 0;     padding: 5px 10px 5px 12px;     width: 100%;   }   .time_date {     color: #747474;     display: block;     font-size: 12px;     margin: 8px 0 0;   }   .received_withd_msg { width: 57%;}   .mesgs {     float: left;     padding: 30px 15px 0 25px;     width: 60%;   }   .sent_msg p {     background: #05728f none repeat scroll 0 0;     border-radius: 3px;     font-size: 14px;     margin: 0; color:#fff;     padding: 5px 10px 5px 12px;     width:100%;   }   .outgoing_msg{ overflow:hidden; margin:26px 0 26px;}   .sent_msg {     float: right;     width: 46%;   }   .input_msg_write input {     background: rgba(0, 0, 0, 0) none repeat scroll 0 0;     border: medium none;     color: #4c4c4c;     font-size: 15px;     min-height: 48px;     width: 100%;   }   .type_msg {border-top: 1px solid #c4c4c4;position: relative;}   .msg_send_btn {     background: #05728f none repeat scroll 0 0;     border: medium none;     border-radius: 50%;     color: #fff;     cursor: pointer;     font-size: 17px;     height: 33px;     position: absolute;     right: 0;     top: 11px;     width: 33px;   }   .messaging { padding: 0 0 50px 0;}   .msg_history {     height: 516px;     overflow-y: auto;   } </style> で、何ができたかというと。一人でチャットできるWebアプリです(笑)初期画面こんな感じ『メッセージをいれてね』の部分に文字を入れて右の紙飛行機ボタンを押すと1人チャット完成です。処理部分に関して抜粋して書きます。Index.vueのHTML部分 <div class="mesgs">   <div class="msg_history">    <div class="outgoing_msg">     <div class="sent_msg">      <p>最初からいれてあるサンプルの部分です</p>      <span class="time_date"> 11:01 AM  |  Today</span> </div>    </div>    <div class="incoming_msg">     <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>     <div class="received_msg">      <div class="received_withd_msg">       <p>最初からいれてあるサンプルの部分です       </p>       <span class="time_date"> 11:01 AM  |  Today</span></div>     </div>    </div>    <div v-for='(meg, index) in talks' :key='index' >     <div class="incoming_msg" v-if=meg.flg>      <div class="incoming_msg_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>      <div class="received_msg">       <div class="received_withd_msg">        <p>{{ meg.item }}</p>        <span class="time_date">{{ meg.timestamp }}</span></div>      </div>     </div>     <div class="outgoing_msg" v-else>      <div class="sent_msg">       <p>{{ meg.item }}</p>       <span class="time_date">{{ meg.timestamp }}</span> </div>     </div>    </div>   </div>   <form v-on:submit.prevent>    <div class="type_msg">     <div class="input_msg_write">      <input type="text" class="write_msg" placeholder="メッセージをいれてね" v-model="newItem" />      <button class="msg_send_btn" type="button"><i class="fa fa-paper-plane-o" aria-hidden="true" v-on:click="addItem"></i></button>     </div>    </div>   </form>  </div> </div> Index.vueの処理部分<script>   export default {     data() {       return {         newItem: '',         talks: [],         flg: false       }     },     methods: {       addItem: function(event) {        var val = this.flg        var todo = {          item: this.newItem,          timestamp:new Date(),          flg:!val        };        this.flg = todo.flg        this.talks.push(todo)       }     }   } </script> buttonを押下した時にscriptのv-on:click="addItem"が発火。v-model="newItem”の値を入れてdataの変数を書き換え再描画しています。1メッセージごとにflgの中身を交互に切り替え自分と相手側が会話しているように表現しています。再描画部分は<div v-for='(meg, index) in talks' :key='index' >でループで出力し、<div class="incoming_msg" v-if=meg.flg>でHTMLを相互に切り替えています。わりと簡単な実装でチャットツールのような表現をすることができました。しっかりと作り込んでいけばもっと沢山のことができるかもしれませんね。本日はざっくり概要部分だけ触れました。それでは。
  • テクログ

    高機能スライダー「Swiper」の魅力的なオプションについて

    こんにちは、ささです。今回は高機能スライダーの大定番「Swiper」の魅力的なオプションを使った実装サンプルを一部ご紹介します!色々なスライダープラグイン試してみましたが、個人的にこれが一番使いやすいプラグインではないかと思っています。◆Swiperとはhttps://codepen.io/HOanhhOanhh/pen/eorEVR/レスポンシブ対応やスワイプ操作が可能なため、スマホサイトへの実装がしやすく、前・次ボタン、ページネーション、スクロールバー、スライド速度、エフェクトなど様々なオプションを備えた高機能プラグインです。※実装方法や設定の詳細は、下記URLをご参照ください。http://idangero.us/swiper/get-started/基本的な設定をするだけで、シンプルなスライダーの実装が可能ですが、Swiperの魅力は豊富なオプションだと思います。様々なオプションを駆使すれば、以下のような面白い動きをさせることが可能です。◆実装サンプル・Swiper Cover Flow Sliderhttps://codepen.io/michiel-huiskens/pen/jMjozYメイン画像を中央に表示し3Dでスライドが切り替わる、カバーフロー効果を使用したスライダー・3D Cube Slider with Swiper.jshttps://codepen.io/digistate/pen/OzOZgY四角い箱がくるくる回転する、キューブ効果を使用した3D回転スライダー・Slider transitionshttps://codepen.io/fluxus/pen/rweVgp縦スクロールとパララックス効果を使用したスライダーこれらはほんの一部のオプションで作られたもので、Swiperにはまだまだ多くのオプションが存在します。※ご興味ある方は、下記URLをご参照ください。http://idangero.us/swiper/api/#parametersSwiperを使いこなして、より魅力的なスライダーを実装してみてはいかがでしょうか!
  • テクログ

    ブラウザテストフレームワークの5月でした

    ブラウザテストフレームワーク、使ってますか!単体テストもいいけど、やっぱりユーザが使って実際ちゃんと動作してるの?ってのが気になりますよね。最近はjsでいろいろやることも多いし、関連するところが動かなくなったり。(jsの単体テストやれって話もありますが)で、有償無償問わず、いろいろと見てみました。結構網羅したり、試したりするだけでもそれなりにかかったので、なんとなく一覧的に。・いわゆるツールでの自動テスト系teststudioRanorexAutifyTestCompleteUnified Functional TestingROBOWAREuipathkatalon studioimacros・いわゆるブラウザテストフレームワーク(E2Eテスト用)Seleniumを直使用CodeceptionCodeceptJSNightwatch.jsWebdriverIOScrapywatirAppiumSelenideGebおよびSpockCapybaraSplinterCasperJSSST (selenium-simple-test)重要視した点としては、パッとつくれて、パッと動かせる。なんだこれ、どうやるんだ、みたいなのはなし。……ということで、有償の自動テストツール系について、可能なものは体験版を入れてちょっと動かしたりしました。「ちょっと」なのはあえてちょっとだけやって、それでもできないのならば簡単じゃない!ということでした。もちろんデモや動画をみてると、「なんかすごいことやってるし、なんでもできそう…」となりますし、実際理解すればなんでもできるのかもしれません。でも少しだけいじっただけでは全く思ったとおりに動かないんですよね。というわけでツール系はなくなり、ブラウザテストフレームワークの検証となりました。テストコード書かないといけない、というのは確かに手軽とはいえないですが、サンプルがあればあとはその改良をつづけていけばなんとかなる、という思惑です。現状のサポート具合、活発さ、書きやすさ…などからCodeceptionCodeceptJSが残り、mac,PCでのブラウザテストはクリア。実機もやりたい、ということでAppium連携をしたり…ということをやっていましたよ。実機動作は結構コツが必要だったり、iPhoneだとやりたいことがどうしてもできない部分があったり…となりましたが、それ以外は結構思ったとおりのテストができましたので、毎回確認しないといけない動作がある、とか、そういった場合には役に立つのではないでしょうか。一個小ネタでいえば、テストをAWS Lambdaに連携させて、外への影響を確認したりする、ということもやってみました。純粋なE2Eテストの範疇からは外れるかとは思いますが、やはりどうしても確認したい内容もありますので、そういうものもいかがでしょう。ちなみに最終的に残ったのはCodeceptJS+Appiumでした!(以下イメージ画像
  • テクログ

    Vuejsって聞いたことある?

    こんちわ!新納です。突然ですが皆さんVue.jsって知ってます?読み方はビュージェーエスです。JSではいろんなライブラリが出ていますよね。その中でもjQueryは特に有名で使いやすいライブラリだと思います。個人的にも、jQuery大好きです。(簡単にかけるので)ですが、jQueryも簡単は書きやすい反面ミニマムな機能実装にはおすすめですが大規模、且つ複数のJSファイルに分かれるような状態になると中々メンテが大変な事になってきます。更に、あまり良いこととは言えませんがjQueryでは階層指定でバインドしている場合も多々あると思うので、うかつにHTMLをいじると既存処理が動かなくなったよーなんてことになったりします。.parent().parent.().children()……とかやっていると少しHTMLいじっただけで死ねますよねwまあ双方向バインディングとかVirtualDOMとかいろいろ特徴があるのでとくとくと説明していきたいところですが、今回はあまり概念には触れず超簡単なサンプルを使ってjQueryとの書き方の違いを比較したいと思います。コピペのまま動くようにしたいので今回はどちらのライブラリもCDNからロードしています。★やりたいこと痩せるためにはボタンを押したらリストの2番めの要素の文言を『昼はぬいてダイエット』に変える◆jQueryの場合-----------------------------------test_jquery.html<html lang="ja"> <head> <meta charset="UTF-8"> <title>てすと</title> </head> <body> <div id="content"> <input type="button" value="痩せるためには"> <ul> <li>朝ごはん</li> <li>昼ごはん</li> <li>晩ごはん</li> </ul> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="./test_jquery.js"></script> </body> </html> test_jquery.js$(function(){ $("#content input").on("click",function(){ $("#content ul li").eq(1).text("昼は抜いてダイエット"); }); }); -----------------------------------------------------------------------◆Vuejsの場合------------------------------test_vue.html<html lang="ja"> <head> <meta charset="UTF-8" /> <title>てすと</title> </head> <body> <div id="content"> <form> <input type="button" value="痩せるためには" v-on:click="ibentohakka" /> </form> <ul> <li v-for="gohan in list">{{ gohan }}</li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js"></script> <script src="./test_vue.js"></script> </body> </html> test_vue.jsvar app = new Vue({ el: '#content', data: { list: [ '朝ごはん', '昼ごはん', '晩ごはん' ] }, methods: {  ibentohakka: function() { Vue.set(this.list, 1, '昼は抜いてダイエット'); } } }); ---------------------------------------------------------…どうすか?画面で見ると結果は全く同じです。『jQueryの方が記述短いじゃねーかいい加減にしろ!』とお怒りの方。ごもっともです…Vueは特徴的なところが何点かありますね。<input type="button" value="痩せるためには" v-on:click="ibentohakka" />これは、jQueryのonclickと似ています。これが押されたらjsに書いてあるmethodsのibentohakkaが発火し中の処理Vue.set(this.list, 1, '昼は抜いてダイエット’);が実行されます。<li v-for="gohan in list">{{ gohan }}</li>jQueryではHTMLに直接リストを記述しましたが、Vueはリストの部分にこれしかありません。これは、gohan in listの部分でデータ・セットの部分data: { list: [ '朝ごはん', '昼ごはん', '晩ごはん' ]},のリストをループして出力します。jQueryだと$("#content ul li").eq(1).text("昼は抜いてダイエット”);でdomを指定して値を書き換えていますが、これだと例えばulの要素が1つ上に追加されたら想定外の部分が書き換わってしまいます。ですが、Vueであれば<li v-for="gohan in list">{{ gohan }}</li>で作り出したものに対してVue.set(this.list, 1, '昼は抜いてダイエット');としているので、仮にHTMLの階層が変わってしまっても変更したい要素がうまく切り替わってくれます。この短いコードではあまりメリットを感じられないかもしれません。が、プロジェクト規模が大きくなり、HTMLの改修が増えるほどVueのメリットは大きくなってくると思っています。ライブラリを読むだけで使えるしjQueryとの共存もできるのでいきなり全書換は嫌だけど簡単な部分だけでもVueで記述していったらいつか良さに気づく日もくるんじゃないでしょうか。ではまた!