none
Windows 10 Fall Creators Update (バージョン1709) にアップグレード後、MFC リボンを使用したアプリケーションの動作が遅くなる

    質問

  • Windows 10 Fall Creators Update (バージョン1709) にアップグレードすると、MFC リボンを使ったアプリケーションの動作が遅くなります。

    具体的には、次の現象が発生します。

    ・リボンのタブを切り替えるときに2~3秒ほど時間がかかります。

    ・右クリックでポップアップメニューを表示するときも同様に2~3秒ほど時間がかかります。

    ・どちらの操作も初回表示のみ遅く、2回目からは素早く表示されます。

    Windows 10 Creators Update (バージョン1703) では、どちらの操作も0.5秒ほどで問題なく表示されます。

    MFCリボンアプリケーションは、Visual Studio 2010 で作成しています。

    ただし、最新のVisual Studio 2017でも発生するようです。

    https://developercommunity.visualstudio.com/content/problem/136952/mfc-ribbon-slow-on-first-loadshow.html

    動作が遅くなってしまい非常に困っています。

    ソースコードを修正する方法だけでなく、Windows10の設定変更などで回避する方法があれば教えていただきたく存じます。(1703に戻す方法以外で)

    よろしくお願いします。

    2017年10月31日 10:23

すべての返信

  • いろいろ試してみて、分かったことをご報告します。

    Windows 10 (Ver 1709) でGetPixel()/SetPixel() の呼び出しが10倍以上遅くなっているのが原因であると思われます。
    特に、リボンのアイコン数が多いと、目に見えて遅くなります。
    Visual Studio 2017 でビルドしても発生します。
    詳しくは以下の通りです。

    【再現手順】
     a. MFCリボンアプリケーションを新規作成。
     b. リソースエディタを開く。
     c. ビットマップリソースを2種類(2048px×16px, 2048px×32px)追加。
     d. リボンリソースを開き、カテゴリを追加。
     e. dで追加したカテゴリに対し、Small Images, Large Images としてbで追加したビットマップリソースのIDを指定。
     f. 作成したアプリケーションをビルド。
     g. Windows 10 (Ver 1709) でアプリケーションを起動し、カテゴリを切り替えると、切り替えが完了するまで1秒以上かかる。


    【原因】
     MFCリボンのタブ(カテゴリ)を切り替えたとき、カテゴリのSmallImages, Large Images に対して、SetTransparentColor() が呼び出される。
     この関数からUpdateInternalImage() を経由し、最終的にGetPixel()/SetPixel() が実行されるが、Windows 10 (Ver 1709) では、Ver 1703 と比較して、GetPixel()/SetPixel() の呼び出しに10倍以上時間がかかるようになってしまった。

    【回避策】
     CMainFrame::OnCreate() でリボンを生成した直後に、全カテゴリのSmallImages, Large Images に対して、
     SetTransparentColor(GetGlobalData()->clrBtnFace) を呼び出す。
     (VS 2010 の場合は、SetTransparentColor(afxGlobalData.clrBtnFace))
     重たい処理を事前に行っておくことで、リボンのタブ(カテゴリ)を切り替えが素早く行われる。 

     ただし、この回避策では、起動するまで時間が遅くなるため、抜本的な対処ではない。
     OS側で GetPixel()/SetPixel() の高速化が対策されない場合、
     抜本的に対処するには、GetPixel()/SetPixel() を使わないよう、CMFCToolBarImages クラスの処理を修正する必要がある。


    この問題を早急にマイクロソフト社が修正しない限り、アプリ側で何らかの対処をせざるを得ないと思います。
    そもそも、GetPixel()/SetPixel() を多用していること自体がよくないのですが、自前でコーディングしていた部分であればともかく、ライブラリ側の問題でユーザーが修正を迫られるのはいかがなものなのでしょうか?

    最近のマイクロソフト社の動きを見ていると、従来型のWindowsデスクトップアプリにはあまり関心がない気がしてなりません。
    Windows離れがより一層進むことを危惧します。

    2017年11月4日 20:43
  • 詳細な検証情報の共有、ありがとうございます。

    一点、共有しておきたいことがあるとすれば、「この場はユーザー同士の情報交換フォーラムであり、Microsoft の開発メンバーに声を届ける場ではない」ということです。
    調査いただいた内容から、Windows の不具合であろうことは見えていますので、フィードバック Hub にダメ押しで挙げてください。

    2017年11月4日 22:53
    モデレータ
  • Azulean 様

    ご連絡ありがとうございます。

    ここは、開発者間の情報交換の場であることは承知しております。

    フィードバックHub にも投稿していますが、まだレスがついていないようですので、そちらにもコメントを追記しています。

    2017年11月5日 3:19
  • フォーラムの性質は理解されていると言うことなので、その上で1つ書かせてください。

    Windows は年2回大規模なアップデートを配信するというリリース体制に移行しました。
    新機能の追加・仕様変更などが従来よりも頻繁に発生するため、結果的に、何らかの不具合が埋め込まれるリスクが高まりました。
    Creators Update でも「DateTimePicker コントロールの表示や入力が正しく機能しない場合がある」という問題がありましたので、今後も続くと予想されます。
    (もっとも、古いコモンコントロールを利用するアプリケーションとなると、割合は低くなりますが)

    Microsoft は内部でのリングのほか、Insider Preview としてテストする人々を募っています。
    これは Microsoft 自身で見つけきれなかった不具合を見つけてもらう性質もあると思っています。
    自己防衛も兼ねて、Insider Preview の終盤には自分たちのアプリケーションの動作確認を通じて Windows の不具合を見つけていくのも必要かもしれませんね。
    (正式リリース前に見つければ修正が早まるかもしれない。正式リリース後だと定例リリースと一緒にリリースなど、スピード感が落ちる)

    2017年11月5日 7:03
    モデレータ
  • Azulean 様

    自己防衛のために、Insider Preview でテストしておくというのは、おっしゃる通りだと思います。

    ただ、そうであれば、マイクロソフト社は、Windows 10のアップグレードにおいて、「不具合が出る可能性があるので、Insider Preview でテストすべき」 ということを、もっと開発者にアピールすべきでしょう。 

    最近、Windows デスクトップアプリ開発者向けのサポートが手薄になってきていると感じます。 早くUWPへの移行を進めたいめのでしょうね。

    (Azulean 様に言ってもどうしようもないのですが、お許しください。)

    2017年11月6日 20:50
  • ただ、そうであれば、マイクロソフト社は、Windows 10のアップグレードにおいて、「不具合が出る可能性があるので、Insider Preview でテストすべき」 ということを、もっと開発者にアピールすべきでしょう。 

    具体的にどういった策を採っていたら良かったとお考えですか?
    仮に Web サイトやエバンジェリストのブログに載っていたとして、「アピールされていた」とみなせますか?
    良い案があれば、それもフィードバックとして出しておくことをお勧めします。
    (愚痴や批判だけだと何も変わらないので建設的な方向で考えるという視点からです)

    どちらかと言えば、我々日本人が思い込みがちな、「品質が高くて当然」という意識から抜け出すことが、Developer に求められているかと思います。
    こういった話は Microsoft に限らず、欧米系のベンダーではよくある話でしょうから。
    こういった見方もあるという紹介まで

    最近、Windows デスクトップアプリ開発者向けのサポートが手薄になってきていると感じます。 早くUWPへの移行を進めたいめのでしょうね。

    どうしても、リソースは限られている以上、優先度はあるでしょうね。
    .NET Framework の Windows Forms は高 DPI 対応で地道に手を入れている現状はあるので、デスクトップアプリ全体ではないと思いますけれども。

    2017年11月6日 22:09
    モデレータ
  • Windows Defender の制御フローガードをオフにすることでとりあえずは回避できましたが、セキュリティ緩くすることになるのであまりいい状態ではないですね。

    2017年11月9日 0:54
  • gizmolabs 様

    ご連絡ありがとうございます。

    こちらでも試してみましたが、Windows Defender の制御フローガードをオフにしても依然として遅いままです。

    ちなみに、developpercommunity の方では、制御フローガードをオフにすると改善したという報告があるようです。

    Windows Defender 以外のセキュリティソフトを入れていない状態で確認していますが、gizmolabs 様の環境にはセキュリティソフトをインストールされていますでしょうか?

    2017年11月9日 20:27
  • Azulean 様

    ご連絡ありがとうございます。

    ご質問の件について回答します。

    Windows 7や8の頃は、アプリケーションを最新OSに対応させるための注意点について、マイクロソフトからセミナーが開催され、私も参加させていただきました。

    しかし、Windows 10発売後のアップデートについて、マイクロソフトより、新機能などの案内はあったと思いますが、「アップデートによりこれまで動いていたアプリが正常に動かなくなる可能性がある」という案内はなかったのではないかと思います。

    Azulean 様のようにWindowsを熟知している方であれば、「OSのアップデートで不具合が出る」ことは常識だと思いますが、一般の開発者までこの常識が通じているかといえばそうではないと思います。

    アップデートでトラブルが発生しないのであれば現在のように自動的にアップデートしても構いませんが、それができないのであれば、

    マイクロソフト自ら、開発者および一般ユーザーにOSアップデートの危険性を積極的に通知すべきだと思います。

    (ただし、戦略上絶対にこんなことはできないでしょう。)

    ちなみに、マイクロソフトの姿勢をかなり批判していますが、これは「マイクロソフト自身で発見・修正できる不具合がある」から批判するのであって、自作アプリの不具合について、すべてマイクロソフトのせいにするわけではありません。

    自作アプリの処理が分からないことには対処できない不具合もありますので、そのような不具合については当然開発者の責任で修正する必要があります。

    あと、「品質が高くて当然」 というのは、Windows が有償であり、マイクロソフト以外改変できないことから、高品質を要求することは当然のことだと思います。

    要望の実現にお金を払うのは構いませんが、不具合修正についてお金を払うのは到底受け入れられません。

    (オープンソースであれば、気に入らない部分は自分で修正すればよいのでそこまで高品質を求めません。)

    「過剰に高品質を求めることが悪い」と言われれば、「顧客が求めているので、対応するのが当然」ということになります。

    Windows デスクトップ開発へのサポートが最近手薄な件については、すでにあきらめています。

    既にマルチプラットフォーム対応が求められる時代なので、早く Xamarin や Cordova に移行すべきなのでしょう。

    おそらく、これ以上話をしても平行線になると思いますので、返信は不要です。

    いろいろとご意見いただきありがとうございました。

    2017年11月9日 22:03
  • 私の1意見ですので、議論に値しないとお考えであれば読み捨ててください。

    Windows 7や8の頃は、アプリケーションを最新OSに対応させるための注意点について、マイクロソフトからセミナーが開催され、私も参加させていただきました。

    私の「どのような手段であればアピールされていたとみなせますか?」に対するお答えはこの部分ですかね…?
    セミナーの参加枠は有限なので、すべての開発者にリーチできる手段ではなさそうですが…。

    しかし、Windows 10発売後のアップデートについて、マイクロソフトより、新機能などの案内はあったと思いますが、「アップデートによりこれまで動いていたアプリが正常に動かなくなる可能性がある」という案内はなかったのではないかと思います。

    不具合を前面に出した内容はないでしょうけれども、Insider Preview で互換性評価を行って問題を検証する、リリースされたら評価するといった話は出ていますね。
    https://blogs.windows.com/japan/2017/08/04/waas-simplified-and-aligned/

    Azulean 様のようにWindowsを熟知している方であれば、「OSのアップデートで不具合が出る」ことは常識だと思いますが、一般の開発者までこの常識が通じているかといえばそうではないと思います。

    受動的な立場でいると今後も難しいでしょう。
    これを契機に情報収集する、積極的に試す側に動いて事前に予防するか、Microsoft の有償サポートで「不具合である」というエビデンス(証拠)を引き出して、顧客に説明する運用を取っていくか。

    ちなみに、マイクロソフトの姿勢をかなり批判していますが、これは「マイクロソフト自身で発見・修正できる不具合がある」から批判する

    これはユーザー、開発者サイドから断言できるものではないと思います。

    「すべてのアプリケーション、すべてのデバイスをテストしていれば、発見できる」であるならば、スピード感や費用対効果の観点から無理でしょう。
    実際、我々アプリケーション開発者も、すべてのデバイスではテストしていないのですから、要求されても困る立場ですし…。

    また、Insider Preview を通しても発見されなかったか、発見されたが修正されなかったかのいずれかなので、人数比からすると、Microsoft 内で発見できないレベルだったと言えるかもしれません。

    あと、「品質が高くて当然」 というのは、Windows が有償であり、マイクロソフト以外改変できないことから、高品質を要求することは当然のことだと思います。

    「(前述のような判定基準で)MS が見つけられるはずの不具合は 0 にしろ」というお考えであれば、1開発者として、費用対効果に合っていないと思いますけれども…。

    要望の実現にお金を払うのは構いませんが、不具合修正についてお金を払うのは到底受け入れられません。

    この話を考えの根底に置くなら、Windows は使えないことになります。
    昔からですが、Windows の不具合修正は保証されていませんし、リクエストするためには有償のプレミアサポートの契約レベルが必要であるため。

    ライセンス条項に付属する、品質保証規定でも、Microsoft の裁量により修正か、返金かを選ぶとされています。

    「過剰に高品質を求めることが悪い」と言われれば、「顧客が求めているので、対応するのが当然」ということになります。

    たぶん、この考えで行くと、日本国内でも揉める気がします。
    「過剰」なのですよね…?

    そして、そのスタンスは自分たちアプリケーション開発者の首を絞めることにつながりますが…。

    なお、Microsoft に対する同情的な内容になっていますが、私自身も何度か苦しめられています。幸い、プレミアサポートを使える職場なので、ある程度は追い込んでから、Microsoft に回避策を出してくれとか、社内の人的リソースを浪費しないようにはできていますので何とかなっている範囲ですね...。
    2017年11月9日 22:40
    モデレータ