著者アーカイブ asaba

asaba 著者:asaba

【cordova-react】ページ読み込み速度改善の備忘録

以前からアプリの速度改善に取り組んでいるのですが、先人の知恵もあってページ起動時間がかなり短くなりました。

欲をかいてあと一秒早くしたいなーと思いながらgoogleでコードチューニングのことを調べていると、日本ラドウェア株式会社さんの記事が気になったので読んでみました。

すると、アプリのページ表示に3秒以上費やしてしまうと、ユーザーはストレスを感じWebサイトへのアクセスを取りやめてしまうという

興味をそそるような情報を発見。

今のアプリは起動迄3秒~4秒でアプリとしては十分な速度だったのですが、ダメ元で更に速度を改善できないかなと思い

有用な情報を探していたのですが、ここのサイトでloadable-componentsというライブラリを見つけました。

loadable-componentsは、code-splittingのように必要なページだけを読み込むことで読み込み時間の短縮が見込まれる期待を持っているライブラリです。

何も手をつけていないデフォルトの状態では、読み込むためのファイルはバンドルによって一つのファイルになっているのでこれを一気に

読んでいるのが原因で遅くなるのではと考えました。

試しに公式のコードを真似てアプリに加えてみました。すると、syntax error importで怒られてしまいました。

スタックオーバーフローをくまなく見ると、どうやらwebPackにloadable-componentsを動かす環境が整っていないために

起きるエラーみたいです。という訳でcreate-react-Appで立ち上げないといけないのですが、一から環境を変えてしまう訳にはいかない

ので、別の機会に自分でwebPackの設定をして動かせるように努めたいと思います。

一応サンプルだけ載せておきます。役にたつか分からないですが、公式が割とごちゃごちゃしているので載せておきます。

 


<span style="color: #666699;">routes.js</span>

import loadable from '@loadable/component'

//分割したいファイルを記述

export const Detail = loadable(() = import('./detail'))


 


<span style="color: #666699;">app.js
</span>import React, { Component } from 'react';
import Route from 'react-router-dom/Route';
import HashRouter from 'react-router-dom/HashRouter';
import Switch from 'react-router-dom/Switch';
import ReactDOM from 'react-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import Detail from './detail';
import * as routes from 'routes'
class Root extends Component {
  render() {
    return(
      <MuiThemeProvider>
        <HashRouter>
          <Switch>
            <Route exact path="/detail/:id" component={routes.Detail} />
          </Switch>
        </HashRouter>
      </MuiThemeProvider>
    );
  }
}
asaba 著者:asaba

【CSS】CSSMiniferでCSSを圧縮してアプリの負荷を軽減してみる

一つのファイルにCSSを大量に書くと、当然そのページは読み込みが遅くなり、UIとかも不安定な状態で表示されます。

自分の今修正しているアプリも、漏れなくその多量のCSSの影響を受けております。今更外部ファイルに書くわけにはいかないし

どうしましょうかと模索していた時にこのCSSMiniferを見つけました。

CSSMiniferって何ですかというと、CSSを圧縮して数行にまとめてくれる便利ツールです。CSSを圧縮することで、ページの読み込み

速度を改善させることができます。数百行にわたるCSSでも、このツールにかかれば5~6行で完結させることができます。

使い方はシンプルで、圧縮したいコードを左側のテキスト欄にコピペした後にminifyをするボタンを押すだけ。こんな感じに

仕上がります。(といっても詰め込みすぎて一見すると何書いてあるかわからない。)

 

後はこれをファイルにコピペするだけ。他にも色々なCSSコンプレッサーがありますが、CSSMinifyが一番ごちゃごちゃしていなくて

使いやすかったです。

というか他のツールだと微妙に記述が改変されていたりする(ダブルクォーテーションが消されていたりする)ので、最初からこいつ選んでおけばよかったんじゃないか・・・?と思いました。

webアプリの速度改善の場合大抵はJQueryやスクリプト読み込みの順番を修正するのが王道なのですが、CSSをたくさん書いた場合は

こっちに目を付けてみるのも正解ですね。正しく使えばアプリのリファクタリングに貢献してくれるのではと思います。

 

asaba 著者:asaba

【react-CSS】keyframesを使ったスライド動作

ページの読み込みの際にスライドしたら体感速度ってどのくらい減るだろうと思い試しにreactでkeyframesを使ったページスライド

機能を作ってみました。なぜ作ったかというと、某ブログとかをスマホで見ていてボタンを押した後何も起こらない間が数秒続くときがあ

り、開発者としてどうしてもそこの動作が見逃せなかったのがきっかけです。もしうまいこと動作出来たら今開発しているアプリにも

導入して少しでも速度改善のピースとして役に立てたいと思っています。

keyframesとは、特定のページがアニメーション開始から終了するまでの動作を細かく指定できるCSSプロパティです。このプロパティは

まず始まりを0%、終わりを100%で定義し、その間の%ならば自在に動きをつけることができます。

通常のstyle定義のcssでは手が届かないようなところの処理もこのプロパティでこと細かく設定できるので、滑らかなwebアプリを作りたい

と思ったらこれからはこいつに頼ればいいんですね!

reactのパッケージであるCSSTransationでも細かい動作が期待できますが、こっちはよりreact色が強い書き方をしてるのでどっちを選ぶか

は経験とお好みで決めることになりそうです。

javascript↓


import React, { Component } from 'react';
import {BrowserRouter as Router, Switch, Route, Redirect, Link, NavLink, withRouter} from 'react-router-dom'
import ReactDOM from 'react-dom'

class Login extends Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);

this.state = {
//何か書く
}
}

handleClick(e) {
e.preventDefault();
try {
this.props.history.push({
pathname: "/Signup",
})
} catch (err) {
}
}

render() {
return (
<div>
<div>
<button onClick={this.handleClick}>新規登録</button>
</div>
</div>
);
}
}

export default Login;

css↓


@keyframes SignUp {
0% {
opacity: 0;/* 透明 */
transform: translateX(1500px);/* X軸方向に1500px */最大限
}
100% {
opacity: 30;/* 不透明 */
transform: translateX(0);
}
}

.SignUp {
animation-duration: 0.5s;/* アニメーション時間 */
animation-name: SignUp;/* アニメーション名 */
animation-iteration-count: 1;/* アニメーションを一回だけ動かす

reactで実現させたいのでこんな感じに書いてみました。keyframesの後ろに名前SignUp(なんでもいい)を定義して、そのすぐ下で

今定義したSignUpに関するアニメーションを設定しています。コードの整理が少しめんどくさいですが、keyframesと組み合わせることで

簡単に独自のアニメーションを作ることができます。

今は別々のファイルですが、同じファイル内に書くにはどうしたらいいんだろうと模索中です。(cssは可読性を重視したいため)

今回は簡単なシンプルなサンプルを作っただけでしたが、こだわり次第でいくらでも発展させられるのでこれからも注目していきたい

と思います。

 

 

asaba 著者:asaba

海外からのワンギリ詐欺が横行している話

つい最近のお話です。お正月が終わるころだったと思いますが、ゲームを終えて寝ようかなと布団をかぶろうとしたときに海外から電話が

ありました。こんな真夜中に、しかも数回かかってきていずれも二・三回で切れてものすごく不気味だったので

折り返す勇気も出なかったのですが、電話番号を登録し忘れた知人だったらいけないのでしかたなくかけてみることにしました。

出てみると先方は無言。なんか小声で呟いていたように聞こえましたが全く聞き取れず。秒で切りましたw

すると、同じような事例の方が何人か見つかりました。かかってくる国はまちまちで、

特に中国やフィリピンが多いなぁって感じました。自分のは675から始まっていたので恐らくパプアニューギニアからでしょうか。中古の

携帯でないのにどこで漏れたんや・・・。

 

 

いらいらしながら探ってみるとやはりいいものではありませんでした。電話主の正体はパプアニューギニアの通信会社と手を組んだブローカーです。

闇ブローカーといえば先月タイで捕まった日本人集団が記憶に新しいですが、そのような連中と一緒だと思って良さそうです。

パプアニューギニアへの通話料金は30秒ごとに249円です。彼らは友達の話や世間話でできるだけ通話料金を多く貰えるように話を長引かせ、かかった時間分の通話料を報酬として受け取るというからくりになっているみたいです。

この電話に出てしまったときの対処法ですが、万が一請求が来ても携帯会社に説明なりスルーなりすれば特に問題はないみたいです。

ちなみにどこで情報が漏れたかは分からず、webのアンケートフォームや携帯会社など諸説ありますが、ばれた所で電話番号だけでは

悪用はできないのでさほど気にすることもなさそうです・・・。

これを機に非通知などでかかってきた電話には最初は出ず、後から頭数字を検索して用心しようと思いました。

p.s.脱線してすみません。

asaba 著者:asaba

【android】機内モードを使って消失した現在地アイコンを復活させた話

gpsを使って現在地を読み取るアプリを作っていたのですが、今まで普通に映っていた現在地アイコンが急に消えてしまう事案に

遭遇しました。プロジェクトクリーンやリビルドも何回かしたのですが依然アイコンは消えたまま・・・!

ここまでコードをロールバックしても動かなかったので、視野を広げて飛行機ちゃんこと機内モードに白羽の矢を立てました。

機内モードにするとbluetoothやwi-fiといった通信機能が一時的に使えなくなります。こいつをタップして一度全てリセットした状態でも

う一回起動してみようと思い試してみました。が変わらず・・・。さてどうしましょうと考えていたらなんといきなり現在地アイコンが復活しました!

読み込みに時間がかかっていただけのようで、その後何回か再起動したのですが問題なく現在地アイコンを出すことができました。

iphoneユーザーですからっていい訳は死んでも使いたくないのでここで解決できて本当に助かりました。

設定方法→①まずホーム画面に戻ります。②上から下にスワイプすると、下のような画面が出てきます。③左下にある機内モード(飛行機のマーク)を押します。すると、wi-fi、bluetooth、位置情報といった通信手段が一斉遮断され、アプリなどの連携を断ち切ります。

ここで、もう一回機内モードを押して停止させましょう。すると、今までオフだった通信手段が全部白色になりオンの状態に

なります。とりあえずこれで解決・・・・。

 

 

コードやライブラリ周りを見てもまだ現在地が出てこなかった場合は、こちらが怪しいと目をつけてみてください。

asaba 著者:asaba

【android WebView】webViewに被せたアクションバーに処理を実装する方法

最近になってまたWebViewを触り始めました。webViewってjavascriptとかのイメージが強いですがandroidでも頑張れば実装できるみたい

ですね。しかもこっちはネイティブだから処理速度も安定しているときたので使いこなせれば開発の引き出しが増えそうですね。

今回はそのwebviewを使っていて、アクションバーの中のアイコンをタップしたときに何らかの処理をするメソッドを載せていきます。

 

タップしたアイコンに応じて処理を切り分けるには、onOptionsItemSelected(MenuItem item)メソッドを使う必要があります。

このメソッドは、ヘッダーに当たるアレ。即ちアクションバーに配置したアイコンに応じて処理をswitchで分岐させる役割を

担っています。

例えば、switchの引数idの中身がhomeだった場合は、finish();で終了させてホームボタンにバックさせます。

 

<pre>@Override
public boolean onOptionsItemSelected(MenuItem item) {
    
    int id = item.getItemId();
    WebView webView = (WebView) findViewById(
            R.id.webView);
    switch (id) {
        case android.R.id.home:
            finish();
            break;
        case R.id.menu_share:
            ShareCompat.IntentBuilder builder = ShareCompat.IntentBuilder.from(this);

            String url = webView.getUrl();
            
            builder.setText(url);
            builder.setType("text/plain");
            
            builder.startChooser();
            break;
        case R.id.reload:
            webView.clearCache(true);
            webView.reload();
            break;
    }
    return super.onOptionsItemSelected(item);
}</pre>

 

このように、一般的なアプリのアクションバーにあるページ更新やシェア機能も切り分けて実装することができます。

 

asaba 著者:asaba

【androidJava】ads.MobileAdsInitProvider(ADMOB)を使おうとしてはまったこと

MobileAdsInitProviderは、アプリに広告を表示させることができるライブラリで、ブログやショッピングサイトを取り扱うアプリではよくお目にかかります。

今回はこのライブラリが必要になったので導入してみたのですが、下のエラーを出した後に落ちてしまいました。

 


java.lang.RuntimeException: Unable to get provider com.google.android.gms.ads.MobileAdsInitProvider: java.lang.IllegalStateException

 

どうやら、今までのライブラリと違い単にグレイドルにいれただけでは使えないもよう。

調べてみるとMobileAdsInitProviderを使うには、マニフェストへの記述が必要みたいです。アプリケーションタグを閉じる前に

こんな感じでいれてあげれば解決できます。

 


<meta-data
android:name="com.google.android.gms.ads.AD_MANAGER_APP"
android:value="true"/>

 

こちらの記事のurlを参考にしました

グレイドル関係のエラーが出るたびにこのブログに載せている気がします。ですがグレイドル関係の記事は数が少ないのに対して同じよう

なエラーで困っている人が多くいるので少しでも助けになれたらなと思っております。

なお、日本語版の公式ではこの記事の対策方法が書いていないので注意してください。(見るなら英語版で)

asaba 著者:asaba

【ButterKnife】バターナイフは明示的にgradleに書くべき

viewのメソッドを簡潔にかくことが出来るライブラリです。一般的なviewを使いたい時は、findViewByIdで紐付けるだけで使うことが

できますが、これが複数のviewとなると、同じようなコードができてしまいこれでは可読性に欠けてしまいます。

バターナイフは、このダブつくview定義を事前に定義させることでsetContentViewの下からviewの操作を可能にしてくれるので、複数の

ビューを使いたいけど管理が大変なエンジニアさんには重宝されています。こんな感じ↓

class ExampleActivity extends Activity {
@BindView(R.id.title) TextView title;
@BindView(R.id.subtitle) TextView subtitle;
@BindView(R.id.footer) TextView footer;

@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.bind(this);
// TODO Use fields...
}
}

 

今自分が開発しているアプリもバターナイフを使って管理しているのですが、グレイドル(また出たなお前)のバージョンを上げたら

やっぱりというべきかエラーに通せんぼされてしまいました。

 


Error:Execution failed for task ':app:javaPreCompileDebug'.
&gt; Annotation processors must be explicitly declared now. The following dependencies on the compile classpath are found to contain annotation processor. Please add them to the annotationProcessor configuration.
- butterknife-6.1.0.jar (com.jakewharton:butterknife:6.1.0)
Alternatively, set android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true to continue with previous behavior. Note that this option is deprecated and will be removed in the future.
See https://developer.android.com/r/tools/annotation-processor-error-message.html for more details.

訳してみました。

プロセッサは明示的に宣言されなければなりません。次のコンパイルクラスパスへの依存関係に、注釈プロセッサが含まれています。 annotationProcessor設定にそれらを追加してください。

 

どうやらバターナイフはグレイドルのバージョンに合わせてannotationProcessorとして定義しなければいけないみたいです。グレイドル

アップデート前は普通に定義しなくても使えていたのに・・・。

まあもうできたのが6年前なので仕様が変わっていても不思議じゃないですよね。という訳でannotationProcessorにバターナイフを定義してあと残り

なく解決です。

 

annotationProcessor "com.jakewharton:butterknife:6.1.0"
compileOnly "com.jakewharton:butterknife:6.1.0"

このライブラリに変わるものがすでに出てきているか分かりませんが、ライブラリとしては書くことが少なく学習コストも低いので

いとまがあれば使ってみたいと思います。

asaba 著者:asaba

【javaScript fetch】fetchApiで素のデータを送っても何も返ってこない罠にはまったお話

fetchApiは、通信が成功した際にはpromise型で値を返します。が、スコープで囲んで変数に入れて飛ばすと、サーバーに要求した

値が返ってこない事態にハマってしまいました。ajaxだとdata:{“key”,value}みたいにまとめてからプロパティに入れて取ってくることが

できるのですがこっちでは仕様のせいか受け取ってくれません。

調べてみると、そのままbodyに入れるのではなくformDataというfetchから新しく使えるようになったApiを使って送り込むみたいです。

ajaxではdocumentというxmlを取り扱うことができるオブジェクトがあったのですが、こっちではそれが使えないのでこちらを代わりに

使ってくださいということだと思います。

fetchってもうリリースされてから数年経つのですが、国内の記事を探しても全然見つからないのでみんなまだajax使ってるのかなと

思ってしまいます。

ajaxと違いdomをいちいち掘削しないので、通信速度の向上は期待してもいいと思います。ですが、取ってきたxmlから各タグを取り出すメソッド

とかがめんどくさい感じでしたので、そこらが原因で手が出にくいのかなと思いました。前述の処理だけはjqueryに任せて通信だけ

fetchで賄うことができますが、試していないので速さの保証は実装してみないと分からないです。


var formData = new FormData() ;
var id = this.props.match.params.id;
var followMember = window.localStorage.getItem("member_no");
formData.append( "name", "asaba" ) ;
formData.append( "location", "shizuoka" );
formData.append( "gender", "male" );

var url = 'https://hottomotto';
fetch(url,
{ body: formData,
method: "POST",
})
//通常のレスポンスを返す
.then(function (response) {
return response.text();
})
.then(function(text) {
var xml = new DOMParser().parseFromString(text, "text/xml");
console.log(xml);
});


asaba 著者:asaba

Atomを使っていてメニューバーが消えてしまったときの対処法

いつも通りにソースファイルを立ち上げて作業を始めようとしたのですが、何かの拍子でメニューバーがごっそり消えてしまいました。

メニューバーにはファイルを開いたり保存したりなど普段の作業に必須な項目が入っています。さすがにこのままでは気持ち悪いし

効率が落ちるので元に戻そうと決めたのですが、英語表記なのでわかりにくくかなり苦労してしまいました。

方法としましては、まず今回の目的であるメニューバーを手っ取り早く探すためにCtrl + Shift + pコマンドを押してモーダルを出します。

そこで、toggleと検索します。すると、下の画面のようになると思います。

この画面の一番下のWindow Toggle Menu Barという項目をクリックしてみましょう。すると、上からメニューバーがにゅっと出てくる

のが確認できると思います。

何もなければこれでいつも通りにメニューバーを使うことができます。余談ですが、ファイルを開くと、開いたファイルの一覧が

見ることができるバーも同じように復元しようとしたのですがこちらは元に戻りませんでした・・・。

厳密に言うと形だけは直ったのですが、ファイルの一覧が見れなくなってしまい非常に不便な思いをしています。こちらはツイッターやgit

などで情報収集して修正の目途が立てばまたアップしていきたいと思います。