Can I do web?

AngularJS 中心の不定期ブログ

Angular1 のこれから - 2015

AngularJS Advent Calendar 2015 ラストの投稿です。

ただの感想文なので、こっちに書いておく。

Angular1 のこれから - 2015

まず、Angular1 は完全に枯れたなと。出尽くした感満載。今年の AngularJS Advent Calendar を書くにあたって、ネタ探しが大変でした。

さて、今年は 1.5-beta までアップデートがありました。1.5.0 の正式リリースについては来年の早期を予定してるそうです(リリースするとは言ってない)。

今年の Angular1 は安定とか成熟とかいう言葉がぴったりで、いよいよ枯れたなーって感じがします。大きな変更もなく、淡々とバグフィックスしてきた印象です。

Angular1 のこれから

公式ブログ にさらっと書かれているんですが、

We’ve also been fixing bugs and performance upgrades within the AngularJS 1.4 ecosystem. Once 1.5.0 is fully released then we will only continue to do security patches for the 1.4.x versions therefore please upgrade to 1.5.0 once it is available.

まず「v1.5.0 をリリースしたら v1.4 にはセキュリティパッチしか適用することしかしない」ということなので、
今現在の v1.4 の最新版は v1.4 としてはほぼ完成系に近しいということ。安心して使えます。
あと 「v1.5 がでたらアップグレードしてね」

As of this release, AngularJS 1.5 is feature complete. The next step from here on will be getting things ready for the full 1.5.0 release around the start of 2016!

そして、 v1.5 についても「基本的な実装はできているので、正式リリースが次のステップ」とのこと。

予想という名の妄想

こうは書いてはありますが、Angular チームは v1.x の最新版を使い続けて欲しいのではなくて、
v2.0 へマイグレーションする準備をしておいて欲しいのではないでしょうか。
というのもボクが勝手に受けた印象ですが、angular1 は機能としては v1.4 でほぼ完成で、 v1.5 は v2.0 に向けてマイグレーションの準備をするためのバージョンだと思っています。
v1.5 で追加された `module.component` も v2.0 の `Component` に寄せた様に見えます。
さらに、`ngUpgrade` や `ngForward` など、v2.0 に向けてマイグレーションするためのツールも合わせて用意を進めています。
ですので、 v1.5 が出たからといって、これから5年も10年も運用していくようなことはして欲しくないはずです。
サポートもそんな長期間するかな、というのも疑問です。

あと、雰囲気的に v1.6 はなさそうですね(予想)。

Angularを使いたい人へ

これから Angular1 を採用しようとする際、特に制約がなければ v1.5-beta で良いです。
beta といっても今までの Angular1 + α なので、そう大きなバグはおそらくないでしょう。
来年の早期に正式リリースするのことなので、半年以上続くプロジェクトであれば大きなバージョンアップをしなくて済みます。
ちょっと怖いなという場合は、v1.4 の最新ですが、v1.5 や v2.0 に向けてのコストが少しかさむので、その点でトレードオフになります。

過激派の方は v2.0-beta 一択です。

Angular2 については

Angular1 よりもモダンな JavaScriptフレームワークらしくなってきました。
ボク自身まだまだ把握できてないのですが、来年のリリースで今と比べてどう良くなっているのかが楽しみです。これからもちょくちょく触っていきます。

ちなみに...

Angular 1.x Meeting Notes に直近のリリース予定日が記載されていたので残しておきます。

We intend 1.4.9 will be released before Xmas. 1.5.0­rc.1 will be released after Xmas.

リリースされたかどうかは確かめてみてください
このくらいの温度感なので v1.5 や v2.0 のリリースについても同様の予想をすると良いでしょう。

AngularJS 1.4 のご様子

Advent Calendar ラストー!

前回は v2.0 だったので、今回はこちらをさらっと調べてみました。とはいっても、v1.4に関しては、まだまだスタートしたばかりのご様子で、かつ v2.0 のように大々的に変わるようなこともありません。
(なのであまり書くことがなかった。。。)


今月の11日にオンラインMTGで始まったようです。
AngularJS 1.4 Planning Meeting


v1.4 で優先的に対応されるのが、以下の機能です。

  • Router
    • 1系、2系の両バージョンに向けて、新しい Router の実装。
  • Forms
    • parsing/formatting/validation の機能を見直し。
  • Parser
    • $parse サービスのパフォーマンス改善
  • Documentation
    • 公式ページにマテリアルデザインを適用するために再設計する。
  • $injector
    • より早くバグを特定するために、モジュールを再定義した際にはエラーを投げるようにする。
  • $compile
    • いくつか新しいモジュールを追加する。(より簡単にコンポーネントタイプのディレクティブを定義できるようにする。)
  • Project layout
    • モバイルを意識して、 angular.js をさらに細分化、オプショナルにすることで、core 機能のファイルサイズを軽減する。

v1.4 のリリース予定日

2015/3/5-6 に開催される ng-conf にあわせるとのこと。

まとめ

AngularJS v1.0 がリリースされてから、2年半程経ちました。
v1.x についてはある程度枯れてきていているので、そうビックリすることはないですね。
個人的には、はやく v2.0 を触りたい!

AngularJS 2.0 のご様子

Advent Calendar 20日目のポストです。

ちょうど2.0について書こうと思ってたところに、昨日さらにつっこまれたので取りあげてみます。

f:id:canidoweb:20141220163156p:plain:w400

で、画像中の記事がこちら

この記事について振られたので調べてみた。

元記事をお読み頂きつつ。

#ツールに新たに追加される概念は、1つではなく3つ!

これは2.0になるので知っておこう、なのでそうなりそうです。
ただし、AtScript については Optional な感じで良いと思います。TypeScript + AngularJS な人は知っておくと恩恵があるのではないでしょうか。

#変わるが、良くならない

このコードのサンプルだと、記述が変わったなということ位しかわからくて、あまり意味がありません。v2.0 では、Web Conponents や以前から統合するといっていたPolymer との連携を考慮すると、従来通りの Attribute にデータバインディングする方法ではどうにも解決できないので、代わりに Property にデータバインディングする、という方法に舵を切ったようです。

経緯については、こちらで議論されています。
※ 英語力 0なので、ちゃんと理解できてるかはわかりません

#2016年になるまで使えない

待ちましょう。ドラスティックに変わるものに対して、段階的にリリースされることが嬉しいことかどうかということです。段階的に出ても、機能が不足しているようなら使い物にならないので、Angular チームがそう判断したのならそれで良いと思っています。
AngularJS 2.0 のドラフトを見るとかなり大幅に手を入れていくだろうことがわかると思います。

#Angular 1.3のサポートは、2.0のリリース後わずか18~24カ月で終了

v1.3 のサポート終了はそうかもしれないですが、現在 v1.4 に向けて仕様策定しているので、1.x 系で作成している現状のアプリケーションは当面そちらを採用していくことになるかと思います。その後、v1.5 まではアップデートを検討しているようです。なので移行期間はそれなりにあるのではないかな、と。

#結論:Angularを選択しない

記事中に「安定していて長期のサポートを得られるフレームワークです。」ってあって確かにおっしゃる通りなんだけど、現段階で、10年後のWebの世界を見通した上で作られたフレームワークって無いと思う。結果的に上手く適応できたフレームワークが残ったって感じではないのかなぁって気がします。もしあるのであれば、理想的ですね。

AngularJS 2.0 で変わること

どうなっていくのか、どういった議論があったかなど、詳しく知りたい方はこちらを一通りご覧になると良いです。(めちゃくちゃ多いので気になるところだけでも...)

で、ざっくりと v2.0 では以下の機能達が亡くなります。

f:id:canidoweb:20141220201006p:plain:w120f:id:canidoweb:20141220201007p:plain:w120f:id:canidoweb:20141220201012p:plain:w120f:id:canidoweb:20141220201009p:plain:w120f:id:canidoweb:20141220204008p:plain:w120
これ見ただけでもかなり変わりそうだというのが理解できるのではないでしょうか。その代わりとして、新しい機能や記法がでてくるので、ある意味生まれ変わると思っていた方が良さそうです(もちろん良い方向に)。
詳細は別途、少しずつブログにまとめていこうと思います。

ng-europe のIgor Minar & Tobias Bosch のセッションで使われていたんですが、おもしろかった。


Angular 2.0 Core by Igor Minar & Tobias Bosch at ...

Web Components ライクに Directive を読み込んでみた

Advent Calendar 8日目だー!

ということで。


そもそもできるのかなーと、ふと思ってやってみた。
完全にネタ回です!


まずは呼び出す側のHTMLがこちら。

<!doctype html>
  <head>
    <meta charset="utf-8">
    <title>demo</title>
    <link rel="stylesheet" href="styles/main.css">
    <link rel="import" href="clickCounter.html" /><!-- ① -->
    <link rel="import" href="inputText.html" /><!-- ② -->
  </head>
  <body>
    <p>クリックカウンター</p>
    <click-counter></click-counter><!-- ③ -->
    <div ng-init="myModel='foo'">{{ myModel }}<div>
    <click-counter></click-counter><!-- ③ -->

    <p>文字入力</p>
    <input-text></input-text><!-- ④ -->
    <div ng-init="myModel2='bar'">{{ myModel2 }}<div>
    <input-text></input-text><!-- ④ -->
</body>
</html>

①、②で2種類のコンポーネントを読み込んでいます。
見たらわかると思いますが、①は click-counter 要素、②は input-text 要素を定義するためのものです。


まずは①のコードから見てみます。
機能としてはボタンをクリックで、カウントアップするだけのものです。


clickCounter.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>clickCounter</title>
</head>
<body>
    <script src="bower_components/angular/angular.js"></script>
    <script src="scripts/clickCounter.js"></script>
    <script>
      var element = angular.element(document);
      angular.bootstrap(element.find('click-counter'), ['clickCounterApp']);
    </script>
</body>
</html>


clickCounter.js

'use strict';
// clickCounterApp module 作成
var app = angular.module('clickCounterApp', []);

// clickCounter directive 作成
app.directive('clickCounter', [function(){
  return {
    scope: {},
    restrict: 'E',
    controller: function($scope){
      $scope.count = 0;

      $scope.click = function(){
        $scope.count ++;
      }
    },
    templateUrl: 'clickCounterTmpl.html'
  };
}]);


さらに、テンプレートを外部ファイル化。 clickCounterTmpl.html

<div>
  <button ng-click="click()">click</button>
  <span ng-bind="count"></span></div>

①についてはこんな感じの構成でやってみました。
ポイントは、 angular.bootstrap を使って AngularJS をブートしてあげること。
原則 ng-app は1カ所のみ使用するのがルールですけど、こうすることで、無視できます。
複数呼び出すと警告はでます。
③を2カ所で呼んでいて、その間のAngularJS のコードは対象スコープの外なので動作しません。呼び出し元に影響していないのがわかります。

f:id:canidoweb:20141208224102p:plain

こんな感じで動いてくれています。


次はもう少し Web Components の仕様と戯れてみます。
以下が、②の構成。
機能としては、テキストボックスに入力した文字を出力するだけ。


inputText.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>inputText</title>
</head>
<body>
    <template>
      <input type="text" ng-model="myText">{{ myText }}
    </template>
    <script src="bower_components/angular/angular.js"></script>
    <script src="scripts/inputText.js"></script>
    <script>
      var element = angular.element(document);
      angular.bootstrap(element.find('input-text'), ['inputTextApp']);
    </script>
</body>
</html>


inputText.js

'use strict';

var app = angular.module('inputTextApp', []);

app.directive('inputText', ['$compile', function($compile){
  return {
    scope: {},
    restrict: 'E',
    template: '<div></div>',
    link: function($scope, iElm, iAttrs, controller) {
      var _self = angular.element(document.currentScript.ownerDocument);
      var template = _self.find('template');

      var shadow = iElm[0].createShadowRoot();
      shadow.innerHTML = template.html();

      $compile(shadow)($scope);
    }
  };
}]);


呼び出し方については、①と同じです。あいだに動かないmodelを定義しているのも一緒です。
やってみたことは、ディレクティブ作る用に template を書くプロパティがあるにもかかわらず、template 要素を使ってみたくて使っちゃったこと。
使ってみたかっただけなので、やいやい言われてもどうしようもありません。無駄の極みです。
そして、template 要素から取得したDOM を Shadow DOM につっこんで、そいつを $compile でねじ伏せてみた。
結果、これで動いた。。。なんかもうすごい。

f:id:canidoweb:20141208224103p:plain

まとめ

ふと思ってやってはみたものの、いけるんだなって思った。
ちょっとしたディレクティブなら、ちゃちゃっと読み込めてしまいますよ。


絶対にやらないと思うけど。

Angularが好き

ボクは本当にAngularが好きで、もはや恋するレベルに達していて、今ではもう実案件に使っている。

イカ理由。


  • APIがほんっっっっっとうに糞
    • 趣味の問題といえばそうでもあるが僕は糞だと思う

→ 趣味には口を出しません。そう思うならそうです。


  • 実装が黒魔術
    • 良識あるJSエンジニアなら Function.prototype.toString() しない
    • 実際に一部のクロージャが破壊されてて挙動が直感に反する
    • DirtyCheckの実装、表面的にもDirtyな挙動として現れるのでデータバインドとして何も嬉しくない

→データバインドだったり、Web Components のような、未来にnative実装されるAPIを包括的に実装しようとした結果の1つだと思ってます。
もっといい方法はあるのかもしれないですけど、Angularではこうしてるよっていうのが現状なのかなと。
上記で毒づく程不満はないです。


  • Googleだから許される、みたいなコミュニティの驕りが本当に嫌
    • Angularの都合だけでChromeでObject.observeを前倒しするのやめろ

→ここだけ凄い気になったんですが、そんなことはないみたいです。(気になる方はtweetを追っかけてみてください)


言ってしまえば Object.Observe(O.o) が実装されて困ることって無いですよね?嫌なら使わなければいいだけの話。むしろ実装されたことによって、未来の技術を先にお試し出来る、と捉えることができるし。
O.oをつかってデータバインドさせるなら今のうちに勉強しておくと、未来の自分に投資できます。
Angularのデータバインドが嫌いなら、Chrome実装済みのO.oを利用して自身で作ればよいのです。


  • Angularの内部モジュール同士が密結合
    • DI, module, factory, それぞれ大きなテーマなのに密結合
    • 使いはじめるとAngularをやめることが困難

→これもフルスタックが故の問題かもしれないです。個別にモジュールを選べるなら疎結合でないとダメですけど、フルスタックなのでその辺は密になっても別に。。。
何言ってもフルスタックなので内部モジュールは密結合でもいうほど気になりません。もちろん疎結合になるなら、より良いとは思いますが。


  • パフォーマンス面で他フレームワークに対して長所を持たない
    • というか基本的にAngularでSPA作ると上述のDirtyCheckの問題で悪化する。その解決策がObject.observeを政治的に前倒しするってのも気に食わない。
    • 何をやるにもググって解決しなければならないぐらいには一貫性がない
    • 中身が黒魔術 + 設計が一貫してないから解決するためにこうする、っていう直感が働かない
    • 検索で各MVWとの比較で検索数一位だから流行ってる!みたいな意見あるけどこんな歪な設計するとググらないとなんもわからん。Railsみたいなまともな規約もないし。


→これは元々Angularの設計思想で、パフォーマンスを「超」意識しないといけないようなサービス、Webアプリには向いてません、と明言しています。
あと、canvasなどを扱ってアレコレしちゃおうってのもAngularの思想には今のところないです。
なので、よく「0.1秒レスポンスが遅れると売上が○%落ちた」みたいなサービスには確実に向いてません。
これを目的にAngularを採用するのであればやめましょう。お門違いです。
ただし、O.oでAngularが実装されるようになれば、その点もある程度はクリアできるのかなと期待をしています。期待なので叶うかは別ですが。。。


  • JavaScriptのノウハウが生かせない
    • Angular流儀を強制されて他のモジュールと繋がらない


→Angularで扱えるように、ラッパーを作りましょうっていうのがナレッジになってます。
この辺はたしかに癖があるので、慣れるのに大変かもしれませんし、ラッパー作るの大変かも知れません。
あえていうなら、安易にjQueryプラグインを導入するな!です。わかってて使うのだよ、ということです。
とはいえ、メジャーなものはAngularでラップされていたりするので、極端なもので無い限り心配する必要もないかなーと思ってます。


  • 最後に

MEANの話は出なかったけども、中の人がdisられたってちょー凹んでたので、反論というかなんというか。
ま、なんか今回はdisり方が雑だなーって思った。むしゃくしゃしてやった感否めず。



お財布みつかるといいね。

ng-mtg#5 AngularJS 勉強会まとめ

 

先日開催した  mg-mtg#5 AngularJS 勉強会 - AngularJS Japan User Group | Doorkeeper で使った 資料(?) を公開しようと思ったんだけど、これでは伝わる気がしない、ということでまとめてみました。

 

今回の勉強会は、

  1. 3〜4人のグループ作る
  2. 出題されたテーマについてディスカッションする
  3. 結果を発表する
  4. みんなであれこれ話して結論を出す

これを時間が許す限りやってみようという企画。そこで発表すると時間かかると思い、急遽 GoogleDocs でドキュメント共有 して 3. の結果を書いてもらうようにしました。結果的になんか楽しい感じになったので良かったのかなと。

上のドキュメントのリンクをみて頂ければわかるのですが、何のことだかわからんと思います。なので、振り返ってみます。ドキュメントと合わせて見てください。「」で囲んでいるのが共有ドキュメント内のキーワードになってます。

 

テーマ#1

  Controller 間でデータを共有する方法を検討してみてください。

まずはウォーミングアップ問題。

ボクとしては記入してもらった1つの、「Service に保持して各コントローラに inject する」みたいなのを期待してたんですが、「そもそもあまり共有しないのでは」というバッサリとしたご意見も。他にネタっぽいのもありますね。

1点注意ですが、この中の「$rootScopeを使う」はお勧めしません、というよりbad practice なので、最愛の人が人質にされているようなケース以外はやめましょう。

 

テーマ#2

  Provider, Service, Factory のそれぞれが、適役である具体的なケース・機能を検討してみてください。

 第2問。難しいことを聞いてみました。

難しかったようで、具体的なケースまでには至らず。Provider については「providerはconfigフェーズで設定が必要な場合に使う。」で概ね一致しました。その後に「factoryとserviceはfactory使っとけばいいんじゃない?」でちょっとした紛争が。。。

Factory しか使わない派 vs Service しか使わない派

これ、簡単に言ってしまうと function 返すか、new したオブジェクト返すかなんです。まさか AngularJS の話してるのに、new する/しない 紛争みたいなものに巻き込まれそうになるとは思いませんでした。

 結果としては、「OOPっぽく書くならService、関数マシマシで書くならFactory」で落ち着きました。いやー、盛り上がった(笑)

 

テーマ#3

  directiveをつくる時の判断基準

 これは総じて同じような意見でした。テンプレートをコンポーネント化する場合は、restrict: 'E' で、振る舞いのようなものを割り当てたい場合は restrict: 'A' を使うと直感的かなと思います。ちなみに、restrict: 'C' を使っている方はいなかったです。

「<markdown-editor ng-model=”data”>とかどう作るんだ」が宿題に。

ボクやりますと言ってはみましたが、後からコレじゃね?と tweet してくれた人がいたので、そのリンクを貼っておきます。

JavaScript - 自作directive内でng-modelをきちんと動作させる - Qiita

このことじゃなかったら詳しく聞いて更新します。
あと、この記事を書いた方、会場にいたような・・・そんな気がした。

 

テーマ#4

  パフォーマンスについて、改善や工夫したことはありますか?

1.2.x 系は IE8 をサポートしているのですが、実際にIE8で動作させるとかなり遅くなるケースがあったそうです。
ちなみに、現状のバージョンについては、1.2.x 系が legacy 版、と 1.3.x 系 が latest 版という位置づけになっています。

 vue.js については以前、ホントにちょっと見たことがあって、そのときの第一印象を言っただけなので、合ってるかどうかは実際に調べてみてください。あと間違ってたら教えてください。

「データを表示に合わせて整形する処理...」については、ほぼ全員がケースバイケースだという意見でした。これについてはサーバ処理やサーバ自体のスペックなど色々な状況から判断する必要があると思います。

「$destroy 使ってる?」といった質問がありました。document にイベントリスナをつけるような directive を作る場合は、$destroy を使って明示的に外すようにしているとのこと。これについてはメモリリークの心配もあるので、確かにやっておいた方が良いかも、と新しい発見でした。

 

テーマ#5

  SEO どうしてますか?

これが最後のテーマになりました。

個人的には「 そもそもSEOが必要なのアプリはSPAにしない」が正しいと思います。
とはいえ、そうもいかない事情もあるのだなぁと。note の ogp 対策が話題にあがりました。

そういった背景含め、 @hokaccha さんから頂いたテーマについてディスカッションしました。

https://gist.github.com/hokaccha/a4c09e5663dbabb56fec

「Directiveで囲んで、compile走る前に持ってくるとか」が一番 AngularJS らしい SEO 対策としてのアプローチではないでしょうか。

 

以上で時間いっぱいとなりました。ディスカッション形式、初めての試みだったのでどうなるか全然読めませんでしたけど、蓋を開けてみると、みなさん積極的で良かった良かった。あとは楽しんでもらえてたらより嬉しいです。ニーズがあればまたこの形式でもやってみようと思います。進行下手とかだったらすみません、がんばります。

 

 

とりあえず次回のイベントは AngularJS 2周年記念イベントですかね。

 

 

HTML5のマークアップにSEO観点をいれてみた

 

 

今回 AngularJS じゃなくって、 HTML5的なことを書いてみます。
ちょいちょいこんなのも書いてみようと思います。

 

先日この記事を見て、気にしていたことが少しわかった風なので、まとめつつ現状のマークアップの感覚として残しておくことにしてみた。

自分で書くときのテンプレ的なマークアップを修正というかSEO向けに意識を寄せてみた感じです。

※若干謎なところもあるけど、そのまま?にしちゃって一旦良しとして、あとで詳しい人に聞くことにします。現状そこまでは気にしないことにする!

 

最近SEO全然意識してなかったこともあり、すごい勉強になりました。

現状だとHTML5への過渡期ということで余計に意識しないといけないことがあるようなので、多くのWebサイトがHTML5だー!ってなるには、もう少し時間が必要な感じがしました。ある程度落ち着いてからの方がリスクが少ないと思いますし。


記事を読めばわかるんですけど、HTML5SEOを意識するには、「正しいマークアップをすること」って書いてあるんですけど、たぶんこれが一番難しい。

SEO関係なく。

現状だとその上でHTML5への過渡期分のSEOも考慮しないとなのか、ん〜・・・。

 

参考

 HTML5のSEO-マークアップで注意すべき3つのポイント
http://html5experts.jp/tsuj/2333/

 

以下は参考とした記事をマークアップでまとめてみた感じです。

マークアップがセマンティックであるかどうかについては、まとめ書き程度なのであまり意識していません。ただ、間違ってたら教えてください。

  

<!doctype html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ページ名|サイト名とか</title>
</head>
<body>
  <header>
    <h1>サイト名orページ名とかサイトロゴとか</h1>
    <nav>
      <h2>グローバルナビ</h2>
      <ul>
        <li><i>メニュー1</i></li>
        <li><i>メニュー2</i></li>
        <li><i>メニュー3</i></li>
      </ul>
    </nav>
  </header>
  <main>
    <section>
      <h2>FlashからHTML5へ。リッチな表現のSEO手法</h2>
      
      <section>
        <h2>別ページを用意する</h2>
        <p>検索エンジン用に別ページを作成する(よくあるヤツ)</p>
      </section>

      <section>
        <h2>代替テキストいれる方法</h2>
        <canvas>
          ここに代替テキストいれとく
          2013年9月1日現在、Google、Bingの検索エンジンでは認識している
          他のは不明、かつ今後の扱いは不透明
        </canvas>
      </section>

      <section>
        <h2>CSS(+JavaScript)で切り替える方法</h2>
        <canvas style="display:none;"></canvas>
        <div style="display:block;">テキスト</div>
        <p>
          JavaScript を使って display の値を反転させる?
          検索エンジンが JavaScript を読めないのが前提?
        </p>
      </section>
      
      <strong>
        <p>本来リッチな表現を検索させる上で、最も重要な事は技術的な要件ではありません。</p>
        <p>そもそもの話ですが、検索される必要がある情報をリッチコンテンツを中心として制作するのが誤りでしょう。</p>
      </strong>

    </section>
    
    <section>
      <h2>SEO効果があるh 要素の使い方</h2>
      <strong>
        <ul>
          <li><p>h1 を複数使用する場合は不利になる場合もあるし、ならない場合もある</p></li>
          <li><p>SEO的には h1 要素は1つで、h2 要素以後もうまく使って文書構造を示しておくのが安全。</p></li>
        </ul>
      </strong>
    </section>
    
    <section>
      <h2>HTML5 で追加・削除・復活した要素</h2>
      <p><strong>ページの情報を正しいHTML5マークアップをしておくことが、唯一の対策となるでしょう。</strong></p>

      <section>
        <h2>HTML5で追加された要素</h2>
        <ul>
          <li>
            <p>nav や footer は現段階では div と同じ扱いを受けている模様。</p>
            <p>今後HTML5が普及した際には、様々な形で検索エンジンも活用し出すことが考えらる。</p>
          </li>
        </ul>
      </section>

      <section>
        <h2>これまでは推奨から外れていたものの復活した要素</h2>
        <ul>
          <li>
            <section>
              <h3>iframe 要素</h3>
              <p>取扱用注意!</p>
              <p>現段階では「iframe 要素内のコンテンツは、ページ内のコンテンツとして認識されることもあれば、されないこともある」</p>
              <p><strong>SEO を考える必要があるWebページでは使用しないことをお勧め</strong></p>
            </section>
          </li>  
          <li>
            <section>
              <h3>b 要素・ i 要素</h3>
              <p>b 要素の多用は、HTML4の b要素と混同するため、現段階ではお勧めしない</p>
              <p>i 要素も同様で、両方ともCSSを用いたマークアップをすると良い</p>
            </section>
          </li>  
        </ul>
      </section>
      
    </section>
    
  </main>
  <footer>
    <div><small>@can_i_do_web</small></div>
  </footer>
</body>
</html>